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="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link rel="stylesheet" href="src/css/style.css">
|
||||
<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"
|
||||
rel="stylesheet">
|
||||
</head>
|
||||
<body>
|
||||
<header>
|
||||
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 id="root">
|
||||
<script type="module" src="/src/App.tsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -14,8 +14,10 @@
|
|||
"dependencies": {
|
||||
"@dimforge/rapier2d": "latest",
|
||||
"@tldraw/tldraw": "2.0.2",
|
||||
"@types/react-helmet": "^6.1.11",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0"
|
||||
"react-dom": "^18.2.0",
|
||||
"react-helmet": "^6.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "1.4.1",
|
||||
|
|
@ -30,4 +32,4 @@
|
|||
"vite-plugin-top-level-await": "^1.3.1",
|
||||
"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 { SimControls } from "./physics/ui/PhysicsControls";
|
||||
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 (
|
||||
<div className="tldraw__editor">
|
||||
<Helmet>
|
||||
<link rel="stylesheet" href="src/css/tldraw.css" />
|
||||
</Helmet>
|
||||
<Tldraw
|
||||
overrides={uiOverrides}
|
||||
// user={createTLUser(opts={id: 'orion', isDarkMode: true})}
|
||||
>
|
||||
<SimControls />
|
||||
{/* <SimControls /> */}
|
||||
{/* {()=> {
|
||||
setUserPreferences({id: 'orion', isDarkMode: true })
|
||||
}} */}
|
||||
<Toggle />
|
||||
</Tldraw>
|
||||
</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;
|
||||
}
|
||||
|
||||
#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 {
|
||||
padding-left: 0;
|
||||
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 { useEffect, useState } from "react";
|
||||
import { usePhysicsSimulation } from "../simulation";
|
||||
import "../../css/physics-ui.css";
|
||||
// import "../../css/physics-ui.css";
|
||||
|
||||
export const SimControls = track(() => {
|
||||
const editor = useEditor();
|
||||
|
|
|
|||
Loading…
Reference in New Issue