@weasel-js/core 1.0.1 → 1.0.3
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/CHANGELOG.md +330 -0
- package/dist/{DrawCommand-DCmiNkBj.d.ts → DrawCommand-BbPrSTra.d.ts} +24 -0
- package/dist/{chunk-Z3KNFTTS.js → chunk-3JYFAQIB.js} +3 -3
- package/dist/chunk-3JYFAQIB.js.map +1 -0
- package/dist/{chunk-UB6A6L77.js → chunk-3KGMJMOS.js} +3 -3
- package/dist/{chunk-UB6A6L77.js.map → chunk-3KGMJMOS.js.map} +1 -1
- package/dist/{chunk-IO5Z75X4.js → chunk-HGF5X6MZ.js} +2 -2
- package/dist/chunk-HGF5X6MZ.js.map +1 -0
- package/dist/{chunk-775XXAHR.js → chunk-JOSUVS6C.js} +2 -2
- package/dist/{chunk-775XXAHR.js.map → chunk-JOSUVS6C.js.map} +1 -1
- package/dist/{chunk-FVNWK7U3.js → chunk-SMCZRSYB.js} +1677 -1371
- package/dist/chunk-SMCZRSYB.js.map +1 -0
- package/dist/{chunk-DCIU3SRK.js → chunk-TR3HZN34.js} +79 -151
- package/dist/chunk-TR3HZN34.js.map +1 -0
- package/dist/{chunk-6SHZHXXR.js → chunk-U45SODC2.js} +2 -2
- package/dist/{chunk-6SHZHXXR.js.map → chunk-U45SODC2.js.map} +1 -1
- package/dist/clipboard.d.ts +5 -2
- package/dist/clipboard.js +1 -2
- package/dist/clone.d.ts +2 -2
- package/dist/clone.js +0 -1
- package/dist/{geometry-DVeZ2i-c.d.ts → geometry-5X6TrAkX.d.ts} +1 -1
- package/dist/{grid-XcFQVS0f.d.ts → grid-sfilv5HP.d.ts} +7 -2
- package/dist/index.d.ts +695 -49
- package/dist/index.js +7 -8
- package/dist/insert.d.ts +6 -3
- package/dist/insert.js +1 -2
- package/dist/insert.js.map +1 -1
- package/dist/move.d.ts +26 -5
- package/dist/move.js +2 -3
- package/dist/move.js.map +1 -1
- package/dist/{options-wAvCnOZd.d.ts → options-CbsIgQci.d.ts} +3 -1
- package/dist/patterns-builtin.d.ts +8 -0
- package/dist/patterns-builtin.js +1 -2
- package/dist/{pointSnapToGrid-BuDZWBrL.d.ts → pointSnapToGrid-C3wowsQy.d.ts} +9 -3
- package/dist/{index-DPI8DV0A.d.ts → registry-CxnkXbG8.d.ts} +225 -350
- package/dist/renderer.d.ts +36 -4
- package/dist/renderer.js +7 -8
- package/dist/resize.d.ts +12 -5
- package/dist/resize.js +2 -3
- package/dist/routing.d.ts +106 -7
- package/dist/routing.js +1 -2
- package/dist/{types-BJ8_cyT7.d.ts → types-BHK2dkMu.d.ts} +43 -1
- package/dist/{types-BhJJ2OCM.d.ts → types-ByZxoD6P.d.ts} +1 -1
- package/dist/{types-B_-khFM0.d.ts → types-DpQ0cWYC.d.ts} +32 -0
- package/dist/{types-Kh_osAq9.d.ts → types-vqxpCFVp.d.ts} +31 -0
- package/dist/{viewToMat3-BvaWCN99.d.ts → viewToMat3-CQW_YqDw.d.ts} +1 -1
- package/package.json +6 -6
- package/dist/chunk-DCIU3SRK.js.map +0 -1
- package/dist/chunk-FVNWK7U3.js.map +0 -1
- package/dist/chunk-IO5Z75X4.js.map +0 -1
- package/dist/chunk-PZ5AY32C.js +0 -9
- package/dist/chunk-PZ5AY32C.js.map +0 -1
- package/dist/chunk-Z3KNFTTS.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/renderer/textures/registerTexture.ts","../src/features/patterns/tileGeometry.ts","../src/features/patterns/index.ts","../src/features/patterns/patterns-builtin.ts"],"names":[],"mappings":";AAmBA,IAAI,OAAA,GAAU,CAAA;AACd,IAAI,QAAA,uBAAe,GAAA,EAA0B;AAQtC,SAAS,WAAW,EAAA,EAAiC;AAC1D,EAAA,OAAO,QAAA,CAAS,GAAA,CAAI,EAAE,CAAA,IAAK,IAAA;AAC7B;AAWO,SAAS,gBACd,KAAA,EACe;AACf,EAAA,MAAM,EAAA,GAAK,CAAA,IAAA,EAAO,EAAE,OAAO,CAAA,CAAA;AAC3B,EAAA,QAAA,CAAS,GAAA,CAAI,EAAA,EAAI,EAAE,MAAA,EAAQ,OAAO,CAAA;AAClC,EAAA,OAAO,EAAE,EAAA,EAAG;AACd;;;ACvBO,SAAS,SAAS,IAAA,EAA+B;AACtD,EAAA,IAAI,IAAA,CAAK,IAAA,KAAS,MAAA,EAAW,OAAO,IAAA,CAAK,IAAA;AACzC,EAAA,QAAQ,KAAK,IAAA;AAAM,IACjB,KAAK,OAAA;AAAS,MAAA,OAAO,CAAA;AAAA,IACrB,KAAK,YAAA;AAAc,MAAA,OAAO,CAAA;AAAA,IAC1B,KAAK,MAAA;AAAQ,MAAA,OAAO,CAAA;AAAA,IACpB,KAAK,QAAA;AAAU,MAAA,OAAO,EAAA;AAAA,IACtB;AAAS,MAAA,OAAO,CAAA;AAAA;AAEpB;AAIA,SAAS,WAAW,IAAA,EAA4B;AAC9C,EAAA,IAAI,IAAI,IAAA,GAAO,CAAA;AACf,EAAA,OAAO,MAAM;AACX,IAAA,CAAA,GAAK,IAAI,UAAA,GAAc,CAAA;AACvB,IAAA,IAAI,IAAI,IAAA,CAAK,IAAA,CAAK,IAAK,CAAA,KAAM,EAAA,EAAK,IAAI,CAAC,CAAA;AACvC,IAAA,CAAA,GAAK,CAAA,GAAI,KAAK,IAAA,CAAK,CAAA,GAAK,MAAM,CAAA,EAAI,EAAA,GAAK,CAAC,CAAA,GAAK,CAAA;AAC7C,IAAA,OAAA,CAAA,CAAS,CAAA,GAAK,CAAA,KAAM,EAAA,MAAS,CAAA,IAAK,UAAA;AAAA,EACpC,CAAA;AACF;AAEO,SAAS,aAAa,IAAA,EAAqC;AAChE,EAAA,MAAM,CAAA,GAAI,SAAS,IAAI,CAAA;AACvB,EAAA,MAAM,EAAE,OAAM,GAAI,IAAA;AAElB,EAAA,QAAQ,KAAK,IAAA;AAAM,IACjB,KAAK,OAAA,EAAS;AACZ,MAAA,MAAM,KAAA,GAAQ,KAAK,SAAA,IAAa,CAAA;AAChC,MAAA,OAAO,EAAE,MAAM,CAAA,EAAG,MAAA,EAAQ,iBAAiB,CAAA,EAAG,KAAA,EAAO,KAAK,CAAA,EAAE;AAAA,IAC9D;AAAA,IACA,KAAK,YAAA,EAAc;AACjB,MAAA,MAAM,KAAA,GAAQ,KAAK,SAAA,IAAa,GAAA;AAChC,MAAA,OAAO;AAAA,QACL,IAAA,EAAM,CAAA;AAAA,QACN,MAAA,EAAQ,CAAC,GAAG,gBAAA,CAAiB,CAAA,EAAG,KAAA,EAAO,KAAK,CAAA,EAAG,GAAG,iBAAA,CAAkB,CAAA,EAAG,KAAA,EAAO,KAAK,CAAC;AAAA,OACtF;AAAA,IACF;AAAA,IACA,KAAK,MAAA,EAAQ;AACX,MAAA,MAAM,CAAA,GAAI,KAAK,MAAA,IAAU,CAAA;AACzB,MAAA,OAAO,EAAE,IAAA,EAAM,CAAA,EAAG,MAAA,EAAQ,CAAC,EAAE,IAAA,EAAM,QAAA,EAAU,EAAA,EAAI,CAAA,GAAI,GAAG,EAAA,EAAI,CAAA,GAAI,GAAG,CAAA,EAAG,KAAA,EAAO,CAAA,EAAE;AAAA,IACjF;AAAA,IACA,KAAK,QAAA,EAAU;AACb,MAAA,MAAM,OAAA,GAAU,KAAK,OAAA,IAAW,IAAA;AAChC,MAAA,MAAM,SAAA,GAAY,KAAK,SAAA,IAAa,CAAA;AACpC,MAAA,MAAM,IAAA,GAAO,UAAA,CAAW,IAAA,CAAK,IAAA,IAAQ,EAAE,CAAA;AACvC,MAAA,MAAM,QAAQ,IAAA,CAAK,KAAA,CAAO,IAAI,CAAA,GAAI,OAAA,IAAY,YAAY,SAAA,CAAU,CAAA;AACpE,MAAA,MAAM,SAAsB,EAAC;AAC7B,MAAA,IAAI,IAAA,CAAK,OAAO,MAAA,EAAW;AACzB,QAAA,MAAA,CAAO,IAAA,CAAK,EAAE,IAAA,EAAM,MAAA,EAAQ,GAAG,CAAA,EAAG,CAAA,EAAG,CAAA,EAAG,KAAA,EAAO,GAAG,MAAA,EAAQ,CAAA,EAAG,KAAA,EAAO,IAAA,CAAK,IAAI,CAAA;AAAA,MAC/E;AACA,MAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,KAAA,EAAO,CAAA,EAAA,EAAK;AAC9B,QAAA,MAAM,EAAA,GAAK,MAAK,GAAI,CAAA;AACpB,QAAA,MAAM,EAAA,GAAK,MAAK,GAAI,CAAA;AACpB,QAAA,MAAM,CAAA,GAAI,SAAA,IAAa,GAAA,GAAM,IAAA,EAAK,CAAA;AAClC,QAAA,MAAM,CAAA,GAAI,SAAA,IAAa,GAAA,GAAM,IAAA,EAAK,CAAA;AAClC,QAAA,MAAM,QAAA,GAAW,IAAA,EAAK,GAAI,IAAA,CAAK,EAAA;AAC/B,QAAA,MAAA,CAAO,IAAA,CAAK,EAAE,IAAA,EAAM,SAAA,EAAW,IAAI,EAAA,EAAI,EAAA,EAAI,CAAA,GAAI,CAAA,EAAG,EAAA,EAAI,CAAA,GAAI,CAAA,EAAG,QAAA,EAAU,OAAO,CAAA;AAAA,MAChF;AACA,MAAA,OAAO,EAAE,IAAA,EAAM,CAAA,EAAG,MAAA,EAAO;AAAA,IAC3B;AAAA,IACA;AACE,MAAA,OAAO,EAAE,IAAA,EAAM,CAAA,EAAG,MAAA,EAAQ,EAAC,EAAE;AAAA;AAEnC;AAIA,SAAS,gBAAA,CAAiB,CAAA,EAAW,KAAA,EAAe,KAAA,EAA4B;AAC9E,EAAA,OAAO;AAAA,IACL,EAAE,IAAA,EAAM,MAAA,EAAQ,EAAA,EAAI,IAAI,EAAA,EAAI,CAAA,GAAI,CAAA,EAAG,EAAA,EAAI,CAAA,GAAI,CAAA,EAAG,EAAA,EAAI,EAAA,EAAI,OAAO,KAAA,EAAM;AAAA,IACnE,EAAE,IAAA,EAAM,MAAA,EAAQ,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,CAAA,EAAG,EAAA,EAAI,CAAA,EAAG,EAAA,EAAI,EAAA,EAAI,KAAA,EAAO,KAAA,EAAM;AAAA,IAC3D,EAAE,IAAA,EAAM,MAAA,EAAQ,EAAA,EAAI,CAAA,GAAI,GAAG,EAAA,EAAI,CAAA,GAAI,CAAA,EAAG,EAAA,EAAI,IAAI,CAAA,EAAG,EAAA,EAAI,CAAA,GAAI,CAAA,EAAG,OAAO,KAAA;AAAM,GAC3E;AACF;AAGA,SAAS,iBAAA,CAAkB,CAAA,EAAW,KAAA,EAAe,KAAA,EAA4B;AAC/E,EAAA,OAAO;AAAA,IACL,EAAE,IAAA,EAAM,MAAA,EAAQ,EAAA,EAAI,IAAI,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,CAAA,GAAI,CAAA,EAAG,EAAA,EAAI,CAAA,GAAI,CAAA,EAAG,OAAO,KAAA,EAAM;AAAA,IACnE,EAAE,IAAA,EAAM,MAAA,EAAQ,EAAA,EAAI,IAAI,CAAA,EAAG,EAAA,EAAI,EAAA,EAAI,EAAA,EAAI,CAAA,GAAI,CAAA,EAAG,EAAA,EAAI,CAAA,EAAG,OAAO,KAAA,EAAM;AAAA,IAClE,EAAE,IAAA,EAAM,MAAA,EAAQ,EAAA,EAAI,IAAI,EAAA,EAAI,CAAA,GAAI,CAAA,EAAG,EAAA,EAAI,CAAA,EAAG,EAAA,EAAI,CAAA,GAAI,CAAA,EAAG,OAAO,KAAA;AAAM,GACpE;AACF;AAGO,SAAS,cAAA,CAAe,IAA8B,QAAA,EAA8B;AACzF,EAAA,KAAA,MAAW,KAAA,IAAS,SAAS,MAAA,EAAQ;AACnC,IAAA,IAAI,KAAA,CAAM,SAAS,MAAA,EAAQ;AACzB,MAAA,EAAA,CAAG,cAAc,KAAA,CAAM,KAAA;AACvB,MAAA,EAAA,CAAG,YAAY,KAAA,CAAM,KAAA;AACrB,MAAA,EAAA,CAAG,SAAA,EAAU;AACb,MAAA,EAAA,CAAG,MAAA,CAAO,KAAA,CAAM,EAAA,EAAI,KAAA,CAAM,EAAE,CAAA;AAC5B,MAAA,EAAA,CAAG,MAAA,CAAO,KAAA,CAAM,EAAA,EAAI,KAAA,CAAM,EAAE,CAAA;AAC5B,MAAA,EAAA,CAAG,MAAA,EAAO;AACV,MAAA;AAAA,IACF;AACA,IAAA,EAAA,CAAG,YAAY,KAAA,CAAM,KAAA;AACrB,IAAA,IAAI,KAAA,CAAM,SAAS,MAAA,EAAQ;AACzB,MAAA,EAAA,CAAG,QAAA,CAAS,MAAM,CAAA,EAAG,KAAA,CAAM,GAAG,KAAA,CAAM,KAAA,EAAO,MAAM,MAAM,CAAA;AACvD,MAAA;AAAA,IACF;AACA,IAAA,EAAA,CAAG,SAAA,EAAU;AACb,IAAA,IAAI,KAAA,CAAM,SAAS,QAAA,EAAU;AAC3B,MAAA,EAAA,CAAG,GAAA,CAAI,KAAA,CAAM,EAAA,EAAI,KAAA,CAAM,EAAA,EAAI,MAAM,CAAA,EAAG,CAAA,EAAG,IAAA,CAAK,EAAA,GAAK,CAAC,CAAA;AAAA,IACpD,CAAA,MAAO;AACL,MAAA,EAAA,CAAG,OAAA,CAAQ,KAAA,CAAM,EAAA,EAAI,KAAA,CAAM,IAAI,KAAA,CAAM,EAAA,EAAI,KAAA,CAAM,EAAA,EAAI,KAAA,CAAM,QAAA,EAAU,CAAA,EAAG,IAAA,CAAK,KAAK,CAAC,CAAA;AAAA,IACnF;AACA,IAAA,EAAA,CAAG,IAAA,EAAK;AAAA,EACV;AACF;;;ACvGO,SAAS,kBAAkB,IAAA,EAA6C;AAG7E,EAAA,IAAI,GAAA;AACJ,EAAA,IAAI;AACF,IAAA,GAAA,GAAM,IAAI,eAAA,CAAgB,IAAA,CAAK,IAAA,EAAM,KAAK,IAAI,CAAA;AAAA,EAChD,CAAA,CAAA,MAAQ;AACN,IAAA,IAAI,OAAO,QAAA,KAAa,WAAA,EAAa,OAAO,IAAA;AAC5C,IAAA,MAAM,CAAA,GAAI,QAAA,CAAS,aAAA,CAAc,QAAQ,CAAA;AACzC,IAAA,CAAA,CAAE,QAAQ,IAAA,CAAK,IAAA;AACf,IAAA,CAAA,CAAE,SAAS,IAAA,CAAK,IAAA;AAChB,IAAA,GAAA,GAAM,CAAA;AAAA,EACR;AACA,EAAA,MAAM,EAAA,GAAK,GAAA,CAAI,UAAA,CAAW,IAAI,CAAA;AAC9B,EAAA,IAAI,CAAC,IAAI,OAAO,IAAA;AAChB,EAAA,IAAA,CAAK,IAAA,CAAK,EAAA,EAAI,IAAA,CAAK,IAAI,CAAA;AAMvB,EAAA,IAAI,MAAA;AACJ,EAAA,IAAI,OAAQ,GAAA,CAAwB,qBAAA,KAA0B,UAAA,EAAY;AACxE,IAAA,MAAA,GAAU,IAAwB,qBAAA,EAAsB;AAAA,EAC1D,CAAA,MAAO;AACL,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,OAAO,gBAAgB,MAAM,CAAA;AAC/B;;;AClCA,SAAS,MAAM,IAAA,EAA6C;AAC1D,EAAA,MAAM,QAAA,GAAW,aAAa,IAAI,CAAA;AAClC,EAAA,OAAO,iBAAA,CAAkB;AAAA,IACvB,IAAA,EAAM,SAAS,IAAI,CAAA;AAAA,IACnB,IAAA,EAAM,CAAC,EAAA,KAAO,cAAA,CAAe,IAAI,QAAQ;AAAA,GAC1C,CAAA;AACH;AASO,SAAS,MAAM,MAAA,EAA2C;AAC/D,EAAA,OAAO,MAAM,EAAE,IAAA,EAAM,OAAA,EAAS,GAAG,QAAQ,CAAA;AAC3C;AASO,SAAS,WAAW,MAAA,EAAgD;AACzE,EAAA,OAAO,MAAM,EAAE,IAAA,EAAM,YAAA,EAAc,GAAG,QAAQ,CAAA;AAChD;AASO,SAAS,KAAK,MAAA,EAA0C;AAC7D,EAAA,OAAO,MAAM,EAAE,IAAA,EAAM,MAAA,EAAQ,GAAG,QAAQ,CAAA;AAC1C;AAmBO,SAAS,OAAO,MAAA,EAA4C;AACjE,EAAA,OAAO,MAAM,EAAE,IAAA,EAAM,QAAA,EAAU,GAAG,QAAQ,CAAA;AAC5C","file":"chunk-IO5Z75X4.js","sourcesContent":["/**\n * registerTexture — accepts an image source, assigns an opaque id, stores in\n * a module-level registry. Actual GL upload happens lazily at draw time in\n * drawShader() via GLTextureCache.upload (which is idempotent).\n *\n * Lifecycle: textures live for the renderer's lifetime. No unregister in v1.\n *\n * Convention §9: this registry stores image data only — no per-renderer state.\n * Each WeaselRenderer's GLTextureCache does its own dedup via has(id).\n */\n\nexport interface TextureHandle {\n readonly id: string;\n}\n\nexport interface TextureEntry {\n source: HTMLImageElement | ImageBitmap;\n}\n\nlet counter = 0;\nlet registry = new Map<string, TextureEntry>();\n\n/** @internal Test helper — do not call from product code. */\nexport function _resetTextureRegistryForTests(): void {\n registry = new Map();\n counter = 0;\n}\n\nexport function getTexture(id: string): TextureEntry | null {\n return registry.get(id) ?? null;\n}\n\n/**\n * Register an image for use as a shader texture uniform.\n *\n * Returns a TextureHandle whose `id` can be passed as a ShaderUniform value.\n * The handle is valid for the lifetime of the renderer it will be used with.\n *\n * @param image The image to register. HTMLImageElement must be fully loaded.\n * @returns Opaque TextureHandle.\n */\nexport function registerTexture(\n image: HTMLImageElement | ImageBitmap,\n): TextureHandle {\n const id = `tex_${++counter}`;\n registry.set(id, { source: image });\n return { id };\n}\n","/**\n * The shapes a built-in tile is made of, as data.\n *\n * One description, two renderers: `patterns-builtin` strokes/fills these to\n * an `OffscreenCanvas` to build the GL texture, and `@weasel-js/svg` maps\n * them to `<pattern>` children. Duplicating the tile drawing in the\n * serializer would let the raster and vector forms drift apart silently.\n */\n\nimport type { TilePatternSpec } from '../../core/paint-types';\n\nexport type TileShape =\n | { kind: 'line'; x1: number; y1: number; x2: number; y2: number; width: number; color: string }\n | { kind: 'circle'; cx: number; cy: number; r: number; color: string }\n | { kind: 'ellipse'; cx: number; cy: number; rx: number; ry: number; rotation: number; color: string }\n | { kind: 'rect'; x: number; y: number; width: number; height: number; color: string };\n\n/** A built-in tile's shapes plus the edge length they're drawn within. */\nexport interface TileGeometry {\n size: number;\n shapes: TileShape[];\n}\n\n/** Defaults per tile kind, matching each factory's signature. */\nexport function tileSize(spec: TilePatternSpec): number {\n if (spec.size !== undefined) return spec.size;\n switch (spec.tile) {\n case 'hatch': return 5;\n case 'crosshatch': return 6;\n case 'dots': return 6;\n case 'chunks': return 48;\n default: return 8;\n }\n}\n\n/** Seeded PRNG (mulberry32) — `chunks` places its scatter with this, so the\n * same `seed` yields the same tile in both the raster and vector paths. */\nfunction mulberry32(seed: number): () => number {\n let s = seed | 0;\n return () => {\n s = (s + 0x6D2B79F5) | 0;\n let t = Math.imul(s ^ (s >>> 15), 1 | s);\n t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296;\n };\n}\n\nexport function tileGeometry(spec: TilePatternSpec): TileGeometry {\n const s = tileSize(spec);\n const { color } = spec;\n\n switch (spec.tile) {\n case 'hatch': {\n const width = spec.lineWidth ?? 1;\n return { size: s, shapes: forwardDiagonals(s, width, color) };\n }\n case 'crosshatch': {\n const width = spec.lineWidth ?? 0.8;\n return {\n size: s,\n shapes: [...forwardDiagonals(s, width, color), ...backwardDiagonals(s, width, color)],\n };\n }\n case 'dots': {\n const r = spec.radius ?? 1;\n return { size: s, shapes: [{ kind: 'circle', cx: s / 2, cy: s / 2, r, color }] };\n }\n case 'chunks': {\n const density = spec.density ?? 0.35;\n const chunkSize = spec.chunkSize ?? 3;\n const rand = mulberry32(spec.seed ?? 42);\n const count = Math.round((s * s * density) / (chunkSize * chunkSize));\n const shapes: TileShape[] = [];\n if (spec.bg !== undefined) {\n shapes.push({ kind: 'rect', x: 0, y: 0, width: s, height: s, color: spec.bg });\n }\n for (let i = 0; i < count; i++) {\n const cx = rand() * s;\n const cy = rand() * s;\n const w = chunkSize * (0.5 + rand());\n const h = chunkSize * (0.5 + rand());\n const rotation = rand() * Math.PI;\n shapes.push({ kind: 'ellipse', cx, cy, rx: w / 2, ry: h / 2, rotation, color });\n }\n return { size: s, shapes };\n }\n default:\n return { size: s, shapes: [] };\n }\n}\n\n/** The forward (`/`) diagonal, plus the two corner stubs that make it tile\n * seamlessly across the edges. */\nfunction forwardDiagonals(s: number, width: number, color: string): TileShape[] {\n return [\n { kind: 'line', x1: -1, y1: s + 1, x2: s + 1, y2: -1, width, color },\n { kind: 'line', x1: -1, y1: 1, x2: 1, y2: -1, width, color },\n { kind: 'line', x1: s - 1, y1: s + 1, x2: s + 1, y2: s - 1, width, color },\n ];\n}\n\n/** The backward (`\\`) diagonal and its two stubs. */\nfunction backwardDiagonals(s: number, width: number, color: string): TileShape[] {\n return [\n { kind: 'line', x1: -1, y1: -1, x2: s + 1, y2: s + 1, width, color },\n { kind: 'line', x1: s - 1, y1: -1, x2: s + 1, y2: 1, width, color },\n { kind: 'line', x1: -1, y1: s - 1, x2: 1, y2: s + 1, width, color },\n ];\n}\n\n/** Draw a tile's shapes to a 2D context — the raster half of the pair. */\nexport function drawTileShapes(oc: CanvasRenderingContext2D, geometry: TileGeometry): void {\n for (const shape of geometry.shapes) {\n if (shape.kind === 'line') {\n oc.strokeStyle = shape.color;\n oc.lineWidth = shape.width;\n oc.beginPath();\n oc.moveTo(shape.x1, shape.y1);\n oc.lineTo(shape.x2, shape.y2);\n oc.stroke();\n continue;\n }\n oc.fillStyle = shape.color;\n if (shape.kind === 'rect') {\n oc.fillRect(shape.x, shape.y, shape.width, shape.height);\n continue;\n }\n oc.beginPath();\n if (shape.kind === 'circle') {\n oc.arc(shape.cx, shape.cy, shape.r, 0, Math.PI * 2);\n } else {\n oc.ellipse(shape.cx, shape.cy, shape.rx, shape.ry, shape.rotation, 0, Math.PI * 2);\n }\n oc.fill();\n }\n}\n","/**\n * Tile-pattern primitive — a small helper for building repeating texture\n * tiles from a draw callback. The result plugs into a `FillStyle` of\n * `{ fill: 'pattern', pattern }` (see `../../core/paint-types.ts`).\n *\n * GL-backed: the tile is rendered to an `OffscreenCanvas` (with a 2D fallback\n * to a regular `<canvas>` for environments without `OffscreenCanvas`),\n * converted to an `ImageBitmap`, and registered with `registerTexture()`.\n * The returned `TextureHandle` is what `FillStyle.pattern` accepts.\n *\n * For ready-to-use named patterns (hatch, crosshatch, dots, chunks),\n * see the `@weasel-js/core/patterns-builtin` subpath.\n */\n\nimport { registerTexture } from '../../renderer/textures/registerTexture';\nimport type { TextureHandle } from '../../renderer/textures/registerTexture';\n\n/** Options for `createTilePattern`. */\nexport interface TilePatternOpts {\n /** Edge length (in pixels) of the square offscreen tile. */\n size: number;\n /** FillStyle one tile at integer-pixel coordinates `(0, 0) .. (size, size)`. */\n draw: (oc: CanvasRenderingContext2D, size: number) => void;\n}\n\n/**\n * Render a single tile to an offscreen canvas and register it as a GL\n * texture, returning a `TextureHandle` you can wrap in a `FillStyle` of\n * `{ fill: 'pattern', pattern }`. Returns `null` only when an\n * `OffscreenCanvas`/2D context can't be acquired (very rare; same fallback\n * semantics as the prior `CanvasPattern`-based implementation).\n */\nexport function createTilePattern(opts: TilePatternOpts): TextureHandle | null {\n // Prefer OffscreenCanvas; fall back to <canvas> for environments without it\n // (tests in jsdom may need that fallback — try OffscreenCanvas first).\n let off: OffscreenCanvas | HTMLCanvasElement;\n try {\n off = new OffscreenCanvas(opts.size, opts.size);\n } catch {\n if (typeof document === 'undefined') return null;\n const c = document.createElement('canvas');\n c.width = opts.size;\n c.height = opts.size;\n off = c;\n }\n const oc = off.getContext('2d') as CanvasRenderingContext2D | null;\n if (!oc) return null;\n opts.draw(oc, opts.size);\n\n // Convert to ImageBitmap so registerTexture can store it.\n // OffscreenCanvas.transferToImageBitmap() is the fast path; the\n // synchronous path requires OffscreenCanvas. If we got here without it,\n // the env doesn't support OffscreenCanvas — fail gracefully.\n let bitmap: ImageBitmap;\n if (typeof (off as OffscreenCanvas).transferToImageBitmap === 'function') {\n bitmap = (off as OffscreenCanvas).transferToImageBitmap();\n } else {\n return null;\n }\n return registerTexture(bitmap);\n}\n","/**\n * Built-in pattern factories — generic line/dot/scatter textures. Each\n * returns a `TextureHandle` you can wrap in a `FillStyle` of\n * `{ fill: 'pattern', pattern }` and pass to anything that accepts a `FillStyle`\n * (`FillStyle`-aware layers, path fills, etc.).\n * Imported from a subpath so consumers that ship their own catalog can\n * avoid the bundle cost.\n *\n * All factories require an explicit `color` (and `bg` for `chunks`). No\n * defaults are baked in — the caller's design system is the source of truth\n * for palette decisions.\n *\n * Each is a thin wrapper over `tileGeometry`, which describes the tile as\n * shapes so `@weasel-js/svg` can emit the same tile as a `<pattern>`.\n * Prefer naming a tile in a `TilePatternSpec` over calling these directly —\n * a spec serializes, a `TextureHandle` does not.\n */\n\nexport { tileGeometry, tileSize, drawTileShapes } from './tileGeometry';\nexport type { TileShape, TileGeometry } from './tileGeometry';\n\nimport { createTilePattern } from '.';\nimport { tileGeometry, drawTileShapes, tileSize } from './tileGeometry';\nimport type { TilePatternSpec } from '../../core/paint-types';\nimport type { TextureHandle } from '../../renderer/textures/registerTexture';\n\nfunction build(spec: TilePatternSpec): TextureHandle | null {\n const geometry = tileGeometry(spec);\n return createTilePattern({\n size: tileSize(spec),\n draw: (oc) => drawTileShapes(oc, geometry),\n });\n}\n\n/** Diagonal hatch (forward slash). */\nexport interface HatchParams {\n color: string;\n size?: number;\n lineWidth?: number;\n}\n\nexport function hatch(params: HatchParams): TextureHandle | null {\n return build({ tile: 'hatch', ...params });\n}\n\n/** Diagonal hatch in both directions. */\nexport interface CrosshatchParams {\n color: string;\n size?: number;\n lineWidth?: number;\n}\n\nexport function crosshatch(params: CrosshatchParams): TextureHandle | null {\n return build({ tile: 'crosshatch', ...params });\n}\n\n/** Regular grid of filled dots. */\nexport interface DotsParams {\n color: string;\n size?: number;\n radius?: number;\n}\n\nexport function dots(params: DotsParams): TextureHandle | null {\n return build({ tile: 'dots', ...params });\n}\n\n/**\n * Random scatter of small ellipses on top of a solid background. Driven by a\n * seeded PRNG so the same `seed` produces a deterministic tile.\n *\n * Note: the `bg` field is optional — omit it for a transparent background\n * (the scatter shapes draw directly onto whatever sits beneath the overlay).\n */\nexport interface ChunksParams {\n color: string;\n bg?: string;\n size?: number;\n /** Coverage: `chunks * chunkSize²` per `size²` tile. Range ~[0, 1]. */\n density?: number;\n chunkSize?: number;\n seed?: number;\n}\n\nexport function chunks(params: ChunksParams): TextureHandle | null {\n return build({ tile: 'chunks', ...params });\n}\n"]}
|
package/dist/chunk-PZ5AY32C.js
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
var __defProp = Object.defineProperty;
|
|
2
|
-
var __export = (target, all) => {
|
|
3
|
-
for (var name in all)
|
|
4
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
5
|
-
};
|
|
6
|
-
|
|
7
|
-
export { __export };
|
|
8
|
-
//# sourceMappingURL=chunk-PZ5AY32C.js.map
|
|
9
|
-
//# sourceMappingURL=chunk-PZ5AY32C.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-PZ5AY32C.js"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/interactions/actions/resize/behaviors/clampMinSize.ts","../src/interactions/actions/resize/behaviors/lockAspect.ts","../src/interactions/actions/resize/behaviors/snapToGrid.ts","../src/interactions/actions/resize/behaviors/snapToGuides.ts","../src/interactions/actions/resize/behaviors/pointSnapToGrid.ts","../src/interactions/actions/resize/behaviors/index.ts","../src/interactions/actions/resize/cornerHandles.ts"],"names":[],"mappings":"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","file":"chunk-Z3KNFTTS.js","sourcesContent":["import type { BoundsConstraint, ResizePose } from '../../../gestures/types';\n\nexport function clampMinSize<TPose extends ResizePose>(args: {\n minWidth: number;\n minHeight: number;\n}): BoundsConstraint<TPose> {\n const { minWidth, minHeight } = args;\n return {\n onMove(_ctx, { pose, anchor }) {\n let { x, y, width, height } = pose;\n let changed = false;\n if (anchor.x !== 'free' && width < minWidth) {\n if (anchor.x === 'min') {\n // West edge is anchor; east edge was dragged. Hold x; widen to min.\n width = minWidth;\n } else {\n // East edge is anchor at originalRight = x + width. Hold the right;\n // shift x left so width = minWidth.\n const right = x + width;\n x = right - minWidth;\n width = minWidth;\n }\n changed = true;\n }\n if (anchor.y !== 'free' && height < minHeight) {\n if (anchor.y === 'min') {\n height = minHeight;\n } else {\n const bottom = y + height;\n y = bottom - minHeight;\n height = minHeight;\n }\n changed = true;\n }\n if (!changed) return;\n return { pose: { ...pose, x, y, width, height } };\n },\n };\n}\n","import type {\n ModifierState,\n BoundsConstraint,\n ResizePose,\n} from '../../../gestures/types';\n\ntype ModKey = keyof ModifierState;\n\n/** Aspect-ratio lock: drag a corner/edge with `key` (default `'shift'`) held\n * to keep the resized bounds at the start-pose's `width / height` ratio.\n *\n * Strategy:\n * - Compute the proposed deltas in width and height (signed, relative to\n * origin). Whichever axis has the larger absolute delta \"wins\"; the other\n * is recomputed from `(originW / originH) * winnerDelta`.\n * - The opposite corner/edge stays anchored — for the corner case we infer\n * the anchor from the proposed bounds; for an edge handle we resize the\n * orthogonal axis symmetrically around the dragged edge's anchor (the\n * handle's own line stays put, the orthogonal axis grows/shrinks centered\n * on the un-dragged edge — see notes below).\n * - No-op when the modifier is not held, when the origin has zero width or\n * height (no defined ratio), or when the proposed pose hasn't moved.\n *\n * Edge-handle handling: with `anchor.x !== 'free' && anchor.y === 'free'`\n * (an `e` or `w` handle), only the width was driven by the pointer. We pick\n * the new height as `width / ratio` and pin it to the un-dragged y axis by\n * anchoring at the origin's top edge (`y` stays at `origin.y`). Symmetric\n * for `n` / `s`.\n */\nexport function lockAspectWithModifier<TPose extends ResizePose>(opts: {\n key?: ModKey;\n} = {}): BoundsConstraint<TPose> {\n const { key = 'shift' } = opts;\n\n return {\n onMove(ctx, { pose, anchor }) {\n if (!ctx.modifiers[key]) return;\n const origin = ctx.origin.get(ctx.draggedIds[0]) as ResizePose | undefined;\n if (!origin) return;\n if (origin.width === 0 || origin.height === 0) return;\n const ratio = origin.width / origin.height; // w / h\n\n // Signed deltas relative to origin. Negative deltas mean the user has\n // dragged through the anchor and flipped the rect; we preserve sign on\n // the recomputed axis so the flipped quadrant stays consistent.\n const dw = pose.width - origin.width;\n const dh = pose.height - origin.height;\n\n let nw: number;\n let nh: number;\n\n if (anchor.x === 'free' && anchor.y === 'free') {\n // No driven axis — nothing to lock against.\n return;\n } else if (anchor.x === 'free') {\n // Edge handle: n or s. height is driven; width follows.\n nh = pose.height;\n nw = nh * ratio;\n // sign-preserve width if the original height delta caused a flip.\n // (height-driven only; width direction follows ratio absolutely.)\n if (nw < 0) nw = -nw;\n } else if (anchor.y === 'free') {\n // Edge handle: e or w. width is driven; height follows.\n nw = pose.width;\n nh = nw / ratio;\n if (nh < 0) nh = -nh;\n } else {\n // Corner handle. Pick the dominant axis by absolute delta.\n if (Math.abs(dw) >= Math.abs(dh)) {\n nw = pose.width;\n // Match height sign to width sign so the rect stays in the same\n // quadrant the pointer chose.\n nh = (Math.abs(nw) / ratio) * Math.sign(pose.height || 1);\n } else {\n nh = pose.height;\n nw = (Math.abs(nh) * ratio) * Math.sign(pose.width || 1);\n }\n }\n\n // Recompute x/y from the anchor (the un-dragged edge stays pinned).\n let nx = pose.x;\n let ny = pose.y;\n if (anchor.x === 'min') {\n // West edge anchored at origin.x.\n nx = origin.x;\n } else if (anchor.x === 'max') {\n // East edge anchored at origin.x + origin.width.\n nx = origin.x + origin.width - nw;\n } else {\n // Edge handle (n/s): width grew/shrunk via ratio. Center horizontally\n // about the origin's center so the rect stays visually centered on\n // the dragged edge's midline.\n nx = origin.x + origin.width / 2 - nw / 2;\n }\n if (anchor.y === 'min') {\n ny = origin.y;\n } else if (anchor.y === 'max') {\n ny = origin.y + origin.height - nh;\n } else {\n ny = origin.y + origin.height / 2 - nh / 2;\n }\n\n return {\n pose: { ...pose, x: nx, y: ny, width: nw, height: nh },\n };\n },\n };\n}\n","import type {\n ModifierState,\n BoundsConstraint,\n ResizePose,\n} from '../../../gestures/types';\n\ntype ModKey = keyof ModifierState;\n\nexport function snapToGrid<TPose extends ResizePose>(args: {\n spacing: number;\n bypassKey?: ModKey;\n suspendBelowDim?: boolean;\n}): BoundsConstraint<TPose> {\n const { spacing, bypassKey, suspendBelowDim = true } = args;\n const round = (v: number) => Math.round(v / spacing) * spacing;\n\n return {\n onMove(ctx, { pose, anchor }) {\n if (bypassKey && ctx.modifiers[bypassKey]) return;\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);\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);\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);\n height = south - y;\n } else {\n const bottom = origin.y + origin.height;\n const newY = round(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 type {\n ModifierState,\n BoundsConstraint,\n ResizePose,\n} from '../../../gestures/types';\nimport type { Guide } from 'features/guides/types';\nimport type { View } from 'core/viewport/view';\nimport { pxExtent } from 'core/viewport/pxExtent';\nimport { DEFAULT_GUIDE_TOLERANCE_PX } from '../../../gestures/shared/strategies/guides';\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 (screen px when `getView` is set, world units otherwise). */\n tolerance?: number;\n /** Read the active view; required for screen-pixel tolerance. */\n getView?: () => View;\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 ResizePose>(\n args: SnapToGuidesResizeArgs,\n): BoundsConstraint<TPose> {\n const tolerance = args.tolerance ?? DEFAULT_GUIDE_TOLERANCE_PX;\n const getView = args.getView;\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 = getView ? pxExtent(tolerance, getView().scale) : { x: tolerance, y: tolerance };\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 movingX = anchor.x === 'min' ? x + width : x;\n let bestD = 0;\n let bestAbs = Infinity;\n for (const g of guides) {\n if (g.axis !== 'x') continue;\n const d = g.offset - movingX;\n const ad = Math.abs(d);\n if (ad <= tol.x && ad < bestAbs) {\n bestAbs = ad;\n bestD = d;\n }\n }\n if (bestAbs !== Infinity && 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 movingY = anchor.y === 'min' ? y + height : y;\n let bestD = 0;\n let bestAbs = Infinity;\n for (const g of guides) {\n if (g.axis !== 'y') continue;\n const d = g.offset - movingY;\n const ad = Math.abs(d);\n if (ad <= tol.y && ad < bestAbs) {\n bestAbs = ad;\n bestD = d;\n }\n }\n if (bestAbs !== Infinity && 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","import type {\n ModifierState,\n PointSnapBehavior,\n PointSnapContext,\n PointSnapFrame,\n PointSnapResult,\n ResizePose,\n} from '../../../gestures/types';\n\nexport function pointSnapToGrid<TPose extends ResizePose>(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","export { clampMinSize } from './clampMinSize';\nexport { lockAspectWithModifier } from './lockAspect';\nexport { snapToGrid } from './snapToGrid';\n\nimport type { BoundsConstraint, ResizePose } from '../../../gestures/types';\nimport { lockAspectWithModifier } from './lockAspect';\n\n/** The kit's standard resize behaviors, applied when a consumer doesn't\n * supply its own list: shift-drag locks the start pose's aspect ratio.\n * Pass an explicit `behaviors: []` to opt out. Stateless, so one shared\n * frozen instance is safe across every gesture. */\nexport const DEFAULT_RESIZE_BEHAVIORS: readonly BoundsConstraint<ResizePose>[] =\n Object.freeze([lockAspectWithModifier()]);\nexport { snapToGuides } from './snapToGuides';\nexport { pointSnapToGrid } from './pointSnapToGrid';\n","import type { ResizeAnchor } from '../../gestures/types';\nimport type { Bounds } from 'core/viewport/fitViewToBounds';\n\n/** Corner resize-handle: world-space center plus the anchor that pins the opposite corner during resize. */\nexport interface CornerHandle {\n cx: number;\n cy: number;\n anchor: ResizeAnchor;\n}\n\n/** Which AABB edge a corner sits on, per axis. `'min'` = the x/y origin\n * edge; `'max'` = the origin + extent edge. */\nexport type CornerEdge = 'min' | 'max';\n\n/** One entry of the canonical 4-corner resize layout. The single source of\n * truth for \"which corner maps to which anchor / handle-kind\". */\nexport interface CornerAnchor {\n /** Which x-edge the corner sits on (`'min'` = left, `'max'` = right). */\n xEdge: CornerEdge;\n /** Which y-edge the corner sits on (`'min'` = top, `'max'` = bottom). */\n yEdge: CornerEdge;\n /** Anchor that pins the diagonally-opposite (fixed) corner. Always the\n * axis-wise opposite of `{xEdge, yEdge}`. */\n anchor: ResizeAnchor;\n /** Affordance/handle discriminator string for this corner. */\n kind: string;\n /** Short positional tag (`'<xEdge>-<yEdge>'`), e.g. `'min-max'`. */\n tag: string;\n}\n\n/**\n * The single ordered corner→anchor table. Order is **load-bearing**: every\n * consumer iterates it in this sequence (TL, TR, BL, BR) so positional\n * meaning (the i-th handle / `kind` / `tag`) stays consistent across the\n * resize-handle affordance, the affordance-hit classifier, and\n * `cornerResizeHandles`. Each corner's `anchor` names the diagonally\n * opposite corner, so dragging the corner scales the box from that fixed\n * point.\n */\nexport const CORNER_ANCHORS: readonly CornerAnchor[] = [\n { xEdge: 'min', yEdge: 'min', anchor: { x: 'max', y: 'max' }, kind: 'handle:top-left', tag: 'min-min' },\n { xEdge: 'max', yEdge: 'min', anchor: { x: 'min', y: 'max' }, kind: 'handle:top-right', tag: 'max-min' },\n { xEdge: 'min', yEdge: 'max', anchor: { x: 'max', y: 'min' }, kind: 'handle:bottom-left', tag: 'min-max' },\n { xEdge: 'max', yEdge: 'max', anchor: { x: 'min', y: 'min' }, kind: 'handle:bottom-right', tag: 'max-max' },\n];\n\n/** Resolve a corner's world-space position for the given bounds. `xEdge`\n * `'max'` → `x + width`; `yEdge` `'max'` → `y + height`. */\nexport function cornerPoint(\n bounds: Bounds,\n entry: Pick<CornerAnchor, 'xEdge' | 'yEdge'>,\n): { x: number; y: number } {\n return {\n x: entry.xEdge === 'max' ? bounds.x + bounds.width : bounds.x,\n y: entry.yEdge === 'max' ? bounds.y + bounds.height : bounds.y,\n };\n}\n\n/** Standard 4-corner resize-handle layout: each corner pins the opposite\n * corner via an anchor of `{x: 'min'|'max', y: 'min'|'max'}` so dragging it\n * scales the box from the fixed opposite corner. Decodes {@link CORNER_ANCHORS}\n * against `bounds`. */\nexport function cornerResizeHandles(bounds: Bounds): CornerHandle[] {\n return CORNER_ANCHORS.map((c) => {\n const p = cornerPoint(bounds, c);\n return { cx: p.x, cy: p.y, anchor: c.anchor };\n });\n}\n\n/** Square hit-test for a handle: returns true if `(px, py)` is within\n * `radius` of the handle center on both axes. */\nexport function hitCornerHandle(\n handle: CornerHandle,\n px: number,\n py: number,\n radius: number,\n): boolean {\n return Math.abs(px - handle.cx) <= radius\n && Math.abs(py - handle.cy) <= radius;\n}\n\n/** The corner that does NOT move under a resize gesture with the given\n * anchor. Used by the rotated-resize math to pin a world-space invariant.\n *\n * Convention: `anchor.x === 'min'` means the min-x (left) edge is the\n * fixed anchor, so the fixed corner sits at `x = bounds.x` (min-x).\n * `anchor.x === 'max'` means the max-x (right) edge is fixed, so the\n * fixed corner sits at `x = bounds.x + bounds.width`. `'free'` on an\n * axis means that axis doesn't move; the fixed coord is the bounds\n * origin on that axis. */\nexport function fixedCornerOf(\n bounds: Bounds,\n anchor: ResizeAnchor,\n): { x: number; y: number } {\n return {\n x: anchor.x === 'max' ? bounds.x + bounds.width : bounds.x,\n y: anchor.y === 'max' ? bounds.y + bounds.height : bounds.y,\n };\n}\n"]}
|