Add grid snapping, grid preview, fix zoom slowdowns and canvas markdown editing being at the wrong size.

This commit is contained in:
2025-03-04 15:14:12 +01:00
parent 0b97e9a295
commit f2d00097d6
12 changed files with 151 additions and 62 deletions

View File

@@ -202,7 +202,7 @@ class SnapPointCache {
export class SnapFinder {
private spatialGrid: SpatialGrid;
private snapPointCache: SnapPointCache;
private config: SnapConfig;
config: SnapConfig;
hints: Ref<SnapHint[]>;
viewport: Ref<Box>;
@@ -216,24 +216,28 @@ export class SnapFinder {
this.viewport = viewport;
}
add(node: CanvasNode): void {
add(node: CanvasNode): void
{
this.spatialGrid.insert(node);
this.snapPointCache.insert(node);
this.hints.value.length = 0;
}
remove(node: CanvasNode): void {
remove(node: CanvasNode): void
{
this.spatialGrid.remove(node);
this.snapPointCache.invalidate(node);
this.hints.value.length = 0;
}
update(node: CanvasNode): void {
update(node: CanvasNode): void
{
this.remove(node);
this.add(node);
}
findEdgeSnapPosition(node: string, x: number, y: number): { x: number, y: number, node: string, direction: Direction } | undefined {
findEdgeSnapPosition(node: string, x: number, y: number): { x: number, y: number, node: string, direction: Direction } | undefined
{
const near = [...this.spatialGrid.fetch(x, y)?.values().filter(e => e !== node).flatMap(e => this.snapPointCache.getSnapPoints(e)?.map(_e => ({ ..._e, node: e })) ?? []) ?? []].filter(e => e.type === TYPE.EDGE);
let nearestDistance = this.config.threshold, nearest = undefined;
@@ -248,7 +252,8 @@ export class SnapFinder {
return nearest;
}
findNodeSnapPosition(node: CanvasNode, resizeHandle?: Box): Partial<Box> {
findNodeSnapPosition(node: CanvasNode, resizeHandle?: Box): Partial<Box>
{
const result: Partial<Box> = {
x: undefined,
y: undefined,
@@ -256,6 +261,16 @@ export class SnapFinder {
h: undefined,
};
if(!this.config.preferences.neighborSnap)
{
result.x = this.snapToGrid(node.x);
result.w = this.snapToGrid(node.width);
result.y = this.snapToGrid(node.y);
result.h = this.snapToGrid(node.height);
return result;
}
this.hints.value.length = 0;
this.snapPointCache.invalidate(node);
@@ -267,7 +282,8 @@ export class SnapFinder {
return this.applySnap(node, bestSnap.x, bestSnap.y, resizeHandle);
}
private findBestSnap(activePoints: SnapPoint[], otherPoints: SnapPoint[], threshold: number, resizeHandle?: Box): Partial<Position> {
private findBestSnap(activePoints: SnapPoint[], otherPoints: SnapPoint[], threshold: number, resizeHandle?: Box): Partial<Position>
{
let bestSnap: Partial<Position> = {};
let bestDiffX = threshold, bestDiffY = threshold;
let xHints: SnapHint[] = [], yHints: SnapHint[] = [];
@@ -312,20 +328,27 @@ export class SnapFinder {
return bestSnap;
}
private applySnap(node: CanvasNode, offsetx?: number, offsety?: number, resizeHandle?: Box): Partial<Box> {
private snapToGrid(pos?: number): number | undefined
{
return pos && this.config.preferences.gridSnap && this.config.preferences.spacing ? Math.round(pos / this.config.preferences.spacing) * this.config.preferences.spacing : undefined;
}
private applySnap(node: CanvasNode, offsetx?: number, offsety?: number, resizeHandle?: Box): Partial<Box>
{
const result: Partial<Box> = { x: undefined, y: undefined, w: undefined, h: undefined };
if (resizeHandle) {
if (offsetx) result.x = node.x + offsetx * resizeHandle.x;
if (offsetx) result.w = node.width + offsetx * resizeHandle.w;
if (offsety) result.y = node.y + offsety * resizeHandle.y;
if (offsety) result.h = node.height - offsety * resizeHandle.h;
} else {
if (offsetx) result.x = node.x + offsetx;
if (offsety) result.y = node.y + offsety;
if (resizeHandle)
{
result.x = offsetx ? node.x + offsetx * resizeHandle.x : this.snapToGrid(node.x);
result.w = offsetx ? node.width + offsetx * resizeHandle.w : this.snapToGrid(node.width);
result.y = offsety ? node.y + offsety * resizeHandle.y : this.snapToGrid(node.y);
result.h = offsety ? node.height - offsety * resizeHandle.h : this.snapToGrid(node.height);
}
else
{
result.x = offsetx ? node.x + offsetx : this.snapToGrid(node.x);
result.y = offsety ? node.y + offsety : this.snapToGrid(node.y);
}
//console.log(result, offsetx, offsety);
return result;
}