@weasel-js/guides 1.10.0 → 1.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -23
- package/dist/index.d.ts +205 -152
- package/dist/index.js +421 -340
- package/dist/index.js.map +1 -1
- package/package.json +4 -16
- package/dist/chunk-B25KFI3I.js +0 -18
- package/dist/chunk-B25KFI3I.js.map +0 -1
- package/dist/chunk-LOFNN7EQ.js +0 -45
- package/dist/chunk-LOFNN7EQ.js.map +0 -1
- package/dist/chunk-TLFMAZ6M.js +0 -31
- package/dist/chunk-TLFMAZ6M.js.map +0 -1
- package/dist/insert.d.ts +0 -30
- package/dist/insert.js +0 -58
- package/dist/insert.js.map +0 -1
- package/dist/move.d.ts +0 -42
- package/dist/move.js +0 -18
- package/dist/move.js.map +0 -1
- package/dist/pointSnapToGrid-BaVEjV23.d.ts +0 -13
- package/dist/resize.d.ts +0 -38
- package/dist/resize.js +0 -89
- package/dist/resize.js.map +0 -1
- package/dist/types-DRSPiXfk.d.ts +0 -38
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@weasel-js/guides",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Placement aids for weasel: grids,
|
|
3
|
+
"version": "1.11.0",
|
|
4
|
+
"description": "Placement aids for weasel: grids, ruler guides, snap sources for them and for sibling alignment and spacing, and container layout strategies.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"sideEffects": false,
|
|
@@ -13,24 +13,12 @@
|
|
|
13
13
|
"import": "./dist/index.js",
|
|
14
14
|
"types": "./dist/index.d.ts"
|
|
15
15
|
},
|
|
16
|
-
"./move": {
|
|
17
|
-
"import": "./dist/move.js",
|
|
18
|
-
"types": "./dist/move.d.ts"
|
|
19
|
-
},
|
|
20
|
-
"./resize": {
|
|
21
|
-
"import": "./dist/resize.js",
|
|
22
|
-
"types": "./dist/resize.d.ts"
|
|
23
|
-
},
|
|
24
|
-
"./insert": {
|
|
25
|
-
"import": "./dist/insert.js",
|
|
26
|
-
"types": "./dist/insert.d.ts"
|
|
27
|
-
},
|
|
28
16
|
"./package.json": "./package.json"
|
|
29
17
|
},
|
|
30
18
|
"peerDependencies": {
|
|
31
19
|
"react": ">=18",
|
|
32
|
-
"@weasel-js/core": "1.
|
|
33
|
-
"@weasel-js/geom": "1.
|
|
20
|
+
"@weasel-js/core": "1.11.0",
|
|
21
|
+
"@weasel-js/geom": "1.11.0"
|
|
34
22
|
},
|
|
35
23
|
"author": "orochi235",
|
|
36
24
|
"homepage": "https://orochi235.github.io/weasel/",
|
package/dist/chunk-B25KFI3I.js
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
// src/behaviors/resize/pointSnapToGrid.ts
|
|
2
|
-
function pointSnapToGrid(args) {
|
|
3
|
-
const { spacing, frame = "dragged-corner", bypassKey } = args;
|
|
4
|
-
const round = (v) => Math.round(v / spacing) * spacing;
|
|
5
|
-
return {
|
|
6
|
-
id: `pointSnapToGrid:${frame}`,
|
|
7
|
-
onMove(ctx) {
|
|
8
|
-
if (bypassKey && ctx.modifiers[bypassKey]) return null;
|
|
9
|
-
const src = frame === "dragged-corner" ? ctx.draggedCorner : frame === "fixed-corner" ? ctx.fixedCorner : frame === "center" ? ctx.center : ctx.origin;
|
|
10
|
-
if (!src) return null;
|
|
11
|
-
return { frame, worldX: round(src.worldX), worldY: round(src.worldY) };
|
|
12
|
-
}
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export { pointSnapToGrid };
|
|
17
|
-
//# sourceMappingURL=chunk-B25KFI3I.js.map
|
|
18
|
-
//# sourceMappingURL=chunk-B25KFI3I.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/behaviors/resize/pointSnapToGrid.ts"],"names":[],"mappings":";AAaO,SAAS,gBAAsC,IAAA,EAIzB;AAC3B,EAAA,MAAM,EAAE,OAAA,EAAS,KAAA,GAAQ,gBAAA,EAAkB,WAAU,GAAI,IAAA;AACzD,EAAA,MAAM,QAAQ,CAAC,CAAA,KAAc,KAAK,KAAA,CAAM,CAAA,GAAI,OAAO,CAAA,GAAI,OAAA;AAEvD,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,mBAAmB,KAAK,CAAA,CAAA;AAAA,IAC5B,OAAO,GAAA,EAAsD;AAC3D,MAAA,IAAI,SAAA,IAAa,GAAA,CAAI,SAAA,CAAU,SAAS,GAAG,OAAO,IAAA;AAClD,MAAA,MAAM,GAAA,GACJ,KAAA,KAAU,gBAAA,GAAmB,GAAA,CAAI,aAAA,GACjC,KAAA,KAAU,cAAA,GAAiB,GAAA,CAAI,WAAA,GAC/B,KAAA,KAAU,QAAA,GAAW,GAAA,CAAI,SACzB,GAAA,CAAI,MAAA;AACN,MAAA,IAAI,CAAC,KAAK,OAAO,IAAA;AACjB,MAAA,OAAO,EAAE,KAAA,EAAO,MAAA,EAAQ,KAAA,CAAM,GAAA,CAAI,MAAM,CAAA,EAAG,MAAA,EAAQ,KAAA,CAAM,GAAA,CAAI,MAAM,CAAA,EAAE;AAAA,IACvE;AAAA,GACF;AACF","file":"chunk-B25KFI3I.js","sourcesContent":["import type {\n ModifierState,\n PointSnapBehavior,\n PointSnapContext,\n PointSnapFrame,\n PointSnapResult,\n Bounds,\n} from '@weasel-js/core';\n\n/** Resize behavior that snaps one reference point of the resize — the dragged\n * corner, the fixed corner, or the center, per `frame` — to a grid, moving\n * the whole pose by the same delta. Unlike the bounds-level `snapToGrid`,\n * this preserves the node's dimensions. */\nexport function pointSnapToGrid<TPose extends Bounds>(args: {\n spacing: number;\n frame?: PointSnapFrame;\n bypassKey?: keyof ModifierState;\n}): PointSnapBehavior<TPose> {\n const { spacing, frame = 'dragged-corner', bypassKey } = args;\n const round = (v: number) => Math.round(v / spacing) * spacing;\n\n return {\n id: `pointSnapToGrid:${frame}`,\n onMove(ctx: PointSnapContext<TPose>): PointSnapResult | null {\n if (bypassKey && ctx.modifiers[bypassKey]) return null;\n const src =\n frame === 'dragged-corner' ? ctx.draggedCorner :\n frame === 'fixed-corner' ? ctx.fixedCorner :\n frame === 'center' ? ctx.center :\n ctx.origin;\n if (!src) return null;\n return { frame, worldX: round(src.worldX), worldY: round(src.worldY) };\n },\n };\n}\n"]}
|
package/dist/chunk-LOFNN7EQ.js
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { AUTO_ORIGIN_PROJECTION, screenTolerance } from '@weasel-js/core';
|
|
2
|
-
|
|
3
|
-
// src/strategies/guides.ts
|
|
4
|
-
|
|
5
|
-
// src/strategies/onPlane.ts
|
|
6
|
-
function guideOffsetOn(g, plane) {
|
|
7
|
-
return plane ? g.offset * plane.scale[g.axis] + plane.offset[g.axis] : g.offset;
|
|
8
|
-
}
|
|
9
|
-
function nearestGuideDelta(guides, axis, value, tol, plane) {
|
|
10
|
-
let best = null;
|
|
11
|
-
for (const g of guides) {
|
|
12
|
-
if (g.axis !== axis) continue;
|
|
13
|
-
const d = guideOffsetOn(g, plane) - value;
|
|
14
|
-
if (Math.abs(d) <= tol && (best === null || Math.abs(d) < Math.abs(best))) best = d;
|
|
15
|
-
}
|
|
16
|
-
return best;
|
|
17
|
-
}
|
|
18
|
-
function roundToGridOn(value, axis, spacing, plane) {
|
|
19
|
-
if (!plane) return Math.round(value / spacing) * spacing;
|
|
20
|
-
const camera = (value - plane.offset[axis]) / plane.scale[axis];
|
|
21
|
-
return Math.round(camera / spacing) * spacing * plane.scale[axis] + plane.offset[axis];
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
// src/strategies/guides.ts
|
|
25
|
-
var DEFAULT_GUIDE_TOLERANCE_PX = 6;
|
|
26
|
-
function guideSnapStrategy(getGuides, options = {}) {
|
|
27
|
-
const tolerance = options.tolerance ?? DEFAULT_GUIDE_TOLERANCE_PX;
|
|
28
|
-
const proj = options.origin ?? AUTO_ORIGIN_PROJECTION;
|
|
29
|
-
return {
|
|
30
|
-
snap(pose, ctx) {
|
|
31
|
-
const guides = getGuides();
|
|
32
|
-
if (guides.length === 0) return null;
|
|
33
|
-
const tol = screenTolerance(tolerance, ctx);
|
|
34
|
-
const o = proj.getOrigin(pose);
|
|
35
|
-
const dx = nearestGuideDelta(guides, "x", o.x, tol.x, ctx.plane) ?? 0;
|
|
36
|
-
const dy = nearestGuideDelta(guides, "y", o.y, tol.y, ctx.plane) ?? 0;
|
|
37
|
-
if (dx === 0 && dy === 0) return null;
|
|
38
|
-
return proj.translate(pose, dx, dy);
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export { DEFAULT_GUIDE_TOLERANCE_PX, guideOffsetOn, guideSnapStrategy, nearestGuideDelta, roundToGridOn };
|
|
44
|
-
//# sourceMappingURL=chunk-LOFNN7EQ.js.map
|
|
45
|
-
//# sourceMappingURL=chunk-LOFNN7EQ.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/strategies/onPlane.ts","../src/strategies/guides.ts"],"names":[],"mappings":";;;;;AAQO,SAAS,aAAA,CAAc,GAAU,KAAA,EAAsB;AAC5D,EAAA,OAAO,KAAA,GAAQ,CAAA,CAAE,MAAA,GAAS,KAAA,CAAM,KAAA,CAAM,CAAA,CAAE,IAAI,CAAA,GAAI,KAAA,CAAM,MAAA,CAAO,CAAA,CAAE,IAAI,IAAI,CAAA,CAAE,MAAA;AAC3E;AAGO,SAAS,iBAAA,CACd,MAAA,EACA,IAAA,EACA,KAAA,EACA,KACA,KAAA,EACe;AACf,EAAA,IAAI,IAAA,GAAsB,IAAA;AAC1B,EAAA,KAAA,MAAW,KAAK,MAAA,EAAQ;AACtB,IAAA,IAAI,CAAA,CAAE,SAAS,IAAA,EAAM;AACrB,IAAA,MAAM,CAAA,GAAI,aAAA,CAAc,CAAA,EAAG,KAAK,CAAA,GAAI,KAAA;AACpC,IAAA,IAAI,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,IAAK,QAAQ,IAAA,KAAS,IAAA,IAAQ,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA,GAAI,IAAA,CAAK,GAAA,CAAI,IAAI,IAAI,IAAA,GAAO,CAAA;AAAA,EACpF;AACA,EAAA,OAAO,IAAA;AACT;AAGO,SAAS,aAAA,CAAc,KAAA,EAAe,IAAA,EAAY,OAAA,EAAiB,KAAA,EAAsB;AAC9F,EAAA,IAAI,CAAC,KAAA,EAAO,OAAO,KAAK,KAAA,CAAM,KAAA,GAAQ,OAAO,CAAA,GAAI,OAAA;AACjD,EAAA,MAAM,MAAA,GAAA,CAAU,QAAQ,KAAA,CAAM,MAAA,CAAO,IAAI,CAAA,IAAK,KAAA,CAAM,MAAM,IAAI,CAAA;AAC9D,EAAA,OAAO,IAAA,CAAK,KAAA,CAAM,MAAA,GAAS,OAAO,CAAA,GAAI,OAAA,GAAU,KAAA,CAAM,KAAA,CAAM,IAAI,CAAA,GAAI,KAAA,CAAM,MAAA,CAAO,IAAI,CAAA;AACvF;;;ACxBO,IAAM,0BAAA,GAA6B;AAuCnC,SAAS,iBAAA,CACd,SAAA,EACA,OAAA,GAAmC,EAAC,EACf;AACrB,EAAA,MAAM,SAAA,GAAY,QAAQ,SAAA,IAAa,0BAAA;AACvC,EAAA,MAAM,IAAA,GACJ,QAAQ,MAAA,IAAW,sBAAA;AAErB,EAAA,OAAO;AAAA,IACL,IAAA,CAAK,MAAM,GAAA,EAAK;AACd,MAAA,MAAM,SAAS,SAAA,EAAU;AACzB,MAAA,IAAI,MAAA,CAAO,MAAA,KAAW,CAAA,EAAG,OAAO,IAAA;AAIhC,MAAA,MAAM,GAAA,GAAM,eAAA,CAAgB,SAAA,EAAW,GAAG,CAAA;AAE1C,MAAA,MAAM,CAAA,GAAI,IAAA,CAAK,SAAA,CAAU,IAAI,CAAA;AAC7B,MAAA,MAAM,EAAA,GAAK,iBAAA,CAAkB,MAAA,EAAQ,GAAA,EAAK,CAAA,CAAE,GAAG,GAAA,CAAI,CAAA,EAAG,GAAA,CAAI,KAAK,CAAA,IAAK,CAAA;AACpE,MAAA,MAAM,EAAA,GAAK,iBAAA,CAAkB,MAAA,EAAQ,GAAA,EAAK,CAAA,CAAE,GAAG,GAAA,CAAI,CAAA,EAAG,GAAA,CAAI,KAAK,CAAA,IAAK,CAAA;AACpE,MAAA,IAAI,EAAA,KAAO,CAAA,IAAK,EAAA,KAAO,CAAA,EAAG,OAAO,IAAA;AACjC,MAAA,OAAO,IAAA,CAAK,SAAA,CAAU,IAAA,EAAM,EAAA,EAAI,EAAE,CAAA;AAAA,IACpC;AAAA,GACF;AACF","file":"chunk-LOFNN7EQ.js","sourcesContent":["import type { GestureContext } from '@weasel-js/core';\nimport type { Guide } from '../guides/types';\n\n/** A gesture's `plane`: how the camera's world maps into the world its poses are in. */\ntype Plane = GestureContext<unknown>['plane'];\ntype Axis = 'x' | 'y';\n\n/** Where a guide the camera draws lies along its own axis in the world a gesture's poses are in. */\nexport function guideOffsetOn(g: Guide, plane: Plane): number {\n return plane ? g.offset * plane.scale[g.axis] + plane.offset[g.axis] : g.offset;\n}\n\n/** The signed distance from `value` to the nearest guide on `axis` within `tol`, or null when none is. */\nexport function nearestGuideDelta(\n guides: readonly Guide[],\n axis: Axis,\n value: number,\n tol: number,\n plane: Plane,\n): number | null {\n let best: number | null = null;\n for (const g of guides) {\n if (g.axis !== axis) continue;\n const d = guideOffsetOn(g, plane) - value;\n if (Math.abs(d) <= tol && (best === null || Math.abs(d) < Math.abs(best))) best = d;\n }\n return best;\n}\n\n/** `value` on `axis` moved to the nearest line of the camera's grid, in the world a gesture's poses are in. */\nexport function roundToGridOn(value: number, axis: Axis, spacing: number, plane: Plane): number {\n if (!plane) return Math.round(value / spacing) * spacing;\n const camera = (value - plane.offset[axis]) / plane.scale[axis];\n return Math.round(camera / spacing) * spacing * plane.scale[axis] + plane.offset[axis];\n}\n","import {\n type SnapStrategy,\n screenTolerance,\n type OriginProjection,\n AUTO_ORIGIN_PROJECTION,\n} from '@weasel-js/core';\nimport type { Guide } from '../guides/types';\nimport { nearestGuideDelta } from './onPlane';\n\n/** Default snap tolerance (screen pixels). */\nexport const DEFAULT_GUIDE_TOLERANCE_PX = 6;\n\n/** Options for `guideSnapStrategy`. */\nexport interface GuideSnapOptions<TPose> {\n /**\n * Tolerance in screen pixels, divided by the gesture view's scale so the\n * trigger zone stays the same on screen at every zoom. Defaults to\n * `DEFAULT_GUIDE_TOLERANCE_PX`.\n */\n tolerance?: number;\n /**\n * Projection used when `TPose` doesn't expose `{x, y}` directly (Path,\n * polygon, etc.) — same contract as `gridSnapStrategy`. Defaults to the\n * rect-pose identity projection.\n */\n origin?: OriginProjection<TPose>;\n}\n\n/**\n * Snap-strategy that snaps the pose's origin to the nearest guide line on\n * each axis when within tolerance. Each axis is considered independently:\n * a vertical guide (`axis: 'x'`) constrains X, a horizontal guide\n * (`axis: 'y'`) constrains Y. When multiple guides are within range on the\n * same axis, the closest wins.\n *\n * Pair with `useGuides` for storage and `createGuidesLayer` for rendering.\n * Combining with `gridSnapStrategy` is left to the consumer.\n */\nexport function guideSnapStrategy<TPose extends { x: number; y: number }>(\n getGuides: () => readonly Guide[],\n options?: Omit<GuideSnapOptions<TPose>, 'origin'>,\n): SnapStrategy<TPose>;\n/** As above, for a `TPose` that is not a rect: `origin` tells the strategy how\n * to read and write the pose's origin. */\nexport function guideSnapStrategy<TPose>(\n getGuides: () => readonly Guide[],\n options: GuideSnapOptions<TPose> & { origin: OriginProjection<TPose> },\n): SnapStrategy<TPose>;\n/** Snap a pose's origin to the nearest guide line within tolerance, per axis. */\nexport function guideSnapStrategy<TPose>(\n getGuides: () => readonly Guide[],\n options: GuideSnapOptions<TPose> = {},\n): SnapStrategy<TPose> {\n const tolerance = options.tolerance ?? DEFAULT_GUIDE_TOLERANCE_PX;\n const proj: OriginProjection<TPose> =\n options.origin ?? (AUTO_ORIGIN_PROJECTION as unknown as OriginProjection<TPose>);\n\n return {\n snap(pose, ctx) {\n const guides = getGuides();\n if (guides.length === 0) return null;\n\n // Per axis: a guide on the x axis is matched by a horizontal distance,\n // so it answers to `scale.x` alone.\n const tol = screenTolerance(tolerance, ctx);\n\n const o = proj.getOrigin(pose);\n const dx = nearestGuideDelta(guides, 'x', o.x, tol.x, ctx.plane) ?? 0;\n const dy = nearestGuideDelta(guides, 'y', o.y, tol.y, ctx.plane) ?? 0;\n if (dx === 0 && dy === 0) return null;\n return proj.translate(pose, dx, dy);\n },\n };\n}\n"]}
|
package/dist/chunk-TLFMAZ6M.js
DELETED
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { roundToGridOn } from './chunk-LOFNN7EQ.js';
|
|
2
|
-
import { AUTO_ORIGIN_PROJECTION, resolveAxes } from '@weasel-js/core';
|
|
3
|
-
|
|
4
|
-
function gridSnapStrategy(spacing, arg) {
|
|
5
|
-
const isOpts = typeof arg === "object" && arg !== null && ("origin" in arg || "debug" in arg || "unitSystem" in arg) && !("base" in arg) && !("x" in arg);
|
|
6
|
-
const optsArg = isOpts ? arg : null;
|
|
7
|
-
const unitSystem = optsArg ? optsArg.unitSystem : arg;
|
|
8
|
-
const proj = optsArg && optsArg.origin ? optsArg.origin : AUTO_ORIGIN_PROJECTION;
|
|
9
|
-
const debug = optsArg ? optsArg.debug : void 0;
|
|
10
|
-
const c = resolveAxes(spacing, unitSystem);
|
|
11
|
-
return {
|
|
12
|
-
snap(pose, ctx) {
|
|
13
|
-
const o = proj.getOrigin(pose);
|
|
14
|
-
const sx = roundToGridOn(o.x, "x", c.x, ctx?.plane);
|
|
15
|
-
const sy = roundToGridOn(o.y, "y", c.y, ctx?.plane);
|
|
16
|
-
debug?.recordSnapCandidate({ x: sx, y: sy }, true);
|
|
17
|
-
return proj.translate(pose, sx - o.x, sy - o.y);
|
|
18
|
-
}
|
|
19
|
-
};
|
|
20
|
-
}
|
|
21
|
-
function pointToGridCell(point, spacing, unitSystem, origin = { x: 0, y: 0 }) {
|
|
22
|
-
const s = resolveAxes(spacing, unitSystem);
|
|
23
|
-
return {
|
|
24
|
-
col: Math.floor((point.x - origin.x) / s.x),
|
|
25
|
-
row: Math.floor((point.y - origin.y) / s.y)
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export { gridSnapStrategy, pointToGridCell };
|
|
30
|
-
//# sourceMappingURL=chunk-TLFMAZ6M.js.map
|
|
31
|
-
//# sourceMappingURL=chunk-TLFMAZ6M.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/strategies/grid.ts"],"names":[],"mappings":";;;AAkCO,SAAS,gBAAA,CACd,SACA,GAAA,EACqB;AACrB,EAAA,MAAM,SACJ,OAAO,GAAA,KAAQ,QAAA,IACf,GAAA,KAAQ,SACP,QAAA,IAAY,GAAA,IAAO,OAAA,IAAW,GAAA,IAAO,gBAAgB,GAAA,CAAA,IACtD,EAAE,MAAA,IAAU,GAAA,CAAA,IACZ,EAAE,GAAA,IAAO,GAAA,CAAA;AACX,EAAA,MAAM,OAAA,GAAU,SACX,GAAA,GACD,IAAA;AACJ,EAAA,MAAM,UAAA,GAAa,OAAA,GAAU,OAAA,CAAQ,UAAA,GAAc,GAAA;AACnD,EAAA,MAAM,IAAA,GAAgC,OAAA,IAAW,OAAA,CAAQ,MAAA,GACrD,QAAQ,MAAA,GACP,sBAAA;AACL,EAAA,MAAM,KAAA,GAA+B,OAAA,GAAU,OAAA,CAAQ,KAAA,GAAQ,MAAA;AAC/D,EAAA,MAAM,CAAA,GAAI,WAAA,CAAY,OAAA,EAAS,UAAU,CAAA;AACzC,EAAA,OAAO;AAAA,IACL,IAAA,CAAK,MAAM,GAAA,EAAK;AACd,MAAA,MAAM,CAAA,GAAI,IAAA,CAAK,SAAA,CAAU,IAAI,CAAA;AAC7B,MAAA,MAAM,EAAA,GAAK,cAAc,CAAA,CAAE,CAAA,EAAG,KAAK,CAAA,CAAE,CAAA,EAAG,KAAK,KAAK,CAAA;AAClD,MAAA,MAAM,EAAA,GAAK,cAAc,CAAA,CAAE,CAAA,EAAG,KAAK,CAAA,CAAE,CAAA,EAAG,KAAK,KAAK,CAAA;AAClD,MAAA,KAAA,EAAO,oBAAoB,EAAE,CAAA,EAAG,IAAI,CAAA,EAAG,EAAA,IAAM,IAAI,CAAA;AACjD,MAAA,OAAO,IAAA,CAAK,UAAU,IAAA,EAAM,EAAA,GAAK,EAAE,CAAA,EAAG,EAAA,GAAK,EAAE,CAAC,CAAA;AAAA,IAChD;AAAA,GACF;AACF;AAOO,SAAS,eAAA,CACd,KAAA,EACA,OAAA,EACA,UAAA,EACA,MAAA,GAAmC,EAAE,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAE,EAClB;AAC9B,EAAA,MAAM,CAAA,GAAI,WAAA,CAAY,OAAA,EAAS,UAAU,CAAA;AACzC,EAAA,OAAO;AAAA,IACL,GAAA,EAAK,KAAK,KAAA,CAAA,CAAO,KAAA,CAAM,IAAI,MAAA,CAAO,CAAA,IAAK,EAAE,CAAC,CAAA;AAAA,IAC1C,GAAA,EAAK,KAAK,KAAA,CAAA,CAAO,KAAA,CAAM,IAAI,MAAA,CAAO,CAAA,IAAK,EAAE,CAAC;AAAA,GAC5C;AACF","file":"chunk-TLFMAZ6M.js","sourcesContent":["import {\n AUTO_ORIGIN_PROJECTION,\n resolveAxes,\n type DebugSink,\n type OriginProjection,\n type SnapStrategy,\n type PlaneUnits,\n type PlaneValue,\n} from '@weasel-js/core';\nimport { roundToGridOn } from './onPlane';\n\n/** Snap-strategy that rounds the pose's origin to the nearest multiple of\n * `spacing` (resolved through `unitSystem`). Either may be per axis —\n * `{ x, y }` — for a grid whose axes have different pitches or units. For\n * non-rect TPose pass an `OriginProjection` so the strategy knows how to\n * read/write the origin. */\nexport function gridSnapStrategy<TPose>(\n spacing: PlaneValue,\n unitSystem?: PlaneUnits,\n): SnapStrategy<TPose>;\n/** As above, additionally reporting each candidate to a debug sink. */\nexport function gridSnapStrategy<TPose>(\n spacing: PlaneValue,\n opts: { unitSystem?: PlaneUnits; debug?: DebugSink },\n): SnapStrategy<TPose>;\n/** As above, for a `TPose` that is not a rect: `origin` tells the strategy how\n * to read and write the pose's origin. */\nexport function gridSnapStrategy<TPose>(\n spacing: PlaneValue,\n opts: { unitSystem?: PlaneUnits; origin: OriginProjection<TPose>; debug?: DebugSink },\n): SnapStrategy<TPose>;\n/** Snap-strategy that rounds the pose's origin to the nearest multiple of\n * `spacing` (resolved through `unitSystem`). For non-rect TPose pass an\n * `OriginProjection` so the strategy knows how to read/write the origin. */\nexport function gridSnapStrategy<TPose>(\n spacing: PlaneValue,\n arg?: PlaneUnits | { unitSystem?: PlaneUnits; origin?: OriginProjection<TPose>; debug?: DebugSink },\n): SnapStrategy<TPose> {\n const isOpts =\n typeof arg === 'object' &&\n arg !== null &&\n ('origin' in arg || 'debug' in arg || 'unitSystem' in arg) &&\n !('base' in arg) &&\n !('x' in arg);\n const optsArg = isOpts\n ? (arg as { unitSystem?: PlaneUnits; origin?: OriginProjection<TPose>; debug?: DebugSink })\n : null;\n const unitSystem = optsArg ? optsArg.unitSystem : (arg as PlaneUnits | undefined);\n const proj: OriginProjection<TPose> = optsArg && optsArg.origin\n ? optsArg.origin\n : (AUTO_ORIGIN_PROJECTION as unknown as OriginProjection<TPose>);\n const debug: DebugSink | undefined = optsArg ? optsArg.debug : undefined;\n const c = resolveAxes(spacing, unitSystem);\n return {\n snap(pose, ctx) {\n const o = proj.getOrigin(pose);\n const sx = roundToGridOn(o.x, 'x', c.x, ctx?.plane);\n const sy = roundToGridOn(o.y, 'y', c.y, ctx?.plane);\n debug?.recordSnapCandidate({ x: sx, y: sy }, true);\n return proj.translate(pose, sx - o.x, sy - o.y);\n },\n };\n}\n\n/**\n * The integer cell `{col, row}` that contains `point`. Pair with\n * `createCellHighlightLayer` (its `getCell` callback) to draw a snap-target\n * preview that uses the same spacing as `gridSnapStrategy`.\n */\nexport function pointToGridCell(\n point: { x: number; y: number },\n spacing: PlaneValue,\n unitSystem?: PlaneUnits,\n origin: { x: number; y: number } = { x: 0, y: 0 },\n): { col: number; row: number } {\n const s = resolveAxes(spacing, unitSystem);\n return {\n col: Math.floor((point.x - origin.x) / s.x),\n row: Math.floor((point.y - origin.y) / s.y),\n };\n}\n"]}
|
package/dist/insert.d.ts
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { ModifierState, InsertBehavior } from '@weasel-js/core';
|
|
2
|
-
import { G as Guide } from './types-DRSPiXfk.js';
|
|
3
|
-
|
|
4
|
-
type ModKey$1 = keyof ModifierState;
|
|
5
|
-
/** Insert behavior that rounds the insertion point to a grid, so a shape
|
|
6
|
-
* drawn freehand lands on grid intersections. Hold `bypassKey` to place
|
|
7
|
-
* freely. */
|
|
8
|
-
declare function snapToGrid<TPose>(args: {
|
|
9
|
-
spacing: number;
|
|
10
|
-
bypassKey?: ModKey$1;
|
|
11
|
-
}): InsertBehavior<TPose>;
|
|
12
|
-
|
|
13
|
-
type ModKey = keyof ModifierState;
|
|
14
|
-
/** Options for the insert-flavored `snapToGuides`. */
|
|
15
|
-
interface SnapToGuidesInsertArgs {
|
|
16
|
-
/** Stable getter into the live guide list (typically from `useGuides`). */
|
|
17
|
-
getGuides: () => readonly Guide[];
|
|
18
|
-
/** Snap tolerance in screen px, read through the gesture's view. */
|
|
19
|
-
tolerance?: number;
|
|
20
|
-
/** Modifier key that bypasses snapping while held. */
|
|
21
|
-
bypassKey?: ModKey;
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* Insert behavior that snaps the start anchor (on gesture start) and the
|
|
25
|
-
* live current point (during drag) to the nearest guide on each axis when
|
|
26
|
-
* within `tolerance`. Pair with `useGuides` and `createGuidesLayer`.
|
|
27
|
-
*/
|
|
28
|
-
declare function snapToGuides<TPose>(args: SnapToGuidesInsertArgs): InsertBehavior<TPose>;
|
|
29
|
-
|
|
30
|
-
export { type SnapToGuidesInsertArgs, snapToGrid, snapToGuides };
|
package/dist/insert.js
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { DEFAULT_GUIDE_TOLERANCE_PX, roundToGridOn, nearestGuideDelta } from './chunk-LOFNN7EQ.js';
|
|
2
|
-
import { screenTolerance } from '@weasel-js/core';
|
|
3
|
-
|
|
4
|
-
// src/behaviors/insert/snapToGrid.ts
|
|
5
|
-
function snapToGrid(args) {
|
|
6
|
-
const { spacing, bypassKey } = args;
|
|
7
|
-
const round = (p, plane) => ({
|
|
8
|
-
x: roundToGridOn(p.x, "x", spacing, plane),
|
|
9
|
-
y: roundToGridOn(p.y, "y", spacing, plane)
|
|
10
|
-
});
|
|
11
|
-
return {
|
|
12
|
-
onStart(ctx) {
|
|
13
|
-
if (bypassKey && ctx.modifiers[bypassKey]) return;
|
|
14
|
-
const id = ctx.draggedIds[0];
|
|
15
|
-
const o = ctx.origin.get(id);
|
|
16
|
-
if (!o) return;
|
|
17
|
-
ctx.origin.set(id, round(o, ctx.plane));
|
|
18
|
-
},
|
|
19
|
-
onMove(ctx, { current }) {
|
|
20
|
-
if (bypassKey && ctx.modifiers[bypassKey]) return;
|
|
21
|
-
return { current: round(current, ctx.plane) };
|
|
22
|
-
}
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
function snapPoint(p, guides, tol, plane) {
|
|
26
|
-
const dx = nearestGuideDelta(guides, "x", p.x, tol.x, plane) ?? 0;
|
|
27
|
-
const dy = nearestGuideDelta(guides, "y", p.y, tol.y, plane) ?? 0;
|
|
28
|
-
if (dx === 0 && dy === 0) return null;
|
|
29
|
-
return { x: p.x + dx, y: p.y + dy };
|
|
30
|
-
}
|
|
31
|
-
function snapToGuides(args) {
|
|
32
|
-
const tolerance = args.tolerance ?? DEFAULT_GUIDE_TOLERANCE_PX;
|
|
33
|
-
const bypassKey = args.bypassKey;
|
|
34
|
-
return {
|
|
35
|
-
onStart(ctx) {
|
|
36
|
-
if (bypassKey && ctx.modifiers[bypassKey]) return;
|
|
37
|
-
const guides = args.getGuides();
|
|
38
|
-
if (guides.length === 0) return;
|
|
39
|
-
const id = ctx.draggedIds[0];
|
|
40
|
-
const o = ctx.origin.get(id);
|
|
41
|
-
if (!o) return;
|
|
42
|
-
const snapped = snapPoint(o, guides, screenTolerance(tolerance, ctx), ctx.plane);
|
|
43
|
-
if (snapped) ctx.origin.set(id, snapped);
|
|
44
|
-
},
|
|
45
|
-
onMove(ctx, { current }) {
|
|
46
|
-
if (bypassKey && ctx.modifiers[bypassKey]) return;
|
|
47
|
-
const guides = args.getGuides();
|
|
48
|
-
if (guides.length === 0) return;
|
|
49
|
-
const snapped = snapPoint(current, guides, screenTolerance(tolerance, ctx), ctx.plane);
|
|
50
|
-
if (!snapped) return;
|
|
51
|
-
return { current: snapped };
|
|
52
|
-
}
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export { snapToGrid, snapToGuides };
|
|
57
|
-
//# sourceMappingURL=insert.js.map
|
|
58
|
-
//# sourceMappingURL=insert.js.map
|
package/dist/insert.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/behaviors/insert/snapToGrid.ts","../src/behaviors/insert/snapToGuides.ts"],"names":[],"mappings":"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","file":"insert.js","sourcesContent":["import type {\n GestureContext,\n InsertBehavior,\n InsertPoint,\n ModifierState,\n} from '@weasel-js/core';\nimport { roundToGridOn } from '../../strategies/onPlane';\n\ntype ModKey = keyof ModifierState;\n\n/** Insert behavior that rounds the insertion point to a grid, so a shape\n * drawn freehand lands on grid intersections. Hold `bypassKey` to place\n * freely. */\nexport function snapToGrid<TPose>(args: {\n spacing: number;\n bypassKey?: ModKey;\n}): InsertBehavior<TPose> {\n const { spacing, bypassKey } = args;\n const round = (p: InsertPoint, plane: GestureContext<unknown>['plane']): InsertPoint => ({\n x: roundToGridOn(p.x, 'x', spacing, plane),\n y: roundToGridOn(p.y, 'y', spacing, plane),\n });\n return {\n onStart(ctx) {\n if (bypassKey && ctx.modifiers[bypassKey]) return;\n const id = ctx.draggedIds[0];\n const o = ctx.origin.get(id) as unknown as InsertPoint | undefined;\n if (!o) return;\n ctx.origin.set(id, round(o, ctx.plane) as unknown as TPose);\n },\n onMove(ctx, { current }) {\n if (bypassKey && ctx.modifiers[bypassKey]) return;\n return { current: round(current, ctx.plane) };\n },\n };\n}\n","import {\n type GestureContext,\n type InsertBehavior,\n type InsertPoint,\n type ModifierState,\n screenTolerance,\n} from '@weasel-js/core';\nimport type { Guide } from '../../guides/types';\nimport { DEFAULT_GUIDE_TOLERANCE_PX } from '../../strategies/guides';\nimport { nearestGuideDelta } from '../../strategies/onPlane';\n\ntype ModKey = keyof ModifierState;\n\n/** Options for the insert-flavored `snapToGuides`. */\nexport interface SnapToGuidesInsertArgs {\n /** Stable getter into the live guide list (typically from `useGuides`). */\n getGuides: () => readonly Guide[];\n /** Snap tolerance in screen px, read through the gesture's view. */\n tolerance?: number;\n /** Modifier key that bypasses snapping while held. */\n bypassKey?: ModKey;\n}\n\nfunction snapPoint(\n p: InsertPoint,\n guides: readonly Guide[],\n tol: { x: number; y: number },\n plane: GestureContext<unknown>['plane'],\n): InsertPoint | null {\n const dx = nearestGuideDelta(guides, 'x', p.x, tol.x, plane) ?? 0;\n const dy = nearestGuideDelta(guides, 'y', p.y, tol.y, plane) ?? 0;\n if (dx === 0 && dy === 0) return null;\n return { x: p.x + dx, y: p.y + dy };\n}\n\n/**\n * Insert behavior that snaps the start anchor (on gesture start) and the\n * live current point (during drag) to the nearest guide on each axis when\n * within `tolerance`. Pair with `useGuides` and `createGuidesLayer`.\n */\nexport function snapToGuides<TPose>(\n args: SnapToGuidesInsertArgs,\n): InsertBehavior<TPose> {\n const tolerance = args.tolerance ?? DEFAULT_GUIDE_TOLERANCE_PX;\n const bypassKey = args.bypassKey;\n\n return {\n onStart(ctx) {\n if (bypassKey && ctx.modifiers[bypassKey]) return;\n const guides = args.getGuides();\n if (guides.length === 0) return;\n const id = ctx.draggedIds[0];\n const o = ctx.origin.get(id) as unknown as InsertPoint | undefined;\n if (!o) return;\n const snapped = snapPoint(o, guides, screenTolerance(tolerance, ctx), ctx.plane);\n if (snapped) ctx.origin.set(id, snapped as unknown as TPose);\n },\n onMove(ctx, { current }) {\n if (bypassKey && ctx.modifiers[bypassKey]) return;\n const guides = args.getGuides();\n if (guides.length === 0) return;\n const snapped = snapPoint(current, guides, screenTolerance(tolerance, ctx), ctx.plane);\n if (!snapped) return;\n return { current: snapped };\n },\n };\n}\n"]}
|
package/dist/move.d.ts
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { ModifierState, MoveBehavior, OriginProjection } from '@weasel-js/core';
|
|
2
|
-
import { G as Guide } from './types-DRSPiXfk.js';
|
|
3
|
-
|
|
4
|
-
type ModKey$1 = keyof ModifierState;
|
|
5
|
-
/** Move behavior that snaps the dragged pose's origin to a grid. Hold
|
|
6
|
-
* `bypassKey` to drag freely. */
|
|
7
|
-
declare function snapToGrid<TPose extends {
|
|
8
|
-
x: number;
|
|
9
|
-
y: number;
|
|
10
|
-
}>(args: {
|
|
11
|
-
spacing: number;
|
|
12
|
-
bypassKey?: ModKey$1;
|
|
13
|
-
}): MoveBehavior<TPose>;
|
|
14
|
-
|
|
15
|
-
type ModKey = keyof ModifierState;
|
|
16
|
-
/** Options for the move-flavored `snapToGuides`. */
|
|
17
|
-
interface SnapToGuidesMoveArgs<TPose> {
|
|
18
|
-
/** Stable getter into the live guide list (typically from `useGuides`). */
|
|
19
|
-
getGuides: () => readonly Guide[];
|
|
20
|
-
/** Snap tolerance in screen px, read through the gesture's view. */
|
|
21
|
-
tolerance?: number;
|
|
22
|
-
/** Modifier key that bypasses snapping while held. */
|
|
23
|
-
bypassKey?: ModKey;
|
|
24
|
-
/** Origin projection for non-rect TPose (e.g. Path). */
|
|
25
|
-
origin?: OriginProjection<TPose>;
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Move behavior that snaps the dragged pose's origin to the nearest world-space
|
|
29
|
-
* guide line within `tolerance`. Closest-guide-per-axis wins; the two axes are
|
|
30
|
-
* considered independently. Pair with `useGuides` and `createGuidesLayer`.
|
|
31
|
-
*/
|
|
32
|
-
declare function snapToGuides<TPose extends {
|
|
33
|
-
x: number;
|
|
34
|
-
y: number;
|
|
35
|
-
}>(args: Omit<SnapToGuidesMoveArgs<TPose>, 'origin'>): MoveBehavior<TPose>;
|
|
36
|
-
/** As above, for a `TPose` that is not a rect: `origin` tells the behavior how
|
|
37
|
-
* to read and write the pose's origin. */
|
|
38
|
-
declare function snapToGuides<TPose>(args: SnapToGuidesMoveArgs<TPose> & {
|
|
39
|
-
origin: OriginProjection<TPose>;
|
|
40
|
-
}): MoveBehavior<TPose>;
|
|
41
|
-
|
|
42
|
-
export { type SnapToGuidesMoveArgs, snapToGrid, snapToGuides };
|
package/dist/move.js
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { gridSnapStrategy } from './chunk-TLFMAZ6M.js';
|
|
2
|
-
import { guideSnapStrategy } from './chunk-LOFNN7EQ.js';
|
|
3
|
-
import { snap } from '@weasel-js/core';
|
|
4
|
-
|
|
5
|
-
function snapToGrid(args) {
|
|
6
|
-
return snap(gridSnapStrategy(args.spacing), { bypassKey: args.bypassKey });
|
|
7
|
-
}
|
|
8
|
-
function snapToGuides(args) {
|
|
9
|
-
const strategy = guideSnapStrategy(args.getGuides, {
|
|
10
|
-
tolerance: args.tolerance,
|
|
11
|
-
origin: args.origin
|
|
12
|
-
});
|
|
13
|
-
return snap(strategy, { bypassKey: args.bypassKey });
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export { snapToGrid, snapToGuides };
|
|
17
|
-
//# sourceMappingURL=move.js.map
|
|
18
|
-
//# sourceMappingURL=move.js.map
|
package/dist/move.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/behaviors/move/snapToGrid.ts","../src/behaviors/move/snapToGuides.ts"],"names":["snap"],"mappings":";;;;AAOO,SAAS,WAAmD,IAAA,EAG3C;AACtB,EAAA,OAAO,IAAA,CAAK,iBAAwB,IAAA,CAAK,OAAO,GAAG,EAAE,SAAA,EAAW,IAAA,CAAK,SAAA,EAAW,CAAA;AAClF;ACyBO,SAAS,aACd,IAAA,EACqB;AACrB,EAAA,MAAM,QAAA,GAAW,iBAAA,CAAyB,IAAA,CAAK,SAAA,EAAW;AAAA,IACxD,WAAW,IAAA,CAAK,SAAA;AAAA,IAChB,QAAQ,IAAA,CAAK;AAAA,GACd,CAAA;AACD,EAAA,OAAOA,KAAK,QAAA,EAAU,EAAE,SAAA,EAAW,IAAA,CAAK,WAAW,CAAA;AACrD","file":"move.js","sourcesContent":["import { type ModifierState, type MoveBehavior, snap } from '@weasel-js/core';\nimport { gridSnapStrategy } from '../../strategies/grid';\n\ntype ModKey = keyof ModifierState;\n\n/** Move behavior that snaps the dragged pose's origin to a grid. Hold\n * `bypassKey` to drag freely. */\nexport function snapToGrid<TPose extends { x: number; y: number }>(args: {\n spacing: number;\n bypassKey?: ModKey;\n}): MoveBehavior<TPose> {\n return snap(gridSnapStrategy<TPose>(args.spacing), { bypassKey: args.bypassKey });\n}\n","import {\n type ModifierState,\n type MoveBehavior,\n type OriginProjection,\n snap,\n} from '@weasel-js/core';\nimport type { Guide } from '../../guides/types';\nimport { guideSnapStrategy } from '../../strategies/guides';\n\ntype ModKey = keyof ModifierState;\n\n/** Options for the move-flavored `snapToGuides`. */\nexport interface SnapToGuidesMoveArgs<TPose> {\n /** Stable getter into the live guide list (typically from `useGuides`). */\n getGuides: () => readonly Guide[];\n /** Snap tolerance in screen px, read through the gesture's view. */\n tolerance?: number;\n /** Modifier key that bypasses snapping while held. */\n bypassKey?: ModKey;\n /** Origin projection for non-rect TPose (e.g. Path). */\n origin?: OriginProjection<TPose>;\n}\n\n/**\n * Move behavior that snaps the dragged pose's origin to the nearest world-space\n * guide line within `tolerance`. Closest-guide-per-axis wins; the two axes are\n * considered independently. Pair with `useGuides` and `createGuidesLayer`.\n */\nexport function snapToGuides<TPose extends { x: number; y: number }>(\n args: Omit<SnapToGuidesMoveArgs<TPose>, 'origin'>,\n): MoveBehavior<TPose>;\n/** As above, for a `TPose` that is not a rect: `origin` tells the behavior how\n * to read and write the pose's origin. */\nexport function snapToGuides<TPose>(\n args: SnapToGuidesMoveArgs<TPose> & { origin: OriginProjection<TPose> },\n): MoveBehavior<TPose>;\n/** Snap the dragged pose's origin to the nearest guide line, per axis. */\nexport function snapToGuides<TPose>(\n args: SnapToGuidesMoveArgs<TPose>,\n): MoveBehavior<TPose> {\n const strategy = guideSnapStrategy<TPose>(args.getGuides, {\n tolerance: args.tolerance,\n origin: args.origin as OriginProjection<TPose>,\n });\n return snap(strategy, { bypassKey: args.bypassKey });\n}\n"]}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { Bounds, PointSnapFrame, ModifierState, PointSnapBehavior } from '@weasel-js/core';
|
|
2
|
-
|
|
3
|
-
/** Resize behavior that snaps one reference point of the resize — the dragged
|
|
4
|
-
* corner, the fixed corner, or the center, per `frame` — to a grid, moving
|
|
5
|
-
* the whole pose by the same delta. Unlike the bounds-level `snapToGrid`,
|
|
6
|
-
* this preserves the node's dimensions. */
|
|
7
|
-
declare function pointSnapToGrid<TPose extends Bounds>(args: {
|
|
8
|
-
spacing: number;
|
|
9
|
-
frame?: PointSnapFrame;
|
|
10
|
-
bypassKey?: keyof ModifierState;
|
|
11
|
-
}): PointSnapBehavior<TPose>;
|
|
12
|
-
|
|
13
|
-
export { pointSnapToGrid as p };
|
package/dist/resize.d.ts
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { Bounds, ModifierState, BoundsConstraint } from '@weasel-js/core';
|
|
2
|
-
import { G as Guide } from './types-DRSPiXfk.js';
|
|
3
|
-
export { p as pointSnapToGrid } from './pointSnapToGrid-BaVEjV23.js';
|
|
4
|
-
|
|
5
|
-
type ModKey$1 = keyof ModifierState;
|
|
6
|
-
/** Resize constraint that snaps the moving edges to a grid, leaving the
|
|
7
|
-
* anchored ones where they are. By default a node already smaller than one
|
|
8
|
-
* grid cell on an axis is left unsnapped on that axis, so it stays resizable
|
|
9
|
-
* at sub-grid sizes. */
|
|
10
|
-
declare function snapToGrid<TPose extends Bounds>(args: {
|
|
11
|
-
spacing: number;
|
|
12
|
-
bypassKey?: ModKey$1;
|
|
13
|
-
suspendBelowDim?: boolean;
|
|
14
|
-
}): BoundsConstraint<TPose>;
|
|
15
|
-
|
|
16
|
-
type ModKey = keyof ModifierState;
|
|
17
|
-
/** Options for the resize-flavored `snapToGuides`. */
|
|
18
|
-
interface SnapToGuidesResizeArgs {
|
|
19
|
-
/** Stable getter into the live guide list (typically from `useGuides`). */
|
|
20
|
-
getGuides: () => readonly Guide[];
|
|
21
|
-
/** Snap tolerance in screen px, read through the gesture's view. */
|
|
22
|
-
tolerance?: number;
|
|
23
|
-
/** Modifier key that bypasses snapping while held. */
|
|
24
|
-
bypassKey?: ModKey;
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* Resize behavior that snaps the active edge of the dragged rect to the
|
|
28
|
-
* nearest guide on the corresponding axis when within `tolerance`. The
|
|
29
|
-
* "free" axis is left untouched. The fixed (anchor) edge stays pinned;
|
|
30
|
-
* only the moving edge snaps.
|
|
31
|
-
*
|
|
32
|
-
* On the X axis, vertical guides (`axis: 'x'`) constrain the moving vertical
|
|
33
|
-
* edge — east when `anchor.x === 'min'` (west pinned), west when `'max'`.
|
|
34
|
-
* Likewise on Y for horizontal guides.
|
|
35
|
-
*/
|
|
36
|
-
declare function snapToGuides<TPose extends Bounds>(args: SnapToGuidesResizeArgs): BoundsConstraint<TPose>;
|
|
37
|
-
|
|
38
|
-
export { type SnapToGuidesResizeArgs, snapToGrid, snapToGuides };
|
package/dist/resize.js
DELETED
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
export { pointSnapToGrid } from './chunk-B25KFI3I.js';
|
|
2
|
-
import { DEFAULT_GUIDE_TOLERANCE_PX, nearestGuideDelta, roundToGridOn } from './chunk-LOFNN7EQ.js';
|
|
3
|
-
import { screenTolerance } from '@weasel-js/core';
|
|
4
|
-
|
|
5
|
-
// src/behaviors/resize/snapToGrid.ts
|
|
6
|
-
function snapToGrid(args) {
|
|
7
|
-
const { spacing, bypassKey, suspendBelowDim = true } = args;
|
|
8
|
-
return {
|
|
9
|
-
onMove(ctx, { pose, anchor }) {
|
|
10
|
-
if (bypassKey && ctx.modifiers[bypassKey]) return;
|
|
11
|
-
const round = (v, axis) => roundToGridOn(v, axis, spacing, ctx.plane);
|
|
12
|
-
const origin = ctx.origin.get(ctx.draggedIds[0]);
|
|
13
|
-
const subX = suspendBelowDim && origin.width < spacing;
|
|
14
|
-
const subY = suspendBelowDim && origin.height < spacing;
|
|
15
|
-
let { x, y, width, height } = pose;
|
|
16
|
-
let changed = false;
|
|
17
|
-
if (anchor.x !== "free" && !subX) {
|
|
18
|
-
if (anchor.x === "min") {
|
|
19
|
-
const east = round(x + width, "x");
|
|
20
|
-
width = east - x;
|
|
21
|
-
} else {
|
|
22
|
-
const right = origin.x + origin.width;
|
|
23
|
-
const newX = round(x, "x");
|
|
24
|
-
width = right - newX;
|
|
25
|
-
x = newX;
|
|
26
|
-
}
|
|
27
|
-
changed = true;
|
|
28
|
-
}
|
|
29
|
-
if (anchor.y !== "free" && !subY) {
|
|
30
|
-
if (anchor.y === "min") {
|
|
31
|
-
const south = round(y + height, "y");
|
|
32
|
-
height = south - y;
|
|
33
|
-
} else {
|
|
34
|
-
const bottom = origin.y + origin.height;
|
|
35
|
-
const newY = round(y, "y");
|
|
36
|
-
height = bottom - newY;
|
|
37
|
-
y = newY;
|
|
38
|
-
}
|
|
39
|
-
changed = true;
|
|
40
|
-
}
|
|
41
|
-
if (!changed) return;
|
|
42
|
-
return { pose: { ...pose, x, y, width, height } };
|
|
43
|
-
}
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
function snapToGuides(args) {
|
|
47
|
-
const tolerance = args.tolerance ?? DEFAULT_GUIDE_TOLERANCE_PX;
|
|
48
|
-
const bypassKey = args.bypassKey;
|
|
49
|
-
return {
|
|
50
|
-
onMove(ctx, { pose, anchor }) {
|
|
51
|
-
if (bypassKey && ctx.modifiers[bypassKey]) return;
|
|
52
|
-
const guides = args.getGuides();
|
|
53
|
-
if (guides.length === 0) return;
|
|
54
|
-
const tol = screenTolerance(tolerance, ctx);
|
|
55
|
-
let { x, y, width, height } = pose;
|
|
56
|
-
let changed = false;
|
|
57
|
-
if (anchor.x !== "free") {
|
|
58
|
-
const bestD = nearestGuideDelta(guides, "x", anchor.x === "min" ? x + width : x, tol.x, ctx.plane);
|
|
59
|
-
if (bestD !== null && bestD !== 0) {
|
|
60
|
-
if (anchor.x === "min") {
|
|
61
|
-
width = width + bestD;
|
|
62
|
-
} else {
|
|
63
|
-
x = x + bestD;
|
|
64
|
-
width = width - bestD;
|
|
65
|
-
}
|
|
66
|
-
changed = true;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
if (anchor.y !== "free") {
|
|
70
|
-
const bestD = nearestGuideDelta(guides, "y", anchor.y === "min" ? y + height : y, tol.y, ctx.plane);
|
|
71
|
-
if (bestD !== null && bestD !== 0) {
|
|
72
|
-
if (anchor.y === "min") {
|
|
73
|
-
height = height + bestD;
|
|
74
|
-
} else {
|
|
75
|
-
y = y + bestD;
|
|
76
|
-
height = height - bestD;
|
|
77
|
-
}
|
|
78
|
-
changed = true;
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
if (!changed) return;
|
|
82
|
-
return { pose: { ...pose, x, y, width, height } };
|
|
83
|
-
}
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
export { snapToGrid, snapToGuides };
|
|
88
|
-
//# sourceMappingURL=resize.js.map
|
|
89
|
-
//# sourceMappingURL=resize.js.map
|
package/dist/resize.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/behaviors/resize/snapToGrid.ts","../src/behaviors/resize/snapToGuides.ts"],"names":[],"mappings":"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","file":"resize.js","sourcesContent":["import type { ModifierState, BoundsConstraint, Bounds } from '@weasel-js/core';\nimport { roundToGridOn } from '../../strategies/onPlane';\n\ntype ModKey = keyof ModifierState;\n\n/** Resize constraint that snaps the moving edges to a grid, leaving the\n * anchored ones where they are. By default a node already smaller than one\n * grid cell on an axis is left unsnapped on that axis, so it stays resizable\n * at sub-grid sizes. */\nexport function snapToGrid<TPose extends Bounds>(args: {\n spacing: number;\n bypassKey?: ModKey;\n suspendBelowDim?: boolean;\n}): BoundsConstraint<TPose> {\n const { spacing, bypassKey, suspendBelowDim = true } = args;\n\n return {\n onMove(ctx, { pose, anchor }) {\n if (bypassKey && ctx.modifiers[bypassKey]) return;\n const round = (v: number, axis: 'x' | 'y') => roundToGridOn(v, axis, spacing, ctx.plane);\n const origin = ctx.origin.get(ctx.draggedIds[0])!;\n const subX = suspendBelowDim && origin.width < spacing;\n const subY = suspendBelowDim && origin.height < spacing;\n\n let { x, y, width, height } = pose;\n let changed = false;\n\n if (anchor.x !== 'free' && !subX) {\n if (anchor.x === 'min') {\n // East edge moves; west (x) stays.\n const east = round(x + width, 'x');\n width = east - x;\n } else {\n // West edge moves; east (x+width) stays.\n const right = origin.x + origin.width;\n const newX = round(x, 'x');\n width = right - newX;\n x = newX;\n }\n changed = true;\n }\n if (anchor.y !== 'free' && !subY) {\n if (anchor.y === 'min') {\n const south = round(y + height, 'y');\n height = south - y;\n } else {\n const bottom = origin.y + origin.height;\n const newY = round(y, 'y');\n height = bottom - newY;\n y = newY;\n }\n changed = true;\n }\n if (!changed) return;\n return { pose: { ...pose, x, y, width, height } };\n },\n };\n}\n","import {\n type ModifierState,\n type BoundsConstraint,\n screenTolerance,\n type Bounds,\n} from '@weasel-js/core';\nimport type { Guide } from '../../guides/types';\nimport { DEFAULT_GUIDE_TOLERANCE_PX } from '../../strategies/guides';\nimport { nearestGuideDelta } from '../../strategies/onPlane';\n\ntype ModKey = keyof ModifierState;\n\n/** Options for the resize-flavored `snapToGuides`. */\nexport interface SnapToGuidesResizeArgs {\n /** Stable getter into the live guide list (typically from `useGuides`). */\n getGuides: () => readonly Guide[];\n /** Snap tolerance in screen px, read through the gesture's view. */\n tolerance?: number;\n /** Modifier key that bypasses snapping while held. */\n bypassKey?: ModKey;\n}\n\n/**\n * Resize behavior that snaps the active edge of the dragged rect to the\n * nearest guide on the corresponding axis when within `tolerance`. The\n * \"free\" axis is left untouched. The fixed (anchor) edge stays pinned;\n * only the moving edge snaps.\n *\n * On the X axis, vertical guides (`axis: 'x'`) constrain the moving vertical\n * edge — east when `anchor.x === 'min'` (west pinned), west when `'max'`.\n * Likewise on Y for horizontal guides.\n */\nexport function snapToGuides<TPose extends Bounds>(\n args: SnapToGuidesResizeArgs,\n): BoundsConstraint<TPose> {\n const tolerance = args.tolerance ?? DEFAULT_GUIDE_TOLERANCE_PX;\n const bypassKey = args.bypassKey;\n\n return {\n onMove(ctx, { pose, anchor }) {\n if (bypassKey && ctx.modifiers[bypassKey]) return;\n const guides = args.getGuides();\n if (guides.length === 0) return;\n\n // Per axis: a vertical guide is matched by a horizontal distance, so it\n // answers to `scale.x` alone.\n const tol = screenTolerance(tolerance, ctx);\n\n let { x, y, width, height } = pose;\n let changed = false;\n\n // X-axis: snap the moving vertical edge to the nearest 'x' guide.\n if (anchor.x !== 'free') {\n const bestD = nearestGuideDelta(guides, 'x', anchor.x === 'min' ? x + width : x, tol.x, ctx.plane);\n if (bestD !== null && bestD !== 0) {\n if (anchor.x === 'min') {\n // East edge moves; west (x) stays.\n width = width + bestD;\n } else {\n // West edge moves; east (x+width) stays.\n x = x + bestD;\n width = width - bestD;\n }\n changed = true;\n }\n }\n\n // Y-axis: snap the moving horizontal edge to the nearest 'y' guide.\n if (anchor.y !== 'free') {\n const bestD = nearestGuideDelta(guides, 'y', anchor.y === 'min' ? y + height : y, tol.y, ctx.plane);\n if (bestD !== null && bestD !== 0) {\n if (anchor.y === 'min') {\n height = height + bestD;\n } else {\n y = y + bestD;\n height = height - bestD;\n }\n changed = true;\n }\n }\n\n if (!changed) return;\n return { pose: { ...pose, x, y, width, height } };\n },\n };\n}\n"]}
|
package/dist/types-DRSPiXfk.d.ts
DELETED
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Guide — a horizontal or vertical world-space line used as a snap target
|
|
3
|
-
* and an optional rendered overlay.
|
|
4
|
-
*
|
|
5
|
-
* `axis === 'x'` means a vertical line at world `x = offset` (snaps the X
|
|
6
|
-
* coordinate); `axis === 'y'` means a horizontal line at world `y = offset`
|
|
7
|
-
* (snaps the Y coordinate). This matches "the X axis snaps along X."
|
|
8
|
-
*/
|
|
9
|
-
interface Guide {
|
|
10
|
-
/** Stable, caller-supplied id. Used by removeGuide and as a render key. */
|
|
11
|
-
id: string;
|
|
12
|
-
/** Which world axis this guide constrains. */
|
|
13
|
-
axis: 'x' | 'y';
|
|
14
|
-
/** World-space offset along the constrained axis. */
|
|
15
|
-
offset: number;
|
|
16
|
-
/** The stretch of the line worth drawing, in world units on the other
|
|
17
|
-
* axis: an `'x'` guide's y range. Derived alignment guides carry the
|
|
18
|
-
* extent of the boxes that produced them. Absent, the line has no extent
|
|
19
|
-
* of its own and `createGuidesLayer` draws it across the canvas. */
|
|
20
|
-
span?: {
|
|
21
|
-
min: number;
|
|
22
|
-
max: number;
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* SpacingGap — one measured gap between two boxes, drawn as an equal-spacing
|
|
27
|
-
* marker. `axis === 'x'` is a horizontal gap from world `x = min` to
|
|
28
|
-
* `x = max`, drawn at `y = at`; `axis === 'y'` is the vertical counterpart.
|
|
29
|
-
*/
|
|
30
|
-
interface SpacingGap {
|
|
31
|
-
axis: 'x' | 'y';
|
|
32
|
-
min: number;
|
|
33
|
-
max: number;
|
|
34
|
-
/** World position on the other axis the marker is drawn at. */
|
|
35
|
-
at: number;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export type { Guide as G, SpacingGap as S };
|