rename spatial to fc/folk

This commit is contained in:
Orion Reed 2024-10-30 02:18:27 -04:00
parent d2bb5f40fa
commit 862174a8bb
19 changed files with 249 additions and 178 deletions

View File

@ -15,12 +15,12 @@
margin: 0; margin: 0;
} }
spatial-geometry { fc-geometry {
border: 1px solid black; border: 1px solid black;
border-radius: 3px; border-radius: 3px;
} }
spatial-connection { fc-connection {
display: block; display: block;
position: absolute; position: absolute;
inset: 0 0 0 0; inset: 0 0 0 0;
@ -32,18 +32,18 @@
</style> </style>
</head> </head>
<body> <body>
<spatial-geometry id="box1" x="100" y="100" width="50" height="50"></spatial-geometry> <fc-geometry id="box1" x="100" y="100" width="50" height="50"></fc-geometry>
<spatial-geometry id="box2" x="200" y="300">Hello World</spatial-geometry> <fc-geometry id="box2" x="200" y="300">Hello World</fc-geometry>
<spatial-connection source="#box1" target="#box2"></spatial-connection> <fc-connection source="#box1" target="#box2"></fc-connection>
<spatial-connection source="#box1" target="400,100"></spatial-connection> <fc-connection source="#box1" target="400,100"></fc-connection>
<script type="module"> <script type="module">
import { SpatialGeometry } from '../src/canvas/spatial-geometry.ts'; import { FolkGeometry } from '../src/canvas/fc-geometry.ts';
import { SpatialConnection } from '../src/arrows/spatial-connection.ts'; import { FolkConnection } from '../src/arrows/fc-connection.ts';
SpatialGeometry.register(); FolkGeometry.register();
SpatialConnection.register(); FolkConnection.register();
</script> </script>
</body> </body>
</html> </html>

View File

@ -35,7 +35,7 @@
font-style: italic; font-style: italic;
} }
spatial-geometry { fc-geometry {
z-index: 2; z-index: 2;
} }
</style> </style>
@ -45,64 +45,77 @@
<h1>My article</h1> <h1>My article</h1>
<p> <p>
<span <span
>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore >Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
magna aliqua.</span eiusmod tempor incididunt ut labore et dolore magna aliqua.</span
> >
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi
aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint ut aliquip ex ea commodo consequat. Duis aute irure dolor in
occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa
qui officia deserunt mollit anim id est laborum.
</p> </p>
<p> <p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
laborum. velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
occaecat cupidatat non proident, sunt in culpa qui officia deserunt
mollit anim id est laborum.
</p> </p>
<p> <p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
laborum. velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
occaecat cupidatat non proident, sunt in culpa qui officia deserunt
mollit anim id est laborum.
</p> </p>
<p> <p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
pariatur. commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
velit esse cillum dolore eu fugiat nulla pariatur.
<span <span
>Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est >Excepteur sint occaecat cupidatat non proident, sunt in culpa qui
laborum.</span officia deserunt mollit anim id est laborum.</span
> >
</p> </p>
<p> <p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
laborum. velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
occaecat cupidatat non proident, sunt in culpa qui officia deserunt
mollit anim id est laborum.
</p> </p>
<p> <p>
Lorem ipsum dolor sit amet,>consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore Lorem ipsum dolor sit amet,>consectetur adipiscing elit, sed do eiusmod
magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
laborum. velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
occaecat cupidatat non proident, sunt in culpa qui officia deserunt
mollit anim id est laborum.
</p> </p>
<p> <p>
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod
magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim
consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est commodo consequat. Duis aute irure dolor in reprehenderit in voluptate
laborum. velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
occaecat cupidatat non proident, sunt in culpa qui officia deserunt
mollit anim id est laborum.
</p> </p>
</main> </main>
<script type="module"> <script type="module">
import { SpatialGeometry } from '../src/canvas/spatial-geometry.ts'; import { FolkGeometry } from '../src/canvas/fc-geometry.ts';
SpatialGeometry.register(); FolkGeometry.register();
function copyStyles(from, to) { function copyStyles(from, to) {
const styles = getComputedStyle(from); const styles = getComputedStyle(from);
@ -115,7 +128,8 @@
} }
document.addEventListener('click', ({ target }) => { document.addEventListener('click', ({ target }) => {
if (target.closest('spatial-geometry') || target.matches('body, html')) return; if (target.closest('fc-geometry') || target.matches('body, html'))
return;
const rect = target.getBoundingClientRect(); const rect = target.getBoundingClientRect();
@ -133,7 +147,7 @@
copyStyles(el, copiedElements[i]); copyStyles(el, copiedElements[i]);
}); });
const geometry = document.createElement('spatial-geometry'); const geometry = document.createElement('fc-geometry');
geometry.x = rect.x; geometry.x = rect.x;
geometry.y = rect.y; geometry.y = rect.y;
geometry.height = rect.height; geometry.height = rect.height;

View File

@ -36,13 +36,13 @@
} }
} }
spatial-connection { fc-connection {
display: block; display: block;
position: absolute; position: absolute;
inset: 0 0 0 0; inset: 0 0 0 0;
} }
spatial-geometry { fc-geometry {
border-radius: 7px; border-radius: 7px;
&::part(rotate), &::part(rotate),
@ -53,7 +53,7 @@
display: none; display: none;
} }
spatial-thought { fc-thought {
background-color: white; background-color: white;
border-radius: 6px; border-radius: 6px;
border: solid 1px light-dark(rgb(118, 118, 118), rgb(133, 133, 133)); border: solid 1px light-dark(rgb(118, 118, 118), rgb(133, 133, 133));

View File

@ -1,24 +1,26 @@
import { SpatialGeometry } from '../../src/canvas/spatial-geometry.ts'; import { FolkGeometry } from '../../src/canvas/fc-geometry.ts';
import { SpatialConnection } from '../../src/arrows/spatial-connection.ts'; import { FolkConnection } from '../../src/arrows/fc-connection.ts';
import { FileSaver } from '../../src/persistence/file.ts'; import { FileSaver } from '../../src/persistence/file.ts';
declare global { declare global {
interface HTMLElementTagNameMap { interface HTMLElementTagNameMap {
'spatial-thought': SpatialThought; 'fc-thought': FolkThought;
} }
} }
class SpatialThought extends HTMLElement { class FolkThought extends HTMLElement {
static tagName = 'spatial-thought'; static tagName = 'fc-thought';
static register() { static register() {
customElements.define(this.tagName, this); customElements.define(this.tagName, this);
} }
#deleteButton = this.querySelector('button[name="delete"]') as HTMLButtonElement; #deleteButton = this.querySelector(
'button[name="delete"]'
) as HTMLButtonElement;
#text = this.querySelector('[name="text"]') as HTMLElement; #text = this.querySelector('[name="text"]') as HTMLElement;
#geometry = this.parentElement as SpatialGeometry; #geometry = this.parentElement as FolkGeometry;
constructor() { constructor() {
super(); super();
@ -36,17 +38,17 @@ class SpatialThought extends HTMLElement {
document document
.querySelectorAll( .querySelectorAll(
`spatial-connection[source="spatial-geometry[id='${this.#geometry.id}']"], `fc-connection[source="fc-geometry[id='${this.#geometry.id}']"],
spatial-connection[target="spatial-geometry[id='${this.#geometry.id}']"]` fc-connection[target="fc-geometry[id='${this.#geometry.id}']"]`
) )
.forEach((el) => el.remove()); .forEach((el) => el.remove());
} }
} }
} }
SpatialGeometry.register(); FolkGeometry.register();
SpatialThought.register(); FolkThought.register();
SpatialConnection.register(); FolkConnection.register();
interface Thought { interface Thought {
id: string; id: string;
@ -68,41 +70,48 @@ interface ChainOfThought {
const html = String.raw; const html = String.raw;
function parseHTML(html: string): Element { function parseHTML(html: string): Element {
return document.createRange().createContextualFragment(html).firstElementChild!; return document.createRange().createContextualFragment(html)
.firstElementChild!;
} }
function renderThought({ id, x, y, text }: Thought) { function renderThought({ id, x, y, text }: Thought) {
return html`<spatial-geometry id="${id}" x="${x}" y="${y}"> return html`<fc-geometry id="${id}" x="${x}" y="${y}">
<spatial-thought> <fc-thought>
<div contenteditable="true" name="text">${text}</div> <div contenteditable="true" name="text">${text}</div>
<button name="delete"></button> <button name="delete"></button>
</spatial-thought> </fc-thought>
</spatial-geometry>`; </fc-geometry>`;
} }
function renderConnection({ sourceId, targetId }: Connection) { function renderConnection({ sourceId, targetId }: Connection) {
return html`<spatial-connection return html`<fc-connection
source="spatial-geometry[id='${sourceId}']" source="fc-geometry[id='${sourceId}']"
target="spatial-geometry[id='${targetId}']" target="fc-geometry[id='${targetId}']"
></spatial-connection>`; ></fc-connection>`;
} }
function renderChainOfThought({ thoughts, connections }: ChainOfThought) { function renderChainOfThought({ thoughts, connections }: ChainOfThought) {
return html`${thoughts.map(renderThought).join('')}${connections.map(renderConnection).join('')}`; return html`${thoughts.map(renderThought).join('')}${connections
.map(renderConnection)
.join('')}`;
} }
function parseChainOfThought(): ChainOfThought { function parseChainOfThought(): ChainOfThought {
return { return {
thoughts: Array.from(document.querySelectorAll('spatial-geometry')).map((el) => ({ thoughts: Array.from(document.querySelectorAll('fc-geometry')).map(
(el) => ({
id: el.id, id: el.id,
text: (el.firstElementChild as SpatialThought).text, text: (el.firstElementChild as FolkThought).text,
x: el.x, x: el.x,
y: el.y, y: el.y,
})), })
connections: Array.from(document.querySelectorAll('spatial-connection')).map((el) => ({ ),
sourceId: (el.sourceElement as SpatialGeometry).id, connections: Array.from(document.querySelectorAll('fc-connection')).map(
targetId: (el.targetElement as SpatialGeometry).id, (el) => ({
})), sourceId: (el.sourceElement as FolkGeometry).id,
targetId: (el.targetElement as FolkGeometry).id,
})
),
}; };
} }
@ -110,14 +119,18 @@ const openButton = document.querySelector('button[name="open"]')!;
const saveButton = document.querySelector('button[name="save"]')!; const saveButton = document.querySelector('button[name="save"]')!;
const saveAsButton = document.querySelector('button[name="save-as"]')!; const saveAsButton = document.querySelector('button[name="save-as"]')!;
const main = document.querySelector('main')!; const main = document.querySelector('main')!;
const fileSaver = new FileSaver('chains-of-thought', 'json', 'application/json'); const fileSaver = new FileSaver(
'chains-of-thought',
'json',
'application/json'
);
main.addEventListener('dblclick', (e) => { main.addEventListener('dblclick', (e) => {
if (e.target === main) { if (e.target === main) {
main.appendChild( main.appendChild(
parseHTML( parseHTML(
renderThought({ renderThought({
id: String(document.querySelectorAll('spatial-thought').length + 1), id: String(document.querySelectorAll('fc-thought').length + 1),
text: '', text: '',
x: e.clientX, x: e.clientX,
y: e.clientY, y: e.clientY,

View File

@ -19,24 +19,27 @@
margin: 0; margin: 0;
} }
spatial-geometry { fc-geometry {
border: 2px solid black; border: 2px solid black;
} }
</style> </style>
</head> </head>
<body> <body>
<spatial-geometry x="100" y="100" width="50" height="50"></spatial-geometry> <fc-geometry x="100" y="100" width="50" height="50"></fc-geometry>
<spatial-geometry x="200" y="200" width="50" height="50"></spatial-geometry> <fc-geometry x="200" y="200" width="50" height="50"></fc-geometry>
<script type="module"> <script type="module">
import { SpatialGeometry } from '../src/canvas/spatial-geometry.ts'; import { FolkGeometry } from '../src/canvas/fc-geometry.ts';
SpatialGeometry.register(); FolkGeometry.register();
const geometryElements = document.querySelectorAll('spatial-geometry'); const geometryElements = document.querySelectorAll('fc-geometry');
function collisionDetection(rect1, rect2) { function collisionDetection(rect1, rect2) {
return ( return (
rect1.left < rect2.right && rect1.right > rect2.left && rect1.top < rect2.bottom && rect1.bottom > rect2.top rect1.left < rect2.right &&
rect1.right > rect2.left &&
rect1.top < rect2.bottom &&
rect1.bottom > rect2.top
); );
} }
@ -46,7 +49,12 @@
el !== e.target && el !== e.target &&
collisionDetection( collisionDetection(
// TODO: refactor this hack once resizing and the vertices API are figured out // TODO: refactor this hack once resizing and the vertices API are figured out
DOMRectReadOnly.fromRect({ x: el.x, y: el.y, height: el.height, width: el.width }), DOMRectReadOnly.fromRect({
x: el.x,
y: el.y,
height: el.height,
width: el.width,
}),
DOMRectReadOnly.fromRect({ DOMRectReadOnly.fromRect({
x: e.target.x, x: e.target.x,
y: e.target.y, y: e.target.y,

View File

@ -15,7 +15,7 @@
margin: 0; margin: 0;
} }
spatial-geometry { fc-geometry {
border: 1px solid black; border: 1px solid black;
border-radius: 3px; border-radius: 3px;
} }
@ -28,8 +28,10 @@
</style> </style>
</head> </head>
<body> <body>
<spatial-geometry id="box1" x="100" y="100" width="50" height="50"></spatial-geometry> <fc-geometry id="box1" x="100" y="100" width="50" height="50"></fc-geometry>
<spatial-geometry id="box2" x="200" y="300" width="50" height="50">Hello World</spatial-geometry> <fc-geometry id="box2" x="200" y="300" width="50" height="50"
>Hello World</fc-geometry
>
<event-propagator <event-propagator
source="#box1" source="#box1"
target="#box2" target="#box2"
@ -37,8 +39,8 @@
expression="$target.textContent += '!'" expression="$target.textContent += '!'"
></event-propagator> ></event-propagator>
<spatial-geometry id="box3" x="150" y="200" width="50" height="50"></spatial-geometry> <fc-geometry id="box3" x="150" y="200" width="50" height="50"></fc-geometry>
<spatial-geometry id="box4" x="300" y="350" width="50" height="50"></spatial-geometry> <fc-geometry id="box4" x="300" y="350" width="50" height="50"></fc-geometry>
<event-propagator <event-propagator
source="#box3" source="#box3"
target="#box4" target="#box4"
@ -47,10 +49,10 @@
></event-propagator> ></event-propagator>
<script type="module"> <script type="module">
import { SpatialGeometry } from '../src/canvas/spatial-geometry.ts'; import { FolkGeometry } from '../src/canvas/fc-geometry.ts';
import { EventPropagator } from '../src/arrows/event-propagator.ts'; import { EventPropagator } from '../src/arrows/event-propagator.ts';
SpatialGeometry.register(); FolkGeometry.register();
EventPropagator.register(); EventPropagator.register();
</script> </script>
</body> </body>

View File

@ -3,7 +3,7 @@
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Spatial Canvas Primitives</title> <title>Folk Canvas Primitives</title>
<style> <style>
html { html {
height: 100%; height: 100%;
@ -16,7 +16,7 @@
</style> </style>
</head> </head>
<body> <body>
<h1>Spatial Canvas Primitives</h1> <h1>Folk Canvas Primitives</h1>
<ul> <ul>
<li><a href="/shapes">Shapes</a></li> <li><a href="/shapes">Shapes</a></li>

View File

@ -21,11 +21,11 @@
<button on:click="DRAW">Draw</button> <button on:click="DRAW">Draw</button>
</nav> </nav>
<script type="module"> <script type="module">
import { SpatialGeometry } from '../src/canvas/spatial-geometry.ts'; import { FolkGeometry } from '../src/canvas/fc-geometry.ts';
import { SpatialInk } from '../src/canvas/spatial-ink.ts'; import { FolkInk } from '../src/canvas/fc-ink.ts';
SpatialGeometry.register(); FolkGeometry.register();
SpatialInk.register(); FolkInk.register();
const drawButton = document.querySelector('button'); const drawButton = document.querySelector('button');
@ -36,7 +36,7 @@
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
const ink = document.createElement('spatial-ink'); const ink = document.createElement('fc-ink');
document.body.appendChild(ink); document.body.appendChild(ink);
@ -45,7 +45,7 @@
ink.points = ink.points.map(([x, y, p]) => [x - rect.x, y - rect.y, p]); ink.points = ink.points.map(([x, y, p]) => [x - rect.x, y - rect.y, p]);
const geometry = document.createElement('spatial-geometry'); const geometry = document.createElement('fc-geometry');
geometry.x = rect.x; geometry.x = rect.x;
geometry.y = rect.y; geometry.y = rect.y;
geometry.height = rect.height; geometry.height = rect.height;

View File

@ -37,27 +37,35 @@
</style> </style>
</head> </head>
<body> <body>
<spatial-geometry x="25" y="100" width="400" height="200"> <fc-geometry x="25" y="100" width="400" height="200">
<leaflet-map coordinates="52.09, 5.12" zoom="13"></leaflet-map> <leaflet-map coordinates="52.09, 5.12" zoom="13"></leaflet-map>
</spatial-geometry> </fc-geometry>
<spatial-geometry x="50" y="550" width="400" height="250"> <fc-geometry x="50" y="550" width="400" height="250">
<leaflet-map coordinates="51.50404120260676, -0.14007568359375003" zoom="13"></leaflet-map> <leaflet-map
</spatial-geometry> coordinates="51.50404120260676, -0.14007568359375003"
zoom="13"
></leaflet-map>
</fc-geometry>
<spatial-geometry x="500" y="400" width="500" height="300"> <fc-geometry x="500" y="400" width="500" height="300">
<geo-wiki coordinates="51.50404120260676, -0.14007568359375003"></geo-wiki> <geo-wiki
</spatial-geometry> coordinates="51.50404120260676, -0.14007568359375003"
></geo-wiki>
</fc-geometry>
<script type="module"> <script type="module">
import { SpatialGeometry } from '../src/canvas/spatial-geometry.ts'; import { FolkGeometry } from '../src/canvas/fc-geometry.ts';
import { LeafletMap } from '../src/maps'; import { LeafletMap } from '../src/maps';
SpatialGeometry.register(); FolkGeometry.register();
LeafletMap.register(); LeafletMap.register();
function collisionDetection(rect1, rect2) { function collisionDetection(rect1, rect2) {
return ( return (
rect1.left < rect2.right && rect1.right > rect2.left && rect1.top < rect2.bottom && rect1.bottom > rect2.top rect1.left < rect2.right &&
rect1.right > rect2.left &&
rect1.top < rect2.bottom &&
rect1.bottom > rect2.top
); );
} }
@ -74,7 +82,10 @@
} }
const proximityMap = new Map( const proximityMap = new Map(
Array.from(document.querySelectorAll('spatial-geometry')).map((el) => [el, new Set()]) Array.from(document.querySelectorAll('fc-geometry')).map((el) => [
el,
new Set(),
])
); );
function handleProximity(e) { function handleProximity(e) {
@ -83,7 +94,12 @@
const alreadyIntersection = set.has(e.target); const alreadyIntersection = set.has(e.target);
// TODO: refactor this hack once resizing and the vertices API are figured out // TODO: refactor this hack once resizing and the vertices API are figured out
const isNowIntersecting = proximityDetection( const isNowIntersecting = proximityDetection(
DOMRectReadOnly.fromRect({ x: el.x, y: el.y, height: el.height, width: el.width }), DOMRectReadOnly.fromRect({
x: el.x,
y: el.y,
height: el.height,
width: el.width,
}),
DOMRectReadOnly.fromRect({ DOMRectReadOnly.fromRect({
x: e.target.x, x: e.target.x,
y: e.target.y, y: e.target.y,
@ -136,7 +152,9 @@
attributeChangedCallback(name, oldValue, newValue) { attributeChangedCallback(name, oldValue, newValue) {
if (name === 'coordinates') { if (name === 'coordinates') {
this.#coordinates = newValue.split(',').map((str) => Number(str)) || [0, 0]; this.#coordinates = newValue
.split(',')
.map((str) => Number(str)) || [0, 0];
this.searchWiki(this.#coordinates); this.searchWiki(this.#coordinates);
} }
} }
@ -152,7 +170,9 @@
origin: '*', origin: '*',
}); });
// https://www.mediawiki.org/wiki/API:Geosearch // https://www.mediawiki.org/wiki/API:Geosearch
this.#results = await fetch(`https://en.wikipedia.org/w/api.php?${params}`) this.#results = await fetch(
`https://en.wikipedia.org/w/api.php?${params}`
)
.then((response) => response.json()) .then((response) => response.json())
.then((data) => data?.query?.geosearch ?? []); .then((data) => data?.query?.geosearch ?? []);

View File

@ -15,7 +15,7 @@
margin: 0; margin: 0;
} }
spatial-geometry:has(record-player) { fc-geometry:has(record-player) {
&::part(resize-nw), &::part(resize-nw),
&::part(resize-ne), &::part(resize-ne),
&::part(resize-se), &::part(resize-se),
@ -24,7 +24,7 @@
} }
} }
spatial-geometry > video { fc-geometry > video {
height: 100%; height: 100%;
} }
</style> </style>
@ -35,45 +35,47 @@
ffmpeg -framerate 25 -pattern_type glob -i '*.png' -c:v prores -pix_fmt yuva444p10le dancing-flower.mov ffmpeg -framerate 25 -pattern_type glob -i '*.png' -c:v prores -pix_fmt yuva444p10le dancing-flower.mov
ffmpeg -framerate 25 -f image2 -pattern_type glob -i '*.png' -c:v libvpx-vp9 -pix_fmt yuva420p dancing-flowers.webm ffmpeg -framerate 25 -f image2 -pattern_type glob -i '*.png' -c:v libvpx-vp9 -pix_fmt yuva420p dancing-flowers.webm
--> -->
<spatial-geometry x="100" y="75" width="330" height="198"> <fc-geometry x="100" y="75" width="330" height="198">
<record-player> <record-player>
<audio src="/Feather.mp3"></audio> <audio src="/Feather.mp3"></audio>
</record-player> </record-player>
</spatial-geometry> </fc-geometry>
<spatial-geometry x="25" y="300" width="166" height="200"> <fc-geometry x="25" y="300" width="166" height="200">
<video loop> <video loop>
<source src="/dancing-flower.mov" type="video/quicktime" /> <source src="/dancing-flower.mov" type="video/quicktime" />
<source src="/dancing-flower.webm" type="video/webm" /> <source src="/dancing-flower.webm" type="video/webm" />
</video> </video>
</spatial-geometry> </fc-geometry>
<spatial-geometry x="155" y="315" width="166" height="200"> <fc-geometry x="155" y="315" width="166" height="200">
<video loop> <video loop>
<source src="/dancing-flower.mov" type="video/quicktime" /> <source src="/dancing-flower.mov" type="video/quicktime" />
<source src="/dancing-flower.webm" type="video/webm" /> <source src="/dancing-flower.webm" type="video/webm" />
</video> </video>
</spatial-geometry> </fc-geometry>
<spatial-geometry x="280" y="305" width="166" height="200"> <fc-geometry x="280" y="305" width="166" height="200">
<video loop> <video loop>
<source src="/dancing-flower.mov" type="video/quicktime" /> <source src="/dancing-flower.mov" type="video/quicktime" />
<source src="/dancing-flower.webm" type="video/webm" /> <source src="/dancing-flower.webm" type="video/webm" />
</video> </video>
</spatial-geometry> </fc-geometry>
<script type="module"> <script type="module">
import { SpatialGeometry } from '../src/canvas/spatial-geometry.ts'; import { FolkGeometry } from '../src/canvas/fc-geometry.ts';
import { RecordPlayer } from '../src/music/record-player.ts'; import { RecordPlayer } from '../src/music/record-player.ts';
SpatialGeometry.register(); FolkGeometry.register();
RecordPlayer.register(); RecordPlayer.register();
let proximityDistance = 200; let proximityDistance = 200;
const proximitySet = new Set(); const proximitySet = new Set();
const recordPlayerGeometry = document.querySelector('spatial-geometry:has(record-player)'); const recordPlayerGeometry = document.querySelector(
'fc-geometry:has(record-player)'
);
const recordPlayer = recordPlayerGeometry.firstElementChild; const recordPlayer = recordPlayerGeometry.firstElementChild;
const flowers = document.querySelectorAll('spatial-geometry:has(video)'); const flowers = document.querySelectorAll('fc-geometry:has(video)');
// set playback rate when video is ready // set playback rate when video is ready
function setPlayback(e) { function setPlayback(e) {
e.target.playbackRate = (91 / 60) * e.target.duration; e.target.playbackRate = (91 / 60) * e.target.duration;

View File

@ -15,23 +15,23 @@
margin: 0; margin: 0;
} }
spatial-geometry { fc-geometry {
border: 2px solid black; border: 2px solid black;
} }
</style> </style>
</head> </head>
<body> <body>
<script type="module"> <script type="module">
import { SpatialGeometry } from '../src/canvas/spatial-geometry.ts'; import { FolkGeometry } from '../src/canvas/fc-geometry.ts';
SpatialGeometry.register(); FolkGeometry.register();
const geometries = []; const geometries = [];
const now = performance.now(); const now = performance.now();
for (let i = 0; i < 100; i++) { for (let i = 0; i < 100; i++) {
for (let j = 0; j < 100; j++) { for (let j = 0; j < 100; j++) {
const geo = document.createElement('spatial-geometry'); const geo = document.createElement('fc-geometry');
geo.x = 50 * i; geo.x = 50 * i;
geo.y = 50 * j; geo.y = 50 * j;
geo.width = geo.height = 45; geo.width = geo.height = 45;

View File

@ -15,27 +15,27 @@
margin: 0; margin: 0;
} }
spatial-geometry { fc-geometry {
background: rgb(187, 178, 178); background: rgb(187, 178, 178);
box-shadow: rgba(0, 0, 0, 0.2) 1.95px 1.95px 2.6px; box-shadow: rgba(0, 0, 0, 0.2) 1.95px 1.95px 2.6px;
transition: scale 100ms ease-out, box-shadow 100ms ease-out; transition: scale 100ms ease-out, box-shadow 100ms ease-out;
} }
spatial-geometry:state(move) { fc-geometry:state(move) {
scale: 1.05; scale: 1.05;
box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px; box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px;
} }
</style> </style>
</head> </head>
<body> <body>
<spatial-geometry x="100" y="100" width="50" height="50"></spatial-geometry> <fc-geometry x="100" y="100" width="50" height="50"></fc-geometry>
<spatial-geometry x="100" y="200" width="50" height="50"></spatial-geometry> <fc-geometry x="100" y="200" width="50" height="50"></fc-geometry>
<spatial-geometry x="100" y="300" width="50" height="50"></spatial-geometry> <fc-geometry x="100" y="300" width="50" height="50"></fc-geometry>
<script type="module"> <script type="module">
import { SpatialGeometry } from '../src/canvas/spatial-geometry.ts'; import { FolkGeometry } from '../src/canvas/fc-geometry.ts';
SpatialGeometry.register(); FolkGeometry.register();
</script> </script>
</body> </body>
</html> </html>

View File

@ -22,21 +22,26 @@
</style> </style>
</head> </head>
<body> <body>
<spatial-geometry x="50" y="50" height="300" width="500"> <fc-geometry x="50" y="50" height="300" width="500">
<s-table></s-table> <s-table></s-table>
</spatial-geometry> </fc-geometry>
<script type="module"> <script type="module">
import { SpatialGeometry } from '../src/canvas/spatial-geometry.ts'; import { FolkGeometry } from '../src/canvas/fc-geometry.ts';
import { SpreadsheetTable, SpreadsheetHeader, SpreadsheetCell } from '../src/spreadsheet/spreadsheet.ts'; import {
SpreadsheetTable,
SpreadsheetHeader,
SpreadsheetCell,
} from '../src/spreadsheet/spreadsheet.ts';
SpatialGeometry.register(); FolkGeometry.register();
SpreadsheetTable.register(); SpreadsheetTable.register();
SpreadsheetHeader.register(); SpreadsheetHeader.register();
SpreadsheetCell.register(); SpreadsheetCell.register();
document.querySelector(`s-cell[column="A"][row="1"]`).expression = '1'; document.querySelector(`s-cell[column="A"][row="1"]`).expression = '1';
document.querySelector(`s-cell[column="A"][row="2"]`).expression = '$A1 * 2'; document.querySelector(`s-cell[column="A"][row="2"]`).expression =
'$A1 * 2';
</script> </script>
</body> </body>
</html> </html>

View File

@ -1,6 +1,6 @@
import { SpatialConnection } from './spatial-connection'; import { FolkConnection } from './fc-connection';
export class EventPropagator extends SpatialConnection { export class EventPropagator extends FolkConnection {
static tagName = 'event-propagator'; static tagName = 'event-propagator';
#triggers = (this.getAttribute('triggers') || '').split(','); #triggers = (this.getAttribute('triggers') || '').split(',');

View File

@ -26,12 +26,12 @@ export type Arrow = [
declare global { declare global {
interface HTMLElementTagNameMap { interface HTMLElementTagNameMap {
'spatial-connection': SpatialConnection; 'fc-connection': FolkConnection;
} }
} }
export class SpatialConnection extends AbstractArrow { export class FolkConnection extends AbstractArrow {
static tagName = 'spatial-connection'; static tagName = 'fc-connection';
#options: StrokeOptions = { #options: StrokeOptions = {
size: 7, size: 7,

7
src/canvas/fc-canvas.ts Normal file
View File

@ -0,0 +1,7 @@
export class FCSpace extends HTMLElement {
static tagName = 'fc-space';
static register() {
customElements.define(this.tagName, this);
}
}

View File

@ -180,13 +180,13 @@ styles.replaceSync(`
declare global { declare global {
interface HTMLElementTagNameMap { interface HTMLElementTagNameMap {
'spatial-geometry': SpatialGeometry; 'fc-geometry': FolkGeometry;
} }
} }
// TODO: add z coordinate? // TODO: add z coordinate?
export class SpatialGeometry extends HTMLElement { export class FolkGeometry extends HTMLElement {
static tagName = 'spatial-geometry'; static tagName = 'fc-geometry';
static register() { static register() {
customElements.define(this.tagName, this); customElements.define(this.tagName, this);

View File

@ -25,12 +25,12 @@ styles.replaceSync(`
declare global { declare global {
interface HTMLElementTagNameMap { interface HTMLElementTagNameMap {
'spatial-ink': SpatialInk; 'fc-ink': FolkInk;
} }
} }
export class SpatialInk extends HTMLElement { export class FolkInk extends HTMLElement {
static tagName = 'spatial-ink'; static tagName = 'fc-ink';
static register() { static register() {
customElements.define(this.tagName, this); customElements.define(this.tagName, this);
@ -81,7 +81,8 @@ export class SpatialInk extends HTMLElement {
this.#update(); this.#update();
} }
#simulatePressure = this.getAttribute('streamline') === 'false' ? false : true; #simulatePressure =
this.getAttribute('streamline') === 'false' ? false : true;
get simulatePressure() { get simulatePressure() {
return this.#simulatePressure; return this.#simulatePressure;
@ -104,7 +105,10 @@ export class SpatialInk extends HTMLElement {
constructor() { constructor() {
super(); super();
const shadowRoot = this.attachShadow({ mode: 'open', delegatesFocus: true }); const shadowRoot = this.attachShadow({
mode: 'open',
delegatesFocus: true,
});
shadowRoot.adoptedStyleSheets.push(styles); shadowRoot.adoptedStyleSheets.push(styles);
this.#svg.appendChild(this.#path); this.#svg.appendChild(this.#path);
shadowRoot.appendChild(this.#svg); shadowRoot.appendChild(this.#svg);
@ -189,7 +193,10 @@ export class SpatialInk extends HTMLElement {
cap: true, cap: true,
}, },
}; };
this.#path.setAttribute('d', this.#getSvgPathFromStroke(getStroke(this.#points, options))); this.#path.setAttribute(
'd',
this.#getSvgPathFromStroke(getStroke(this.#points, options))
);
} }
#getSvgPathFromStroke(stroke: Stroke): string { #getSvgPathFromStroke(stroke: Stroke): string {

View File

@ -1,7 +0,0 @@
export class SpatialCanvas extends HTMLElement {
static tagName = 'spatial-canvas';
static register() {
customElements.define(this.tagName, this);
}
}