Add canvas

This commit is contained in:
Orion Reed 2024-03-24 20:06:27 -07:00
parent 8c3dec7271
commit 52383179c1
10 changed files with 170 additions and 296 deletions

View File

@ -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,
},
},
},
};

View File

@ -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>

View File

@ -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"
}
}
}

View File

@ -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>
</>
);
}

View File

@ -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;

View File

@ -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;
}

30
src/css/tldraw.css Normal file
View File

@ -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;
}

19
src/css/toggle.css Normal file
View File

@ -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%;
}
}

View File

@ -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>,
);

View File

@ -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();