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