([]);
@@ -57,31 +38,7 @@ function App() {
};
}, [isPhysicsEnabled]);
- // Function to gather elements info asynchronously
- async function gatherElementsInfo() {
- const rootElement = document.getElementsByTagName('main')[0];
- const info: any[] = [];
- if (rootElement) {
- for (const child of rootElement.children) {
- if (['BUTTON'].includes(child.tagName)) continue
- const rect = child.getBoundingClientRect();
- let w = rect.width
- // if (!['P', 'UL'].includes(child.tagName)) {
- // w = measureElementTextWidth(child);
- // }
- // console.log(w)
- info.push({
- tagName: child.tagName,
- x: rect.left,
- y: rect.top,
- w: w,
- h: rect.height,
- html: child.outerHTML
- });
- };
- }
- return info;
- }
+
const shapes: HTMLShape[] = elementsInfo.map((element) => ({
id: createShapeId(),
@@ -97,157 +54,29 @@ function App() {
shapes.push({
id: createShapeId(),
- type: 'html',
+ type: 'geo',
x: 0,
y: window.innerHeight,
props: {
w: window.innerWidth,
- h: 20,
- html: "FOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO"
+ h: 50,
+ color: 'grey',
+ fill: 'solid'
+ },
+ meta: {
+ fixed: true
}
})
return (
-
-
-
- { }
-
- {isPhysicsEnabled && elementsInfo.length > 0 ? : null}
-
+
+
+ { }
+
+ {isPhysicsEnabled && elementsInfo.length > 0 ? : null}
);
};
-function Default() {
- return (
-
- {/*
-
- */}
-
- Hello! 👋
-
- 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.
-
-
- 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.
-
-
- My work
-
- Alongside my independent work I am a researcher at Block Science building
- knowledge organisation infrastructure and at ECSA working on
- computational media . I am also part of the nascent Liberatory Computing
- collective and a co-organiser of the OCWG .
-
-
- Get in touch
-
- I am on Twitter as @OrionReedOne and on
- Mastodon as @orion@hci.social . The best way to reach me is
- through Twitter or my email, me@orionreed.com
-
-
- ***
-
- Talks
-
- Writing
-
-
- );
-}
-
-function Canvas({ shapes }: { shapes: TLShape[] }) {
-
- return (
-
- {/*
-
- */}
-
-
-
-
- );
-}
-
-function Toggle() {
- return (
- <>
- {/*
-
- */}
- window.dispatchEvent(new CustomEvent('togglePhysicsEvent'))}>
-
-
- >
- );
-}
-
-function Contact() {
- return (
-
-
- )
-}
-
-function measureElementTextWidth(element: Element) {
- // Create a temporary span element
- const tempElement = document.createElement('span');
- // Get the text content from the passed element
- tempElement.textContent = element.textContent || element.innerText;
- // Get the computed style of the passed element
- const computedStyle = window.getComputedStyle(element);
- // Apply relevant styles to the temporary element
- tempElement.style.font = computedStyle.font;
- tempElement.style.fontWeight = computedStyle.fontWeight;
- tempElement.style.fontSize = computedStyle.fontSize;
- tempElement.style.fontFamily = computedStyle.fontFamily;
- tempElement.style.letterSpacing = computedStyle.letterSpacing;
- // Ensure the temporary element is not visible in the viewport
- tempElement.style.position = 'absolute';
- tempElement.style.visibility = 'hidden';
- tempElement.style.whiteSpace = 'nowrap'; // Prevent text from wrapping
- // Append to the body to make measurements possible
- document.body.appendChild(tempElement);
- // Measure the width
- const width = tempElement.getBoundingClientRect().width;
- // Remove the temporary element from the document
- document.body.removeChild(tempElement);
- // Return the measured width
- return width === 0 ? 10 : width;
-}
\ No newline at end of file
diff --git a/src/objects/causal-islands-integration-domain.pdf b/src/artifacts/causal-islands-integration-domain.pdf
similarity index 100%
rename from src/objects/causal-islands-integration-domain.pdf
rename to src/artifacts/causal-islands-integration-domain.pdf
diff --git a/src/css/style.css b/src/css/style.css
index 57a84cb..8bf3b75 100644
--- a/src/css/style.css
+++ b/src/css/style.css
@@ -134,7 +134,7 @@ ul {
.fade-out {
opacity: 0 !important;
- transition: opacity 1s ease-in-out;
+ transition: opacity 0.2s ease-in-out;
/* visibility: hidden; */
/* display: none; */
}
diff --git a/src/physics/ui/overrides.ts b/src/physics/ui/overrides.ts
deleted file mode 100644
index ae905e7..0000000
--- a/src/physics/ui/overrides.ts
+++ /dev/null
@@ -1,22 +0,0 @@
-import {
- TLUiEventSource,
- TLUiOverrides,
- TLUiTranslationKey,
-} from "@tldraw/tldraw";
-
-// In order to see select our custom shape tool, we need to add it to the ui.
-export const uiOverrides: TLUiOverrides = {
- actions(_editor, actions) {
- actions['toggle-physics'] = {
- id: 'toggle-physics',
- label: 'Toggle Physics' as TLUiTranslationKey,
- readonlyOk: true,
- kbd: 'p',
- onSelect(_source: TLUiEventSource) {
- const event = new CustomEvent('togglePhysicsEvent');
- window.dispatchEvent(event);
- },
- }
- return actions
- },
-}
\ No newline at end of file
diff --git a/src/ts/components/Canvas.tsx b/src/ts/components/Canvas.tsx
new file mode 100644
index 0000000..e4c5c80
--- /dev/null
+++ b/src/ts/components/Canvas.tsx
@@ -0,0 +1,37 @@
+import { Tldraw, TLShape, TLUiComponents } from "@tldraw/tldraw";
+import { SimController } from "../physics/PhysicsControls";
+import { HTMLShapeUtil } from "../shapes/HTMLShapeUtil";
+
+const components: TLUiComponents = {
+ HelpMenu: null,
+ StylePanel: null,
+ PageMenu: null,
+ NavigationPanel: null,
+ DebugMenu: null,
+ ContextMenu: null,
+ ActionsMenu: null,
+ QuickActions: null,
+ MainMenu: null,
+ MenuPanel: null,
+ // ZoomMenu: null,
+ // Minimap: null,
+ // Toolbar: null,
+ // KeyboardShortcutsDialog: null,
+ // HelperButtons: null,
+ // SharePanel: null,
+ // TopPanel: null,
+}
+
+export function Canvas({ shapes }: { shapes: TLShape[]; }) {
+
+ return (
+
+
+
+
+
+ );
+}
diff --git a/src/ts/components/Contact.tsx b/src/ts/components/Contact.tsx
new file mode 100644
index 0000000..5838f93
--- /dev/null
+++ b/src/ts/components/Contact.tsx
@@ -0,0 +1,14 @@
+import React from "react";
+
+function Contact() {
+ return (
+
+
+ );
+}
diff --git a/src/ts/components/Default.tsx b/src/ts/components/Default.tsx
new file mode 100644
index 0000000..f0f16c2
--- /dev/null
+++ b/src/ts/components/Default.tsx
@@ -0,0 +1,59 @@
+import React from "react";
+
+export function Default() {
+ return (
+
+
+ Hello! 👋
+
+ 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.
+
+
+
+ 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.
+
+
+ My work
+
+ Alongside my independent work I am a researcher at Block Science building
+ knowledge organisation infrastructure and at ECSA working on
+ computational media . I am also part of the nascent Liberatory Computing
+ collective and a co-organiser of the OCWG .
+
+
+ Get in touch
+
+ I am on Twitter as @OrionReedOne and on
+ Mastodon as @orion@hci.social . The best way to reach me is
+ through Twitter or my email, me@orionreed.com
+
+
+ ***
+
+ Talks
+
+ Writing
+
+
+ );
+}
diff --git a/src/ts/components/Toggle.tsx b/src/ts/components/Toggle.tsx
new file mode 100644
index 0000000..d7614f8
--- /dev/null
+++ b/src/ts/components/Toggle.tsx
@@ -0,0 +1,11 @@
+import React from "react";
+
+export function Toggle() {
+ return (
+ <>
+ window.dispatchEvent(new CustomEvent('togglePhysicsEvent'))}>
+
+
+ >
+ );
+}
diff --git a/src/physics/ui/PhysicsControls.tsx b/src/ts/physics/PhysicsControls.tsx
similarity index 72%
rename from src/physics/ui/PhysicsControls.tsx
rename to src/ts/physics/PhysicsControls.tsx
index e15fbb5..444f4a0 100644
--- a/src/physics/ui/PhysicsControls.tsx
+++ b/src/ts/physics/PhysicsControls.tsx
@@ -1,8 +1,8 @@
import { TLUnknownShape, useEditor } from "@tldraw/tldraw";
import { useEffect } from "react";
-import { usePhysicsSimulation } from "../simulation";
+import { usePhysicsSimulation } from "./simulation";
-export const SimControls = ({ shapes }: { shapes: TLUnknownShape[] }) => {
+export const SimController = ({ shapes }: { shapes: TLUnknownShape[] }) => {
const editor = useEditor();
useEffect(() => {
diff --git a/src/physics/config.ts b/src/ts/physics/config.ts
similarity index 100%
rename from src/physics/config.ts
rename to src/ts/physics/config.ts
diff --git a/src/physics/math.ts b/src/ts/physics/math.ts
similarity index 100%
rename from src/physics/math.ts
rename to src/ts/physics/math.ts
diff --git a/src/physics/simulation.ts b/src/ts/physics/simulation.ts
similarity index 97%
rename from src/physics/simulation.ts
rename to src/ts/physics/simulation.ts
index 3829d2d..f73900f 100644
--- a/src/physics/simulation.ts
+++ b/src/ts/physics/simulation.ts
@@ -9,6 +9,8 @@ type BodyWithShapeData = RAPIER.RigidBody & {
};
type RigidbodyLookup = { [key: TLShapeId]: RAPIER.RigidBody };
+const START_DELAY = 1500;
+
export class PhysicsWorld {
private editor: Editor;
private world: RAPIER.World;
@@ -28,6 +30,7 @@ export class PhysicsWorld {
public start() {
this.world = new RAPIER.World(GRAVITY);
+ // setTimeout(() => {
this.addShapes(this.editor.getCurrentPageShapes());
const simLoop = () => {
@@ -38,6 +41,7 @@ export class PhysicsWorld {
};
simLoop();
return () => cancelAnimationFrame(this.animFrame);
+ // }, START_DELAY);
};
public stop() {
@@ -55,6 +59,7 @@ export class PhysicsWorld {
}
switch (shape.type) {
+ case "html":
case "geo":
case "image":
case "video":
@@ -72,12 +77,12 @@ export class PhysicsWorld {
}
createShape(shape: TLGeoShape | TLDrawShape) {
- if (shape.props.dash === "dashed") return; // Skip dashed shapes
- if (isRigidbody(shape.props.color)) {
- const gravity = getGravityFromColor(shape.props.color)
- const rb = this.createRigidbody(shape, gravity);
+ console.log('creating shape');
+ if (!shape.meta.fixed) {
+ const rb = this.createRigidbody(shape, 1);
this.createCollider(shape, rb);
- } else {
+ }
+ else {
this.createCollider(shape);
}
}
@@ -379,7 +384,6 @@ export function usePhysicsSimulation(editor: Editor, enabled: boolean) {
useEffect(() => {
if (enabled) {
sim.current.start();
- editor.selectNone();
return () => sim.current.stop();
}
}, [enabled, sim]);
diff --git a/src/HTMLShapeUtil.tsx b/src/ts/shapes/HTMLShapeUtil.tsx
similarity index 95%
rename from src/HTMLShapeUtil.tsx
rename to src/ts/shapes/HTMLShapeUtil.tsx
index 7503eb3..156b261 100644
--- a/src/HTMLShapeUtil.tsx
+++ b/src/ts/shapes/HTMLShapeUtil.tsx
@@ -23,7 +23,7 @@ export class HTMLShapeUtil extends ShapeUtil {
}
component(shape: HTMLShape) {
- return
+ return
}
indicator(shape: HTMLShape) {
diff --git a/src/utils.tsx b/src/utils.tsx
new file mode 100644
index 0000000..4ab56b6
--- /dev/null
+++ b/src/utils.tsx
@@ -0,0 +1,61 @@
+export function measureElementTextWidth(element: HTMLElement) {
+ // Create a temporary span element
+ const tempElement = document.createElement('span');
+ // Get the text content from the passed element
+ tempElement.textContent = element.textContent || element.innerText;
+ // Get the computed style of the passed element
+ const computedStyle = window.getComputedStyle(element);
+ // Apply relevant styles to the temporary element
+ tempElement.style.font = computedStyle.font;
+ tempElement.style.fontWeight = computedStyle.fontWeight;
+ tempElement.style.fontSize = computedStyle.fontSize;
+ tempElement.style.fontFamily = computedStyle.fontFamily;
+ tempElement.style.letterSpacing = computedStyle.letterSpacing;
+ // Ensure the temporary element is not visible in the viewport
+ tempElement.style.position = 'absolute';
+ tempElement.style.visibility = 'hidden';
+ tempElement.style.whiteSpace = 'nowrap'; // Prevent text from wrapping
+ // Append to the body to make measurements possible
+ document.body.appendChild(tempElement);
+ // Measure the width
+ const width = tempElement.getBoundingClientRect().width;
+ // Remove the temporary element from the document
+ document.body.removeChild(tempElement);
+ // Return the measured width
+ return width === 0 ? 10 : width;
+}
+
+
+// Function to gather elements info asynchronously
+export async function gatherElementsInfo() {
+ const rootElement = document.getElementsByTagName('main')[0];
+ const info: any[] = [];
+ if (rootElement) {
+ for (const child of rootElement.children) {
+ if (['BUTTON'].includes(child.tagName)) continue;
+ const rect = child.getBoundingClientRect();
+ let w = rect.width;
+ if (!['P', 'UL'].includes(child.tagName)) {
+ w = measureElementTextWidth(child);
+ }
+ // Check if the element is centered
+ const computedStyle = window.getComputedStyle(child);
+ let x = rect.left; // Default x position
+ if (computedStyle.display === 'block' && computedStyle.textAlign === 'center') {
+ // Adjust x position for centered elements
+ const parentWidth = child.parentElement ? child.parentElement.getBoundingClientRect().width : 0;
+ x = (parentWidth - w) / 2 + window.scrollX + (child.parentElement ? child.parentElement.getBoundingClientRect().left : 0);
+ }
+
+ info.push({
+ tagName: child.tagName,
+ x: x,
+ y: rect.top,
+ w: w,
+ h: rect.height,
+ html: child.outerHTML
+ });
+ };
+ }
+ return info;
+}