Add canvas
This commit is contained in:
parent
8c3dec7271
commit
52383179c1
|
|
@ -1,141 +0,0 @@
|
||||||
export const DEFAULT_STORE = {
|
|
||||||
store: {
|
|
||||||
"document:document": {
|
|
||||||
gridSize: 10,
|
|
||||||
name: "",
|
|
||||||
meta: {},
|
|
||||||
id: "document:document",
|
|
||||||
typeName: "document",
|
|
||||||
},
|
|
||||||
"pointer:pointer": {
|
|
||||||
id: "pointer:pointer",
|
|
||||||
typeName: "pointer",
|
|
||||||
x: 0,
|
|
||||||
y: 0,
|
|
||||||
lastActivityTimestamp: 0,
|
|
||||||
meta: {},
|
|
||||||
},
|
|
||||||
"page:page": {
|
|
||||||
meta: {},
|
|
||||||
id: "page:page",
|
|
||||||
name: "Page 1",
|
|
||||||
index: "a1",
|
|
||||||
typeName: "page",
|
|
||||||
},
|
|
||||||
"camera:page:page": {
|
|
||||||
x: 0,
|
|
||||||
y: 0,
|
|
||||||
z: 1,
|
|
||||||
meta: {},
|
|
||||||
id: "camera:page:page",
|
|
||||||
typeName: "camera",
|
|
||||||
},
|
|
||||||
"instance_page_state:page:page": {
|
|
||||||
editingShapeId: null,
|
|
||||||
croppingShapeId: null,
|
|
||||||
selectedShapeIds: [],
|
|
||||||
hoveredShapeId: null,
|
|
||||||
erasingShapeIds: [],
|
|
||||||
hintingShapeIds: [],
|
|
||||||
focusedGroupId: null,
|
|
||||||
meta: {},
|
|
||||||
id: "instance_page_state:page:page",
|
|
||||||
pageId: "page:page",
|
|
||||||
typeName: "instance_page_state",
|
|
||||||
},
|
|
||||||
"instance:instance": {
|
|
||||||
followingUserId: null,
|
|
||||||
opacityForNextShape: 1,
|
|
||||||
stylesForNextShape: {},
|
|
||||||
brush: null,
|
|
||||||
scribble: null,
|
|
||||||
cursor: {
|
|
||||||
type: "default",
|
|
||||||
rotation: 0,
|
|
||||||
},
|
|
||||||
isFocusMode: false,
|
|
||||||
exportBackground: true,
|
|
||||||
isDebugMode: false,
|
|
||||||
isToolLocked: false,
|
|
||||||
screenBounds: {
|
|
||||||
x: 0,
|
|
||||||
y: 0,
|
|
||||||
w: 720,
|
|
||||||
h: 400,
|
|
||||||
},
|
|
||||||
zoomBrush: null,
|
|
||||||
isGridMode: false,
|
|
||||||
isPenMode: false,
|
|
||||||
chatMessage: "",
|
|
||||||
isChatting: false,
|
|
||||||
highlightedUserIds: [],
|
|
||||||
canMoveCamera: true,
|
|
||||||
isFocused: true,
|
|
||||||
devicePixelRatio: 2,
|
|
||||||
isCoarsePointer: false,
|
|
||||||
isHoveringCanvas: false,
|
|
||||||
openMenus: [],
|
|
||||||
isChangingStyle: false,
|
|
||||||
isReadonly: false,
|
|
||||||
meta: {},
|
|
||||||
id: "instance:instance",
|
|
||||||
currentPageId: "page:page",
|
|
||||||
typeName: "instance",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
schema: {
|
|
||||||
schemaVersion: 1,
|
|
||||||
storeVersion: 4,
|
|
||||||
recordVersions: {
|
|
||||||
asset: {
|
|
||||||
version: 1,
|
|
||||||
subTypeKey: "type",
|
|
||||||
subTypeVersions: {
|
|
||||||
image: 2,
|
|
||||||
video: 2,
|
|
||||||
bookmark: 0,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
camera: {
|
|
||||||
version: 1,
|
|
||||||
},
|
|
||||||
document: {
|
|
||||||
version: 2,
|
|
||||||
},
|
|
||||||
instance: {
|
|
||||||
version: 21,
|
|
||||||
},
|
|
||||||
instance_page_state: {
|
|
||||||
version: 5,
|
|
||||||
},
|
|
||||||
page: {
|
|
||||||
version: 1,
|
|
||||||
},
|
|
||||||
shape: {
|
|
||||||
version: 3,
|
|
||||||
subTypeKey: "type",
|
|
||||||
subTypeVersions: {
|
|
||||||
group: 0,
|
|
||||||
text: 1,
|
|
||||||
bookmark: 1,
|
|
||||||
draw: 1,
|
|
||||||
geo: 7,
|
|
||||||
note: 4,
|
|
||||||
line: 1,
|
|
||||||
frame: 0,
|
|
||||||
arrow: 1,
|
|
||||||
highlight: 0,
|
|
||||||
embed: 4,
|
|
||||||
image: 2,
|
|
||||||
video: 1,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
instance_presence: {
|
|
||||||
version: 5,
|
|
||||||
},
|
|
||||||
pointer: {
|
|
||||||
version: 1,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
62
index.html
62
index.html
|
|
@ -8,69 +8,11 @@
|
||||||
<link rel="shortcut icon" type="image/x-icon" href="src/assets/favicon.ico?v=4" />
|
<link rel="shortcut icon" type="image/x-icon" href="src/assets/favicon.ico?v=4" />
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||||
<link rel="stylesheet" href="src/css/style.css">
|
|
||||||
<link
|
<link
|
||||||
href="https://fonts.googleapis.com/css2?family=Recursive:slnt,wght,CASL,CRSV,MONO@-15..0,300..1000,0..1,0..1,0..1&display=swap"
|
href="https://fonts.googleapis.com/css2?family=Recursive:slnt,wght,CASL,CRSV,MONO@-15..0,300..1000,0..1,0..1,0..1&display=swap"
|
||||||
rel="stylesheet">
|
rel="stylesheet">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body id="root">
|
||||||
<header>
|
<script type="module" src="/src/App.tsx"></script>
|
||||||
Orion Reed
|
|
||||||
</header>
|
|
||||||
<button id="toggle-physics">
|
|
||||||
<img src="src/assets/gravity.svg" alt="Toggle Physics">
|
|
||||||
</button>
|
|
||||||
<main>
|
|
||||||
<h1>Hello! 👋</h1>
|
|
||||||
<p>
|
|
||||||
My research investigates the intersection of computing, human-system
|
|
||||||
interfaces, and emancipatory politics. I am interested in the
|
|
||||||
potential of computing as a medium for thought, as a tool for
|
|
||||||
collective action, and as a means of emancipation.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
My current focus is basic research into the nature of digital
|
|
||||||
organisation, developing theoretical toolkits to improve shared
|
|
||||||
infrastructure, and applying this research to the design of new
|
|
||||||
systems and protocols which support the self-organisation of knowledge
|
|
||||||
and computational artifacts.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h1>My work</h1>
|
|
||||||
<p>
|
|
||||||
Alongside my independent work I am a researcher at
|
|
||||||
<a href="https://block.science/">Block Science</a> building
|
|
||||||
<i>knowledge organisation infrastructure</i> and at
|
|
||||||
<a href="https://economicspace.agency/">ECSA</a> working on
|
|
||||||
<i>computational media</i>. I am also part of the nascent <a href="https://libcomp.org/">Liberatory Computing</a>
|
|
||||||
collective and a co-organiser of the <a href="https://canvasprotocol.org/">OCWG</a>.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<h1>Get in touch</h1>
|
|
||||||
<p>
|
|
||||||
I am on Twitter as <a href="https://twitter.com/OrionReedOne">@OrionReedOne</a> and on
|
|
||||||
Mastodon as <a href="https://hci.social/@orion">@orion@hci.social</a>. The best way to reach me is
|
|
||||||
through Twitter or my email, <a href="mailto:me@orionreed.com">me@orionreed.com</a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<span class="dinkus">***</span>
|
|
||||||
|
|
||||||
<h1>Talks</h1>
|
|
||||||
<ul>
|
|
||||||
<li><a
|
|
||||||
href="objects/causal-islands-integration-domain.pdf">Spatial
|
|
||||||
Canvases: Towards an Integration Domain for HCI @ Causal Islands LA</a></li>
|
|
||||||
<li><a
|
|
||||||
href="https://www.youtube.com/watch?v=-q-kk-NMFbA">Knowledge Organisation Infrastructure Demo @ NPC
|
|
||||||
Denver</a></li>
|
|
||||||
</ul>
|
|
||||||
<h1>Writing</h1>
|
|
||||||
<ul>
|
|
||||||
<li><a
|
|
||||||
href="https://blog.block.science/objects-as-reference-toward-robust-first-principles-of-digital-organization/">Objects
|
|
||||||
as Reference: Toward Robust First Principles of Digital Organization</a></li>
|
|
||||||
</ul>
|
|
||||||
</main>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
@ -14,8 +14,10 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@dimforge/rapier2d": "latest",
|
"@dimforge/rapier2d": "latest",
|
||||||
"@tldraw/tldraw": "2.0.2",
|
"@tldraw/tldraw": "2.0.2",
|
||||||
|
"@types/react-helmet": "^6.1.11",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0"
|
"react-dom": "^18.2.0",
|
||||||
|
"react-helmet": "^6.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@biomejs/biome": "1.4.1",
|
"@biomejs/biome": "1.4.1",
|
||||||
|
|
@ -30,4 +32,4 @@
|
||||||
"vite-plugin-top-level-await": "^1.3.1",
|
"vite-plugin-top-level-await": "^1.3.1",
|
||||||
"vite-plugin-wasm": "^3.2.2"
|
"vite-plugin-wasm": "^3.2.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
117
src/App.tsx
117
src/App.tsx
|
|
@ -1,17 +1,128 @@
|
||||||
import { Tldraw, track, useEditor } from "@tldraw/tldraw";
|
import { createTLUser, setUserPreferences, Tldraw, track, useEditor } from "@tldraw/tldraw";
|
||||||
import "@tldraw/tldraw/tldraw.css";
|
import "@tldraw/tldraw/tldraw.css";
|
||||||
import { SimControls } from "./physics/ui/PhysicsControls";
|
import { SimControls } from "./physics/ui/PhysicsControls";
|
||||||
import { uiOverrides } from "./physics/ui/overrides";
|
import { uiOverrides } from "./physics/ui/overrides";
|
||||||
|
import { Helmet } from "react-helmet";
|
||||||
|
import React, { useEffect, useState } from "react";
|
||||||
|
import ReactDOM from "react-dom/client";
|
||||||
|
|
||||||
export default function Canvas() {
|
ReactDOM.createRoot(document.getElementById("root")!).render(<App />);
|
||||||
|
|
||||||
|
function App() {
|
||||||
|
const [isPhysicsEnabled, setIsPhysicsEnabled] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const togglePhysics = () => setIsPhysicsEnabled(prev => !prev);
|
||||||
|
|
||||||
|
window.addEventListener('togglePhysicsEvent', togglePhysics);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
window.removeEventListener('togglePhysicsEvent', togglePhysics);
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<React.StrictMode>
|
||||||
|
<Toggle />
|
||||||
|
{isPhysicsEnabled ? <Canvas /> : <Default />}
|
||||||
|
</React.StrictMode>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
function Default() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Helmet>
|
||||||
|
<link rel="stylesheet" href="src/css/default.css" />
|
||||||
|
</Helmet>
|
||||||
|
<header>
|
||||||
|
Orion Reed
|
||||||
|
</header>
|
||||||
|
<h1>Hello! 👋</h1>
|
||||||
|
<p>
|
||||||
|
My research investigates the intersection of computing, human-system
|
||||||
|
interfaces, and emancipatory politics. I am interested in the
|
||||||
|
potential of computing as a medium for thought, as a tool for
|
||||||
|
collective action, and as a means of emancipation.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
My current focus is basic research into the nature of digital
|
||||||
|
organisation, developing theoretical toolkits to improve shared
|
||||||
|
infrastructure, and applying this research to the design of new
|
||||||
|
systems and protocols which support the self-organisation of knowledge
|
||||||
|
and computational artifacts.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h1>My work</h1>
|
||||||
|
<p>
|
||||||
|
Alongside my independent work I am a researcher at
|
||||||
|
<a href="https://block.science/">Block Science</a> building
|
||||||
|
<i>knowledge organisation infrastructure</i> and at
|
||||||
|
<a href="https://economicspace.agency/">ECSA</a> working on
|
||||||
|
<i>computational media</i>. I am also part of the nascent <a href="https://libcomp.org/">Liberatory Computing</a>
|
||||||
|
collective and a co-organiser of the <a href="https://canvasprotocol.org/">OCWG</a>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h1>Get in touch</h1>
|
||||||
|
<p>
|
||||||
|
I am on Twitter as <a href="https://twitter.com/OrionReedOne">@OrionReedOne</a> and on
|
||||||
|
Mastodon as <a href="https://hci.social/@orion">@orion@hci.social</a>. The best way to reach me is
|
||||||
|
through Twitter or my email, <a href="mailto:me@orionreed.com">me@orionreed.com</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<span className="dinkus">***</span>
|
||||||
|
|
||||||
|
<h1>Talks</h1>
|
||||||
|
<ul>
|
||||||
|
<li><a
|
||||||
|
href="objects/causal-islands-integration-domain.pdf">Spatial
|
||||||
|
Canvases: Towards an Integration Domain for HCI @ Causal Islands LA</a></li>
|
||||||
|
<li><a
|
||||||
|
href="https://www.youtube.com/watch?v=-q-kk-NMFbA">Knowledge Organisation Infrastructure Demo @ NPC
|
||||||
|
Denver</a></li>
|
||||||
|
</ul>
|
||||||
|
<h1>Writing</h1>
|
||||||
|
<ul>
|
||||||
|
<li><a
|
||||||
|
href="https://blog.block.science/objects-as-reference-toward-robust-first-principles-of-digital-organization/">Objects
|
||||||
|
as Reference: Toward Robust First Principles of Digital Organization</a></li>
|
||||||
|
</ul>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function Canvas() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="tldraw__editor">
|
<div className="tldraw__editor">
|
||||||
|
<Helmet>
|
||||||
|
<link rel="stylesheet" href="src/css/tldraw.css" />
|
||||||
|
</Helmet>
|
||||||
<Tldraw
|
<Tldraw
|
||||||
overrides={uiOverrides}
|
overrides={uiOverrides}
|
||||||
|
// user={createTLUser(opts={id: 'orion', isDarkMode: true})}
|
||||||
>
|
>
|
||||||
<SimControls />
|
{/* <SimControls /> */}
|
||||||
|
{/* {()=> {
|
||||||
|
setUserPreferences({id: 'orion', isDarkMode: true })
|
||||||
|
}} */}
|
||||||
|
<Toggle />
|
||||||
</Tldraw>
|
</Tldraw>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Toggle() {
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Helmet>
|
||||||
|
<link rel="stylesheet" href="src/css/toggle.css" />
|
||||||
|
</Helmet>
|
||||||
|
<button id="toggle-physics" onClick={() => window.dispatchEvent(new CustomEvent('togglePhysicsEvent'))}>
|
||||||
|
<img src="src/assets/gravity.svg" alt="Toggle Physics" />
|
||||||
|
</button>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,21 +44,6 @@ p {
|
||||||
margin-bottom: 0em;
|
margin-bottom: 0em;
|
||||||
}
|
}
|
||||||
|
|
||||||
#toggle-physics {
|
|
||||||
position: absolute;
|
|
||||||
top: 10px;
|
|
||||||
right: 10px;
|
|
||||||
width: 50px;
|
|
||||||
height: 50px;
|
|
||||||
background: none;
|
|
||||||
border: none;
|
|
||||||
cursor: pointer;
|
|
||||||
opacity: 0.5;
|
|
||||||
&:hover {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ul {
|
ul {
|
||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
list-style: decimal-leading-zero;
|
list-style: decimal-leading-zero;
|
||||||
|
|
@ -1,64 +0,0 @@
|
||||||
@import url("https://fonts.googleapis.com/css2?family=Inter:wght@400;500&display=swap");
|
|
||||||
|
|
||||||
html,
|
|
||||||
body {
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
font-family: "Inter", sans-serif;
|
|
||||||
overscroll-behavior: none;
|
|
||||||
touch-action: none;
|
|
||||||
min-height: 100vh;
|
|
||||||
font-size: 16px;
|
|
||||||
/* mobile viewport bug fix */
|
|
||||||
min-height: -webkit-fill-available;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
html,
|
|
||||||
* {
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tldraw__editor {
|
|
||||||
position: fixed;
|
|
||||||
inset: 0px;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.examples {
|
|
||||||
padding: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.examples__header {
|
|
||||||
width: fit-content;
|
|
||||||
padding-bottom: 32px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.examples__lockup {
|
|
||||||
height: 56px;
|
|
||||||
width: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.examples__list {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
padding: 0;
|
|
||||||
margin: 0;
|
|
||||||
list-style: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.examples__list__item {
|
|
||||||
padding: 8px 12px;
|
|
||||||
margin: 0px -12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.examples__list__item a {
|
|
||||||
padding: 8px 12px;
|
|
||||||
margin: 0px -12px;
|
|
||||||
text-decoration: none;
|
|
||||||
color: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
.examples__list__item a:hover {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
@import url("https://fonts.googleapis.com/css2?family=Inter:wght@400;500&display=swap");
|
||||||
|
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
font-family: "Inter", sans-serif;
|
||||||
|
overscroll-behavior: none;
|
||||||
|
touch-action: none;
|
||||||
|
min-height: 100vh;
|
||||||
|
/* font-size: 16px; */
|
||||||
|
/* mobile viewport bug fix */
|
||||||
|
min-height: -webkit-fill-available;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
html,
|
||||||
|
* {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tldraw__editor {
|
||||||
|
position: fixed;
|
||||||
|
inset: 0px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tl-background {
|
||||||
|
background-color: transparent !important;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
#toggle-physics {
|
||||||
|
position: absolute;
|
||||||
|
z-index: 99999;
|
||||||
|
top: 10px;
|
||||||
|
right: 10px;
|
||||||
|
width: 50px;
|
||||||
|
height: 50px;
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
cursor: pointer;
|
||||||
|
opacity: 0.25;
|
||||||
|
&:hover {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
& img {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
10
src/main.tsx
10
src/main.tsx
|
|
@ -1,10 +0,0 @@
|
||||||
import React from "react";
|
|
||||||
import ReactDOM from "react-dom/client";
|
|
||||||
import App from "./App.tsx";
|
|
||||||
import "./css/index.css";
|
|
||||||
|
|
||||||
ReactDOM.createRoot(document.getElementById("root")!).render(
|
|
||||||
<React.StrictMode>
|
|
||||||
<App />
|
|
||||||
</React.StrictMode>,
|
|
||||||
);
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import { track, useEditor } from "@tldraw/tldraw";
|
import { track, useEditor } from "@tldraw/tldraw";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { usePhysicsSimulation } from "../simulation";
|
import { usePhysicsSimulation } from "../simulation";
|
||||||
import "../../css/physics-ui.css";
|
// import "../../css/physics-ui.css";
|
||||||
|
|
||||||
export const SimControls = track(() => {
|
export const SimControls = track(() => {
|
||||||
const editor = useEditor();
|
const editor = useEditor();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue