From 3270b18597fa62171554b9e02c3ba2972956affe Mon Sep 17 00:00:00 2001 From: Orion Reed Date: Mon, 16 Dec 2024 00:00:52 -0500 Subject: [PATCH] animation frame controller --- src/folk-graph.ts | 62 ++++++++++++++++++++--------------------------- 1 file changed, 26 insertions(+), 36 deletions(-) diff --git a/src/folk-graph.ts b/src/folk-graph.ts index 347b40f..001ecb0 100644 --- a/src/folk-graph.ts +++ b/src/folk-graph.ts @@ -1,9 +1,9 @@ -import { DOMRectTransform } from './common/DOMRectTransform.ts'; import { FolkBaseSet } from './folk-base-set.ts'; import { PropertyValues } from '@lit/reactive-element'; import { Layout } from 'webcola'; import { FolkShape } from './folk-shape.ts'; import { FolkArrow } from './folk-arrow.ts'; +import { AnimationFrameController, AnimationFrameControllerHost } from './common/animation-frame-controller.ts'; type ColaNode = { id: FolkShape; @@ -19,29 +19,29 @@ type ColaLink = { target: FolkShape; }; -export class FolkGraph extends FolkBaseSet { +export class FolkGraph extends FolkBaseSet implements AnimationFrameControllerHost { static override tagName = 'folk-graph'; private graphSim: Layout; - private animationFrameId?: number; private colaNodes: Map = new Map(); private colaLinks: Map = new Map(); + #rAF = new AnimationFrameController(this); constructor() { super(); this.graphSim = new Layout(); } + render() {} + connectedCallback() { super.connectedCallback(); - this.startSimulation(); + this.#rAF.start(); } disconnectedCallback() { super.disconnectedCallback(); - if (this.animationFrameId) { - cancelAnimationFrame(this.animationFrameId); - } + this.#rAF.stop(); this.colaNodes.clear(); this.colaLinks.clear(); } @@ -51,21 +51,35 @@ export class FolkGraph extends FolkBaseSet { this.updateGraph(); } + tick() { + this.graphSim.start(1, 0, 0, 0, true, false); + + for (const node of this.graphSim.nodes() as ColaNode[]) { + const shape = node.id; + if (shape !== document.activeElement) { + shape.x = node.x - shape.width / 2; + shape.y = node.y - shape.height / 2; + } else { + const rect = shape.getTransformDOMRect(); + node.x = rect.center.x; + node.y = rect.center.y; + } + } + } + private updateGraph() { - // Clear existing nodes and links this.colaNodes.clear(); this.colaLinks.clear(); // Create nodes for shapes for (const element of this.sourceElements) { if (!(element instanceof FolkShape)) continue; - const rect = this.sourcesMap.get(element); - if (!(rect instanceof DOMRectTransform)) continue; + const rect = element.getTransformDOMRect(); const node: ColaNode = { id: element, - x: rect.x + rect.width / 2, - y: rect.y + rect.height / 2, + x: rect.center.x, + y: rect.center.y, width: rect.width, height: rect.height, rotation: rect.rotation, @@ -104,28 +118,4 @@ export class FolkGraph extends FolkBaseSet { this.graphSim.nodes(nodes).links(links).linkDistance(250).avoidOverlaps(true).handleDisconnected(true); } - - private startSimulation() { - const step = () => { - this.graphSim.start(1, 0, 0, 0, true, false); - - for (const node of this.graphSim.nodes() as ColaNode[]) { - const shape = node.id; - const rect = this.sourcesMap.get(shape); - if (!(rect instanceof DOMRectTransform)) continue; - - if (shape !== document.activeElement) { - shape.x = node.x - rect.width / 2; - shape.y = node.y - rect.height / 2; - } else { - node.x = rect.x + rect.width / 2; - node.y = rect.y + rect.height / 2; - } - } - - this.animationFrameId = requestAnimationFrame(step); - }; - - this.animationFrameId = requestAnimationFrame(step); - } }