You've already forked obsidian-visualiser
Progressing on CanvasEditor
This commit is contained in:
84
shared/canvas.util.ts
Normal file
84
shared/canvas.util.ts
Normal file
@@ -0,0 +1,84 @@
|
||||
import type { CanvasNode } from "~/types/canvas";
|
||||
import { clamp } from "#shared/general.utils";
|
||||
|
||||
export type Direction = 'bottom' | 'top' | 'left' | 'right';
|
||||
export type Position = { x: number, y: number };
|
||||
export type Path = {
|
||||
path: string;
|
||||
from: Position;
|
||||
to: Position;
|
||||
side: Direction;
|
||||
}
|
||||
|
||||
export function edgePos(side: Direction, pos: Position, offset: number): Position {
|
||||
switch (side) {
|
||||
case "left":
|
||||
return {
|
||||
x: pos.x - offset,
|
||||
y: pos.y
|
||||
};
|
||||
case "right":
|
||||
return {
|
||||
x: pos.x + offset,
|
||||
y: pos.y
|
||||
};
|
||||
case "top":
|
||||
return {
|
||||
x: pos.x,
|
||||
y: pos.y - offset
|
||||
};
|
||||
case "bottom":
|
||||
return {
|
||||
x: pos.x,
|
||||
y: pos.y + offset
|
||||
}
|
||||
}
|
||||
}
|
||||
export function getNode(nodes: CanvasNode[], id: string): CanvasNode | undefined
|
||||
{
|
||||
return nodes.find(e => e.id === id);
|
||||
}
|
||||
export function posFromDir(e: { minX: number, minY: number, maxX: number, maxY: number }, t: Direction): Position {
|
||||
switch (t) {
|
||||
case "top":
|
||||
return { x: (e.minX + e.maxX) / 2, y: e.minY };
|
||||
case "right":
|
||||
return { x: e.maxX, y: (e.minY + e.maxY) / 2 };
|
||||
case "bottom":
|
||||
return { x: (e.minX + e.maxX) / 2, y: e.maxY };
|
||||
case "left":
|
||||
return { x: e.minX, y: (e.minY + e.maxY) / 2 };
|
||||
}
|
||||
}
|
||||
export function getBbox(node: CanvasNode): { minX: number, minY: number, maxX: number, maxY: number } {
|
||||
return { minX: node.x, minY: node.y, maxX: node.x + node.width, maxY: node.y + node.height };
|
||||
}
|
||||
export function getPath(from: CanvasNode, fromSide: Direction, to: CanvasNode, toSide: Direction): Path | undefined {
|
||||
if(from === undefined || to === undefined)
|
||||
return;
|
||||
|
||||
const start = posFromDir(getBbox(from), fromSide), end = posFromDir(getBbox(to), toSide);
|
||||
return bezier(start, fromSide, end, toSide);
|
||||
}
|
||||
export function bezier(from: Position, fromSide: Direction, to: Position, toSide: Direction): Path {
|
||||
const r = Math.hypot(from.x - to.x, from.y - to.y), o = clamp(r / 2, 70, 150), a = edgePos(fromSide, from, o), s = edgePos(toSide, to, o);
|
||||
return {
|
||||
path: `M${from.x},${from.y} C${a.x},${a.y} ${s.x},${s.y} ${to.x},${to.y}`,
|
||||
from: from,
|
||||
to: to,
|
||||
side: toSide,
|
||||
};
|
||||
}
|
||||
export function labelCenter(from: CanvasNode, fromSide: Direction, to: CanvasNode, toSide: Direction): string {
|
||||
const start = posFromDir(getBbox(from), fromSide), end = posFromDir(getBbox(to), toSide);
|
||||
const len = Math.hypot(start.x - end.x, start.y - end.y), offset = clamp(len / 2, 70, 150), b = edgePos(fromSide, start, offset), s = edgePos(toSide, end, offset);
|
||||
const center = getCenter(start, end, b, s, 0.5);
|
||||
return `translate(${center.x}px, ${center.y}px)`;
|
||||
}
|
||||
export function getCenter(n: Position, i: Position, r: Position, o: Position, e: number): Position {
|
||||
const a = 1 - e, s = a * a * a, l = 3 * e * a * a, c = 3 * e * e * a, u = e * e * e;
|
||||
return {
|
||||
x: s * n.x + l * r.x + c * o.x + u * i.x,
|
||||
y: s * n.y + l * r.y + c * o.y + u * i.y
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user