feat(canvas): fix rotation, clarify frame membership and load icons on demand
This commit is contained in:
@@ -4,17 +4,28 @@ import type { CanvasNode } from "./canvas-elements.ts";
|
||||
import { nodeCenter, nodeSize } from "./canvas-geometry.ts";
|
||||
|
||||
/** Membership changes only on content drops, never on frame movement or resize. */
|
||||
export function containingFrame(node: CanvasNode, nodes: CanvasNode[]) {
|
||||
if (node.data.kind === "frame") return undefined;
|
||||
const center = nodeCenter(node);
|
||||
return nodes.filter((frame) => {
|
||||
if (frame.data.kind !== "frame") return false;
|
||||
const { width, height } = nodeSize(frame);
|
||||
return center.x >= frame.position.x && center.x <= frame.position.x + width && center.y >= frame.position.y && center.y <= frame.position.y + height;
|
||||
}).sort((a, b) => nodeSize(a).width * nodeSize(a).height - nodeSize(b).width * nodeSize(b).height)[0];
|
||||
}
|
||||
|
||||
export function frameDropFeedback(nodes: CanvasNode[], droppedIds: string[]) {
|
||||
const ids = new Set(droppedIds);
|
||||
return nodes.filter((node) => ids.has(node.id) && node.data.kind !== "frame").map((node) => ({
|
||||
id: node.id, from: node.data.frameId, to: containingFrame(node, nodes)?.id,
|
||||
}));
|
||||
}
|
||||
|
||||
export function assignFrameMembership(nodes: CanvasNode[], droppedIds: string[]): CanvasNode[] {
|
||||
const dropped = new Set(droppedIds);
|
||||
const frames = nodes.filter((node) => node.data.kind === "frame");
|
||||
return nodes.map((node) => {
|
||||
if (!dropped.has(node.id) || node.data.kind === "frame") return node;
|
||||
const center = nodeCenter(node);
|
||||
const candidates = frames.filter((frame) => {
|
||||
const { width, height } = nodeSize(frame);
|
||||
return center.x >= frame.position.x && center.x <= frame.position.x + width && center.y >= frame.position.y && center.y <= frame.position.y + height;
|
||||
}).sort((a, b) => nodeSize(a).width * nodeSize(a).height - nodeSize(b).width * nodeSize(b).height);
|
||||
const frameId = candidates[0]?.id;
|
||||
const frameId = containingFrame(node, nodes)?.id;
|
||||
if (frameId === node.data.frameId) return node;
|
||||
const { frameId: _old, ...data } = node.data;
|
||||
return { ...node, data: { ...data, ...(frameId ? { frameId } : {}) } };
|
||||
|
||||
Reference in New Issue
Block a user