Get HTML to render properly (this actually works?!?)
This commit is contained in:
parent
9c50ec8d66
commit
ac4b41dad3
70
src/App.tsx
70
src/App.tsx
|
|
@ -1,10 +1,12 @@
|
||||||
import { atom, createShapeId, createTLUser, setUserPreferences, StoreSnapshot, Tldraw, TLGeoShape, TLInstance, TLRecord, TLShape, TLUiComponents, TLUnknownShape, TLUserPreferences, track, useEditor } from "@tldraw/tldraw";
|
import { createShapeId, Tldraw, TLGeoShape, TLShape, TLUiComponents } from "@tldraw/tldraw";
|
||||||
import "@tldraw/tldraw/tldraw.css";
|
import "@tldraw/tldraw/tldraw.css";
|
||||||
|
import "./css/style.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, HelmetProvider } from "react-helmet-async";
|
import { Helmet, HelmetProvider } from "react-helmet-async";
|
||||||
import React, { Suspense, useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import ReactDOM from "react-dom/client";
|
import ReactDOM from "react-dom/client";
|
||||||
|
import { HTMLShapeUtil, HTMLShape } from "./HTMLShapeUtil";
|
||||||
|
|
||||||
ReactDOM.createRoot(document.getElementById("root")!).render(<App />);
|
ReactDOM.createRoot(document.getElementById("root")!).render(<App />);
|
||||||
|
|
||||||
|
|
@ -53,58 +55,51 @@ function App() {
|
||||||
|
|
||||||
// Function to gather elements info asynchronously
|
// Function to gather elements info asynchronously
|
||||||
async function gatherElementsInfo() {
|
async function gatherElementsInfo() {
|
||||||
const rootElement = document.getElementById('root');
|
const rootElement = document.getElementsByTagName('main')[0];
|
||||||
const info: any[] = [];
|
const info: any[] = [];
|
||||||
if (rootElement) {
|
if (rootElement) {
|
||||||
for (const child of rootElement.children) {
|
for (const child of rootElement.children) {
|
||||||
|
if (['BUTTON'].includes(child.tagName)) continue
|
||||||
const rect = child.getBoundingClientRect();
|
const rect = child.getBoundingClientRect();
|
||||||
let w = rect.width
|
let w = rect.width
|
||||||
if (!['P', 'UL'].includes(child.tagName)) {
|
// if (!['P', 'UL'].includes(child.tagName)) {
|
||||||
w = measureElementTextWidth(child);
|
// w = measureElementTextWidth(child);
|
||||||
}
|
// }
|
||||||
console.log(w)
|
// console.log(w)
|
||||||
info.push({
|
info.push({
|
||||||
tagName: child.tagName,
|
tagName: child.tagName,
|
||||||
position: { x: rect.left, y: rect.top },
|
x: rect.left,
|
||||||
dimensions: { width: w, height: rect.height },
|
y: rect.top,
|
||||||
|
w: w,
|
||||||
|
h: rect.height,
|
||||||
|
html: child.outerHTML
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
// Example usage
|
|
||||||
// const element = document.getElementById('yourElementId'); // Replace 'yourElementId' with the actual ID
|
|
||||||
// if (element) {
|
|
||||||
// console.log(`Text width: ${textWidth}px`);
|
|
||||||
// }
|
|
||||||
// console.log(info.length);
|
|
||||||
// console.log(info);
|
|
||||||
|
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
const shapes: TLGeoShape[] = elementsInfo.map((element, index) => ({
|
const shapes: HTMLShape[] = elementsInfo.map((element) => ({
|
||||||
id: createShapeId(),
|
id: createShapeId(),
|
||||||
type: 'geo',
|
type: 'html',
|
||||||
x: element.position.x,
|
x: element.x,
|
||||||
y: element.position.y,
|
y: element.y,
|
||||||
props: {
|
props: {
|
||||||
geo: "rectangle",
|
w: element.w,
|
||||||
w: element.dimensions.width,
|
h: element.h,
|
||||||
h: element.dimensions.height,
|
html: element.html,
|
||||||
fill: 'solid',
|
|
||||||
color: 'green'
|
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
|
|
||||||
shapes.push({
|
shapes.push({
|
||||||
id: createShapeId(),
|
id: createShapeId(),
|
||||||
type: 'geo',
|
type: 'html',
|
||||||
x: 0,
|
x: 0,
|
||||||
y: window.innerHeight,
|
y: window.innerHeight,
|
||||||
props: {
|
props: {
|
||||||
geo: "rectangle",
|
|
||||||
w: window.innerWidth,
|
w: window.innerWidth,
|
||||||
h: 20,
|
h: 20,
|
||||||
fill: 'solid'
|
html: "FOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO"
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -120,10 +115,10 @@ function App() {
|
||||||
|
|
||||||
function Default() {
|
function Default() {
|
||||||
return (
|
return (
|
||||||
<>
|
<main>
|
||||||
<Helmet>
|
{/* <Helmet>
|
||||||
<link rel="stylesheet" href="src/css/default.css" />
|
<link rel="stylesheet" href="src/css/default.css" />
|
||||||
</Helmet>
|
</Helmet> */}
|
||||||
<header>
|
<header>
|
||||||
Orion Reed
|
Orion Reed
|
||||||
</header>
|
</header>
|
||||||
|
|
@ -175,7 +170,7 @@ function Default() {
|
||||||
href="https://blog.block.science/objects-as-reference-toward-robust-first-principles-of-digital-organization/">Objects
|
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>
|
as Reference: Toward Robust First Principles of Digital Organization</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</>
|
</main>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -183,12 +178,13 @@ function Canvas({ shapes }: { shapes: TLShape[] }) {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="tldraw__editor">
|
<div className="tldraw__editor">
|
||||||
<Helmet>
|
{/* <Helmet>
|
||||||
<link rel="stylesheet" href="src/css/tldraw.css" />
|
<link rel="stylesheet" href="src/css/tldraw.css" />
|
||||||
</Helmet>
|
</Helmet> */}
|
||||||
<Tldraw
|
<Tldraw
|
||||||
overrides={uiOverrides}
|
overrides={uiOverrides}
|
||||||
components={components}
|
components={components}
|
||||||
|
shapeUtils={[HTMLShapeUtil]}
|
||||||
>
|
>
|
||||||
<SimControls shapes={shapes} />
|
<SimControls shapes={shapes} />
|
||||||
</Tldraw>
|
</Tldraw>
|
||||||
|
|
@ -199,9 +195,9 @@ function Canvas({ shapes }: { shapes: TLShape[] }) {
|
||||||
function Toggle() {
|
function Toggle() {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Helmet>
|
{/* <Helmet>
|
||||||
<link rel="stylesheet" href="src/css/toggle.css" />
|
<link rel="stylesheet" href="src/css/toggle.css" />
|
||||||
</Helmet>
|
</Helmet> */}
|
||||||
<button id="toggle-physics" onClick={() => window.dispatchEvent(new CustomEvent('togglePhysicsEvent'))}>
|
<button id="toggle-physics" onClick={() => window.dispatchEvent(new CustomEvent('togglePhysicsEvent'))}>
|
||||||
<img src="src/assets/gravity.svg" alt="Toggle Physics" />
|
<img src="src/assets/gravity.svg" alt="Toggle Physics" />
|
||||||
</button>
|
</button>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,32 @@
|
||||||
|
import { Rectangle2d, TLBaseShape } from '@tldraw/tldraw';
|
||||||
|
import { HTMLContainer, ShapeUtil } from 'tldraw'
|
||||||
|
|
||||||
|
export type HTMLShape = TLBaseShape<'html', { w: number; h: number, html: string }>
|
||||||
|
|
||||||
|
export class HTMLShapeUtil extends ShapeUtil<HTMLShape> {
|
||||||
|
static override type = 'html' as const
|
||||||
|
|
||||||
|
getDefaultProps(): HTMLShape['props'] {
|
||||||
|
return {
|
||||||
|
w: 100,
|
||||||
|
h: 100,
|
||||||
|
html: "<div></div>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getGeometry(shape: IHTMLShape) {
|
||||||
|
return new Rectangle2d({
|
||||||
|
width: shape.props.w,
|
||||||
|
height: shape.props.h,
|
||||||
|
isFilled: true,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
component(shape: HTMLShape) {
|
||||||
|
return <div dangerouslySetInnerHTML={{ __html: shape.props.html }} style={{ margin: 0 }} ></div>
|
||||||
|
}
|
||||||
|
|
||||||
|
indicator(shape: HTMLShape) {
|
||||||
|
return <rect width={shape.props.w} height={shape.props.h} />
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,65 +0,0 @@
|
||||||
@import url("reset.css");
|
|
||||||
|
|
||||||
body {
|
|
||||||
max-width: 60em;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding-left: 4em;
|
|
||||||
padding-right: 4em;
|
|
||||||
padding-top: 3em;
|
|
||||||
padding-bottom: 3em;
|
|
||||||
font-family: "Recursive";
|
|
||||||
font-variation-settings: "MONO" 1;
|
|
||||||
font-variation-settings: "CASL" 1;
|
|
||||||
color: #24292e;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
font-size: 1.5rem;
|
|
||||||
margin-top: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
header {
|
|
||||||
margin-bottom: 2em;
|
|
||||||
font-size: 1.5em;
|
|
||||||
font-variation-settings: "MONO" 1;
|
|
||||||
font-variation-settings: "CASL" 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
i {
|
|
||||||
font-variation-settings: "slnt" -15;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
font-family: Recursive;
|
|
||||||
margin-top: 0;
|
|
||||||
margin-bottom: 0.6em;
|
|
||||||
font-size: 1.1em;
|
|
||||||
font-variation-settings: "wght" 350;
|
|
||||||
}
|
|
||||||
.dinkus {
|
|
||||||
display: block;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 1em;
|
|
||||||
margin-top: 2em;
|
|
||||||
margin-bottom: 0em;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul {
|
|
||||||
padding-left: 0;
|
|
||||||
list-style: decimal-leading-zero;
|
|
||||||
& li::marker {
|
|
||||||
color: rgba(0, 0, 0, 0.322);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 600px) {
|
|
||||||
body {
|
|
||||||
padding: 2em;
|
|
||||||
}
|
|
||||||
header {
|
|
||||||
margin-bottom: 1em;
|
|
||||||
}
|
|
||||||
ul {
|
|
||||||
list-style-position: inside;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,133 @@
|
||||||
|
@import url("reset.css");
|
||||||
|
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
|
overscroll-behavior: none;
|
||||||
|
touch-action: none;
|
||||||
|
min-height: 100vh;
|
||||||
|
min-height: -webkit-fill-available;
|
||||||
|
height: 100%;
|
||||||
|
/* font-family: "Inter", sans-serif; */
|
||||||
|
}
|
||||||
|
|
||||||
|
.tldraw__editor {
|
||||||
|
position: fixed;
|
||||||
|
inset: 0px;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tl-background {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tlui-debug-panel {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Non-tldraw stuff */
|
||||||
|
|
||||||
|
main {
|
||||||
|
max-width: 60em;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding-left: 4em;
|
||||||
|
padding-right: 4em;
|
||||||
|
padding-top: 3em;
|
||||||
|
padding-bottom: 3em;
|
||||||
|
font-family: "Recursive";
|
||||||
|
font-variation-settings: "MONO" 1;
|
||||||
|
font-variation-settings: "CASL" 1;
|
||||||
|
color: #24292e;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
margin-top: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
header {
|
||||||
|
margin-bottom: 2em;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
font-variation-settings: "MONO" 1;
|
||||||
|
font-variation-settings: "CASL" 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
i {
|
||||||
|
font-variation-settings: "slnt" -15;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-family: Recursive;
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 0.6em;
|
||||||
|
font-size: 1.1em;
|
||||||
|
font-variation-settings: "wght" 350;
|
||||||
|
}
|
||||||
|
.dinkus {
|
||||||
|
display: block;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
margin-top: 2em;
|
||||||
|
margin-bottom: 0em;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
padding-left: 0;
|
||||||
|
font-size: 1rem;
|
||||||
|
list-style: decimal-leading-zero;
|
||||||
|
& li::marker {
|
||||||
|
color: rgba(0, 0, 0, 0.322);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#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%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 600px) {
|
||||||
|
body {
|
||||||
|
padding: 2em;
|
||||||
|
}
|
||||||
|
header {
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
ul {
|
||||||
|
list-style-position: inside;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tl-html-layer {
|
||||||
|
font-family: "Recursive";
|
||||||
|
font-variation-settings: "MONO" 1;
|
||||||
|
font-variation-settings: "CASL" 1;
|
||||||
|
& h1,
|
||||||
|
p,
|
||||||
|
span,
|
||||||
|
header,
|
||||||
|
ul {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
& header {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
& p {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,34 +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;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tl-background {
|
|
||||||
background-color: transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tlui-debug-panel {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
#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%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue