add imperative radial space (working on composition of coordinate spaces)
This commit is contained in:
parent
a141d05e87
commit
7535245702
|
|
@ -0,0 +1,45 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Shapes</title>
|
||||||
|
<style>
|
||||||
|
html {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
position: fixed;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
min-height: 100%;
|
||||||
|
position: relative;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
folk-shape {
|
||||||
|
background: rgb(187, 178, 178);
|
||||||
|
}
|
||||||
|
|
||||||
|
folk-space-radial {
|
||||||
|
width: 500px;
|
||||||
|
height: 500px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<folk-space-radial>
|
||||||
|
<folk-shape x="0" y="100" width="50" height="50"></folk-shape>
|
||||||
|
<folk-shape x="0" y="200" width="50" height="50"></folk-shape>
|
||||||
|
<folk-shape x="20" y="300" width="50" height="50" rotation="45"></folk-shape>
|
||||||
|
<folk-shape x="20" y="400" width="50" height="50" rotation="45"></folk-shape>
|
||||||
|
<folk-shape x="20" y="500" width="50" height="50" rotation="45"></folk-shape>
|
||||||
|
</folk-space-radial>
|
||||||
|
|
||||||
|
<script type="module">
|
||||||
|
import '../src/standalone/folk-shape.ts';
|
||||||
|
import '../src/standalone/folk-space-radial.ts';
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
@ -0,0 +1,91 @@
|
||||||
|
import { css, html } from './common/tags';
|
||||||
|
import { FolkShape } from './folk-shape';
|
||||||
|
import { DOMRectTransform } from './common/DOMRectTransform';
|
||||||
|
|
||||||
|
const styles = css`
|
||||||
|
:host {
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
border: 2px dashed hsl(214, 84%, 56%);
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
::slotted(*) {
|
||||||
|
position: absolute;
|
||||||
|
transform-origin: 50% 0%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center-point {
|
||||||
|
position: absolute;
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
background: hsl(214, 84%, 56%);
|
||||||
|
border-radius: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export class FolkSpaceRadial extends HTMLElement {
|
||||||
|
static tagName = 'folk-space-radial';
|
||||||
|
|
||||||
|
static define() {
|
||||||
|
if (!customElements.get(this.tagName)) {
|
||||||
|
customElements.define(this.tagName, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#shadow = this.attachShadow({ mode: 'open' });
|
||||||
|
#centerPoint: HTMLDivElement;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.#shadow.adoptedStyleSheets = [styles];
|
||||||
|
|
||||||
|
// Create center point marker
|
||||||
|
this.#centerPoint = document.createElement('div');
|
||||||
|
this.#centerPoint.className = 'center-point';
|
||||||
|
|
||||||
|
this.#shadow.innerHTML = html` <slot></slot> `;
|
||||||
|
this.#shadow.appendChild(this.#centerPoint);
|
||||||
|
|
||||||
|
// Listen for changes in the slot to layout children when they change
|
||||||
|
const slot = this.#shadow.querySelector('slot');
|
||||||
|
slot?.addEventListener('slotchange', () => this.#layoutChildren());
|
||||||
|
}
|
||||||
|
|
||||||
|
connectedCallback() {
|
||||||
|
this.#layoutChildren();
|
||||||
|
}
|
||||||
|
|
||||||
|
#layoutChildren() {
|
||||||
|
const slot = this.#shadow.querySelector('slot');
|
||||||
|
const assignedElements = slot?.assignedElements() || [];
|
||||||
|
const count = assignedElements.length;
|
||||||
|
|
||||||
|
// Determine the radius and center of the radial layout
|
||||||
|
const radius = Math.min(this.clientWidth, this.clientHeight) / 2 - 50;
|
||||||
|
const centerX = this.clientWidth / 2;
|
||||||
|
const centerY = this.clientHeight / 2;
|
||||||
|
|
||||||
|
assignedElements.forEach((element, index) => {
|
||||||
|
if (!(element instanceof FolkShape)) return;
|
||||||
|
|
||||||
|
// Calculate the angle for each child
|
||||||
|
const angle = (index / count) * 2 * Math.PI;
|
||||||
|
|
||||||
|
// Create a transform for each child
|
||||||
|
const transform = new DOMRectTransform({
|
||||||
|
x: centerX + radius * Math.cos(angle),
|
||||||
|
y: centerY + radius * Math.sin(angle),
|
||||||
|
rotation: angle,
|
||||||
|
transformOrigin: { x: 0.5, y: 0 },
|
||||||
|
});
|
||||||
|
|
||||||
|
// Set the transform on the child
|
||||||
|
element.setTransform(transform);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FolkSpaceRadial.define();
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
import { FolkSpaceRadial } from '../folk-space-radial';
|
||||||
|
|
||||||
|
FolkSpaceRadial.define();
|
||||||
|
|
||||||
|
export { FolkSpaceRadial };
|
||||||
Loading…
Reference in New Issue