@weasel-js/labkit 1.4.0-pre.0 → 1.4.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 +226 -55
- package/dist/_dts/{CanvasStackContext-DtAn_3O-.d.ts → CanvasStackContext-D6M0o8cQ.d.ts} +1 -1
- package/dist/_dts/{frac-Cp3NivlC.d.ts → frac-QS7XzvpG.d.ts} +11 -4
- package/dist/_dts/{index-BDVzvRzQ.d.ts → index-B2X21G1c.d.ts} +8 -2
- package/dist/_dts/{types-D6s4b7if.d.ts → types-C1Zw7s5P.d.ts} +1 -0
- package/dist/_dts/{types-DYMaEvM5.d.ts → types-ChVJJHvk.d.ts} +3 -0
- package/dist/_dts/{useTrialState-gmMvZqPc.d.ts → useTrialState-Cdm13fvl.d.ts} +2 -1
- package/dist/canvas/index.d.ts +75 -9
- package/dist/canvas/index.js +2 -2
- package/dist/chrome/index.d.ts +4 -4
- package/dist/chrome/index.js +5 -5
- package/dist/chunk-2YILQ7Y5.js +33 -0
- package/dist/chunk-2YILQ7Y5.js.map +1 -0
- package/dist/{chunk-3P5TTTA7.js → chunk-4AMN4MMB.js} +5 -5
- package/dist/{chunk-3P5TTTA7.js.map → chunk-4AMN4MMB.js.map} +1 -1
- package/dist/{chunk-ROQDRXKW.js → chunk-7VW3S44V.js} +621 -51
- package/dist/chunk-7VW3S44V.js.map +1 -0
- package/dist/{chunk-4EY67BKJ.js → chunk-B5VWJBWM.js} +12 -6
- package/dist/chunk-B5VWJBWM.js.map +1 -0
- package/dist/{chunk-HEORBLVT.js → chunk-L5WBGUVR.js} +1664 -1628
- package/dist/chunk-L5WBGUVR.js.map +1 -0
- package/dist/{chunk-XJ6N32QP.js → chunk-LJSIUFYD.js} +14 -30
- package/dist/chunk-LJSIUFYD.js.map +1 -0
- package/dist/{chunk-6JMU56CU.js → chunk-QR5V3AFG.js} +6 -4
- package/dist/chunk-QR5V3AFG.js.map +1 -0
- package/dist/{chunk-LITE5YFB.js → chunk-UD7TEHZT.js} +15 -15
- package/dist/chunk-UD7TEHZT.js.map +1 -0
- package/dist/{chunk-3ZELRRBV.js → chunk-VHFQKAUL.js} +86 -6
- package/dist/chunk-VHFQKAUL.js.map +1 -0
- package/dist/{chunk-YQJNT4XQ.js → chunk-W3KSUXXR.js} +16 -13
- package/dist/chunk-W3KSUXXR.js.map +1 -0
- package/dist/{chunk-JDDIZSLL.js → chunk-XCBCZEBO.js} +3 -3
- package/dist/{chunk-JDDIZSLL.js.map → chunk-XCBCZEBO.js.map} +1 -1
- package/dist/{chunk-EQIB2PGC.js → chunk-Y2HK44TG.js} +3 -3
- package/dist/{chunk-EQIB2PGC.js.map → chunk-Y2HK44TG.js.map} +1 -1
- package/dist/{chunk-5TCEVMPI.js → chunk-YQGQUBKA.js} +3 -3
- package/dist/{chunk-5TCEVMPI.js.map → chunk-YQGQUBKA.js.map} +1 -1
- package/dist/controls/index.d.ts +2 -2
- package/dist/controls/index.js +3 -3
- package/dist/dragdrop/index.d.ts +3 -3
- package/dist/dragdrop/index.js +2 -2
- package/dist/index.d.ts +57 -59
- package/dist/index.js +335 -240
- package/dist/index.js.map +1 -1
- package/dist/layers/index.d.ts +4 -4
- package/dist/layers/index.js +3 -3
- package/dist/loupe/index.d.ts +5 -5
- package/dist/loupe/index.js +2 -2
- package/dist/passthrough/weasel-canvas.js +1 -1
- package/dist/passthrough/weasel-ui.d.ts +336 -15
- package/dist/passthrough/weasel-ui.js +2 -2
- package/dist/primitives/index.js +4 -4
- package/dist/state/index.d.ts +3 -3
- package/dist/state/index.js +4 -2
- package/dist/state/index.js.map +1 -1
- package/dist/styles.css +64 -5
- package/dist/surface/index.d.ts +17 -2
- package/dist/surface/index.js +3 -2
- package/dist/ui/layers/index.js +2 -2
- package/dist/undo/index.d.ts +3 -3
- package/package.json +8 -8
- package/src/annotations/AnnotationOverlay.tsx +10 -6
- package/src/annotations/Annotations.less +6 -0
- package/src/annotations/Annotations.overlay.test.tsx +113 -0
- package/src/annotations/MarkList.tsx +3 -2
- package/src/annotations/store.test.ts +72 -0
- package/src/annotations/store.ts +30 -0
- package/src/annotations/types.ts +9 -2
- package/src/canvas/index.ts +11 -0
- package/src/config/builder.test.ts +5 -0
- package/src/config/builder.ts +6 -0
- package/src/config/types.ts +1 -0
- package/src/controls/ControlPanel.test.tsx +23 -0
- package/src/controls/ControlPanel.tsx +3 -0
- package/src/index.test.ts +1 -0
- package/src/index.ts +13 -9
- package/src/lab/Lab.surface.test.tsx +8 -3
- package/src/lab/LabHeader.test.tsx +12 -0
- package/src/lab/LabHeader.tsx +16 -6
- package/src/passthrough/weasel-ui.test.ts +9 -0
- package/src/passthrough/weasel-ui.ts +4 -0
- package/src/primitives/ZoomControl.tsx +2 -0
- package/src/state/store.ts +10 -0
- package/src/state/types.ts +3 -0
- package/src/surface/AGENTS.md +11 -1
- package/src/surface/index.ts +7 -1
- package/src/surface/useSurfaceTile.ts +20 -2
- package/src/surface/useTiledSurface.ts +4 -1
- package/src/theme/Interstellar.stories.tsx +4 -3
- package/src/theme/base.less +39 -1
- package/src/trial/Trial.less +27 -5
- package/src/trial/TrialBody.test.tsx +67 -0
- package/src/trial/TrialBody.tsx +155 -0
- package/src/trial/TrialChrome.tsx +18 -10
- package/src/trial/index.ts +2 -0
- package/dist/chunk-3ZELRRBV.js.map +0 -1
- package/dist/chunk-4EY67BKJ.js.map +0 -1
- package/dist/chunk-6JMU56CU.js.map +0 -1
- package/dist/chunk-HEORBLVT.js.map +0 -1
- package/dist/chunk-LITE5YFB.js.map +0 -1
- package/dist/chunk-ROQDRXKW.js.map +0 -1
- package/dist/chunk-XJ6N32QP.js.map +0 -1
- package/dist/chunk-YQJNT4XQ.js.map +0 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { createContext, createElement, forwardRef, useMemo, useRef, useCallback, useState, useImperativeHandle, useSyncExternalStore,
|
|
1
|
+
import { createContext, createElement, forwardRef, useMemo, useRef, useCallback, useState, useEffect, useImperativeHandle, useSyncExternalStore, useLayoutEffect, useContext, useId, useReducer } from 'react';
|
|
2
2
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
3
3
|
import earcut from 'earcut';
|
|
4
4
|
import polygonClipping from 'polygon-clipping';
|
|
5
5
|
|
|
6
|
-
// ../core/dist/chunk-
|
|
6
|
+
// ../core/dist/chunk-UTIFY2UU.js
|
|
7
7
|
|
|
8
8
|
// ../gestures/dist/index.js
|
|
9
9
|
var GESTURE_DESCRIPTORS = [
|
|
@@ -287,7 +287,7 @@ function matchSpec(e, spec, isMac, phaseCtx) {
|
|
|
287
287
|
}
|
|
288
288
|
var EMPTY_ENGAGED = /* @__PURE__ */ new Set();
|
|
289
289
|
|
|
290
|
-
// ../core/dist/chunk-
|
|
290
|
+
// ../core/dist/chunk-UTIFY2UU.js
|
|
291
291
|
var DepRegistryContext = createContext(null);
|
|
292
292
|
function DepRegistryProvider({ children }) {
|
|
293
293
|
const sourcesRef = useRef(/* @__PURE__ */ new Map());
|
|
@@ -3841,6 +3841,403 @@ function eligibleContribution(reg, entry) {
|
|
|
3841
3841
|
return eligibleForMode(reg.current(), entry.eligibility?.capabilities ?? []);
|
|
3842
3842
|
}
|
|
3843
3843
|
|
|
3844
|
+
// ../cursor/dist/index.js
|
|
3845
|
+
var CURSOR_INK = "#141418";
|
|
3846
|
+
var CURSOR_HALO = "#ffffff";
|
|
3847
|
+
var CURSOR_HALO_WIDTH = 2.6;
|
|
3848
|
+
var CURSOR_ANGLE_STEPS = 16;
|
|
3849
|
+
var CURSOR_MAX_CSS_PX = 128;
|
|
3850
|
+
function halo(p, k) {
|
|
3851
|
+
switch (p.role) {
|
|
3852
|
+
case "ink":
|
|
3853
|
+
case "accent":
|
|
3854
|
+
return { d: p.d, fill: CURSOR_HALO, stroke: { color: CURSOR_HALO, width: CURSOR_HALO_WIDTH * k } };
|
|
3855
|
+
case "stroke":
|
|
3856
|
+
return { d: p.d, stroke: { color: CURSOR_HALO, width: (p.width + CURSOR_HALO_WIDTH) * k } };
|
|
3857
|
+
// A detail IS halo-coloured and sits on top of the ink; it has no halo.
|
|
3858
|
+
case "detail":
|
|
3859
|
+
return null;
|
|
3860
|
+
}
|
|
3861
|
+
}
|
|
3862
|
+
function ink(p, k) {
|
|
3863
|
+
switch (p.role) {
|
|
3864
|
+
case "ink":
|
|
3865
|
+
return { d: p.d, fill: CURSOR_INK };
|
|
3866
|
+
case "stroke":
|
|
3867
|
+
return { d: p.d, stroke: { color: CURSOR_INK, width: p.width * k } };
|
|
3868
|
+
case "detail":
|
|
3869
|
+
return { d: p.d, stroke: { color: CURSOR_HALO, width: p.width * k } };
|
|
3870
|
+
case "accent":
|
|
3871
|
+
return { d: p.d, fill: p.fill };
|
|
3872
|
+
}
|
|
3873
|
+
}
|
|
3874
|
+
function cursorPaintOps(glyph, opts = {}) {
|
|
3875
|
+
const k = opts.lineWidthScale ?? 1;
|
|
3876
|
+
const out = [];
|
|
3877
|
+
for (const p of glyph.paths) {
|
|
3878
|
+
const h = halo(p, k);
|
|
3879
|
+
if (h) out.push(h);
|
|
3880
|
+
}
|
|
3881
|
+
for (const p of glyph.paths) out.push(ink(p, k));
|
|
3882
|
+
return out;
|
|
3883
|
+
}
|
|
3884
|
+
function cursorPaintMatrix(glyph, placement) {
|
|
3885
|
+
const s = placement.size / glyph.box;
|
|
3886
|
+
const theta = placement.angle ?? 0;
|
|
3887
|
+
const a = s * Math.cos(theta);
|
|
3888
|
+
const b = s * Math.sin(theta);
|
|
3889
|
+
const [hx, hy] = glyph.hotspot;
|
|
3890
|
+
return [a, b, -b, a, placement.at.x - (a * hx - b * hy), placement.at.y - (b * hx + a * hy)];
|
|
3891
|
+
}
|
|
3892
|
+
function cursorWorldSize(glyph, worldRadius, scale2) {
|
|
3893
|
+
const r = glyph.radius ?? glyph.box / 2;
|
|
3894
|
+
return worldRadius * scale2 * glyph.box / r;
|
|
3895
|
+
}
|
|
3896
|
+
function chromeLineWidthScale(glyph, size) {
|
|
3897
|
+
return glyph.box / size;
|
|
3898
|
+
}
|
|
3899
|
+
function quantizeCursorAngle(angle) {
|
|
3900
|
+
const i = Math.round(angle / (Math.PI * 2) * CURSOR_ANGLE_STEPS);
|
|
3901
|
+
return (i % CURSOR_ANGLE_STEPS + CURSOR_ANGLE_STEPS) % CURSOR_ANGLE_STEPS;
|
|
3902
|
+
}
|
|
3903
|
+
function renderOp(op) {
|
|
3904
|
+
const fill = op.fill === void 0 ? "none" : op.fill;
|
|
3905
|
+
const stroke = op.stroke ? ` stroke="${op.stroke.color}" stroke-width="${op.stroke.width}" stroke-linecap="round" stroke-linejoin="round"` : "";
|
|
3906
|
+
return `<path d="${op.d}" fill="${fill}"${stroke}/>`;
|
|
3907
|
+
}
|
|
3908
|
+
function bakeCursor(glyph, opts = {}) {
|
|
3909
|
+
const size = opts.size ?? 24;
|
|
3910
|
+
if (size > CURSOR_MAX_CSS_PX) {
|
|
3911
|
+
throw new RangeError(
|
|
3912
|
+
`cursor size ${size} exceeds the ${CURSOR_MAX_CSS_PX}px cap: the browser would drop the image and silently fall back. Use the painted tier.`
|
|
3913
|
+
);
|
|
3914
|
+
}
|
|
3915
|
+
const paths = cursorPaintOps(glyph).map(renderOp).join("");
|
|
3916
|
+
const c = glyph.box / 2;
|
|
3917
|
+
const step = quantizeCursorAngle(opts.angle ?? 0);
|
|
3918
|
+
const theta = step / CURSOR_ANGLE_STEPS * Math.PI * 2;
|
|
3919
|
+
const body = step === 0 ? paths : `<g transform="rotate(${step * 360 / CURSOR_ANGLE_STEPS} ${c} ${c})">${paths}</g>`;
|
|
3920
|
+
const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${glyph.box} ${glyph.box}">${body}</svg>`;
|
|
3921
|
+
const dx = glyph.hotspot[0] - c;
|
|
3922
|
+
const dy = glyph.hotspot[1] - c;
|
|
3923
|
+
const cos = Math.cos(theta);
|
|
3924
|
+
const sin = Math.sin(theta);
|
|
3925
|
+
const hx = Math.round((c + cos * dx - sin * dy) / glyph.box * size);
|
|
3926
|
+
const hy = Math.round((c + sin * dx + cos * dy) / glyph.box * size);
|
|
3927
|
+
const uri = `data:image/svg+xml,${encodeURIComponent(svg)}`;
|
|
3928
|
+
return `url("${uri}") ${hx} ${hy}, ${opts.fallback ?? "default"}`;
|
|
3929
|
+
}
|
|
3930
|
+
var GLYPHS = {
|
|
3931
|
+
"pencil": {
|
|
3932
|
+
"box": 24,
|
|
3933
|
+
"hotspot": [
|
|
3934
|
+
5,
|
|
3935
|
+
19
|
|
3936
|
+
],
|
|
3937
|
+
"paths": [
|
|
3938
|
+
{
|
|
3939
|
+
"role": "ink",
|
|
3940
|
+
"d": "M 5 19 L 7.5 16.5 L 16 8 L 19 11 L 10.5 19.5 L 8 19 Z"
|
|
3941
|
+
},
|
|
3942
|
+
{
|
|
3943
|
+
"role": "detail",
|
|
3944
|
+
"d": "M 14 6 L 19 11",
|
|
3945
|
+
"width": 1.2
|
|
3946
|
+
}
|
|
3947
|
+
]
|
|
3948
|
+
},
|
|
3949
|
+
"pen": {
|
|
3950
|
+
"box": 24,
|
|
3951
|
+
"hotspot": [
|
|
3952
|
+
5,
|
|
3953
|
+
19
|
|
3954
|
+
],
|
|
3955
|
+
"paths": [
|
|
3956
|
+
{
|
|
3957
|
+
"role": "ink",
|
|
3958
|
+
"d": "M 5 19 L 8.5 9.5 L 13 5 L 18 10 L 13.5 14.5 Z"
|
|
3959
|
+
},
|
|
3960
|
+
{
|
|
3961
|
+
"role": "detail",
|
|
3962
|
+
"d": "M 8.4 13.9 L 12.2 10.1",
|
|
3963
|
+
"width": 0.9
|
|
3964
|
+
}
|
|
3965
|
+
]
|
|
3966
|
+
},
|
|
3967
|
+
"eyedropper": {
|
|
3968
|
+
"box": 24,
|
|
3969
|
+
"hotspot": [
|
|
3970
|
+
5,
|
|
3971
|
+
19
|
|
3972
|
+
],
|
|
3973
|
+
"paths": [
|
|
3974
|
+
{
|
|
3975
|
+
"role": "ink",
|
|
3976
|
+
"d": "M 5 19 L 6.8 14.8 L 14.4 7.2 L 16.8 9.6 L 9.2 17.2 Z"
|
|
3977
|
+
},
|
|
3978
|
+
{
|
|
3979
|
+
"role": "ink",
|
|
3980
|
+
"d": "M 18.2 2.6 A 3.2 3.2 0 1 0 18.2 9 A 3.2 3.2 0 1 0 18.2 2.6 Z"
|
|
3981
|
+
}
|
|
3982
|
+
]
|
|
3983
|
+
},
|
|
3984
|
+
"brush": {
|
|
3985
|
+
"box": 24,
|
|
3986
|
+
"hotspot": [
|
|
3987
|
+
12,
|
|
3988
|
+
12
|
|
3989
|
+
],
|
|
3990
|
+
"radius": 9.9,
|
|
3991
|
+
"paths": [
|
|
3992
|
+
{
|
|
3993
|
+
"role": "stroke",
|
|
3994
|
+
"d": "M 12 2.1 A 9.9 9.9 0 1 0 12 21.9 A 9.9 9.9 0 1 0 12 2.1 Z",
|
|
3995
|
+
"width": 1.6
|
|
3996
|
+
}
|
|
3997
|
+
]
|
|
3998
|
+
},
|
|
3999
|
+
"crosshairRect": {
|
|
4000
|
+
"box": 24,
|
|
4001
|
+
"hotspot": [
|
|
4002
|
+
9,
|
|
4003
|
+
9
|
|
4004
|
+
],
|
|
4005
|
+
"paths": [
|
|
4006
|
+
{
|
|
4007
|
+
"role": "stroke",
|
|
4008
|
+
"d": "M 1.6 9 L 6.4 9",
|
|
4009
|
+
"width": 1.6
|
|
4010
|
+
},
|
|
4011
|
+
{
|
|
4012
|
+
"role": "stroke",
|
|
4013
|
+
"d": "M 11.6 9 L 16.4 9",
|
|
4014
|
+
"width": 1.6
|
|
4015
|
+
},
|
|
4016
|
+
{
|
|
4017
|
+
"role": "stroke",
|
|
4018
|
+
"d": "M 9 1.6 L 9 6.4",
|
|
4019
|
+
"width": 1.6
|
|
4020
|
+
},
|
|
4021
|
+
{
|
|
4022
|
+
"role": "stroke",
|
|
4023
|
+
"d": "M 9 11.6 L 9 16.4",
|
|
4024
|
+
"width": 1.6
|
|
4025
|
+
},
|
|
4026
|
+
{
|
|
4027
|
+
"role": "ink",
|
|
4028
|
+
"d": "M 14.2 14.2 L 21 14.2 L 21 21 L 14.2 21 Z"
|
|
4029
|
+
}
|
|
4030
|
+
]
|
|
4031
|
+
},
|
|
4032
|
+
"crosshairEllipse": {
|
|
4033
|
+
"box": 24,
|
|
4034
|
+
"hotspot": [
|
|
4035
|
+
9,
|
|
4036
|
+
9
|
|
4037
|
+
],
|
|
4038
|
+
"paths": [
|
|
4039
|
+
{
|
|
4040
|
+
"role": "stroke",
|
|
4041
|
+
"d": "M 1.6 9 L 6.4 9",
|
|
4042
|
+
"width": 1.6
|
|
4043
|
+
},
|
|
4044
|
+
{
|
|
4045
|
+
"role": "stroke",
|
|
4046
|
+
"d": "M 11.6 9 L 16.4 9",
|
|
4047
|
+
"width": 1.6
|
|
4048
|
+
},
|
|
4049
|
+
{
|
|
4050
|
+
"role": "stroke",
|
|
4051
|
+
"d": "M 9 1.6 L 9 6.4",
|
|
4052
|
+
"width": 1.6
|
|
4053
|
+
},
|
|
4054
|
+
{
|
|
4055
|
+
"role": "stroke",
|
|
4056
|
+
"d": "M 9 11.6 L 9 16.4",
|
|
4057
|
+
"width": 1.6
|
|
4058
|
+
},
|
|
4059
|
+
{
|
|
4060
|
+
"role": "ink",
|
|
4061
|
+
"d": "M 17.6 13.9 A 3.7 3.7 0 1 0 17.6 21.3 A 3.7 3.7 0 1 0 17.6 13.9 Z"
|
|
4062
|
+
}
|
|
4063
|
+
]
|
|
4064
|
+
},
|
|
4065
|
+
"crosshairLine": {
|
|
4066
|
+
"box": 24,
|
|
4067
|
+
"hotspot": [
|
|
4068
|
+
9,
|
|
4069
|
+
9
|
|
4070
|
+
],
|
|
4071
|
+
"paths": [
|
|
4072
|
+
{
|
|
4073
|
+
"role": "stroke",
|
|
4074
|
+
"d": "M 1.6 9 L 6.4 9",
|
|
4075
|
+
"width": 1.6
|
|
4076
|
+
},
|
|
4077
|
+
{
|
|
4078
|
+
"role": "stroke",
|
|
4079
|
+
"d": "M 11.6 9 L 16.4 9",
|
|
4080
|
+
"width": 1.6
|
|
4081
|
+
},
|
|
4082
|
+
{
|
|
4083
|
+
"role": "stroke",
|
|
4084
|
+
"d": "M 9 1.6 L 9 6.4",
|
|
4085
|
+
"width": 1.6
|
|
4086
|
+
},
|
|
4087
|
+
{
|
|
4088
|
+
"role": "stroke",
|
|
4089
|
+
"d": "M 9 11.6 L 9 16.4",
|
|
4090
|
+
"width": 1.6
|
|
4091
|
+
},
|
|
4092
|
+
{
|
|
4093
|
+
"role": "stroke",
|
|
4094
|
+
"d": "M 14.2 21 L 21 14.2",
|
|
4095
|
+
"width": 2.2
|
|
4096
|
+
}
|
|
4097
|
+
]
|
|
4098
|
+
},
|
|
4099
|
+
"crosshairStar": {
|
|
4100
|
+
"box": 24,
|
|
4101
|
+
"hotspot": [
|
|
4102
|
+
9,
|
|
4103
|
+
9
|
|
4104
|
+
],
|
|
4105
|
+
"paths": [
|
|
4106
|
+
{
|
|
4107
|
+
"role": "stroke",
|
|
4108
|
+
"d": "M 1.6 9 L 6.4 9",
|
|
4109
|
+
"width": 1.6
|
|
4110
|
+
},
|
|
4111
|
+
{
|
|
4112
|
+
"role": "stroke",
|
|
4113
|
+
"d": "M 11.6 9 L 16.4 9",
|
|
4114
|
+
"width": 1.6
|
|
4115
|
+
},
|
|
4116
|
+
{
|
|
4117
|
+
"role": "stroke",
|
|
4118
|
+
"d": "M 9 1.6 L 9 6.4",
|
|
4119
|
+
"width": 1.6
|
|
4120
|
+
},
|
|
4121
|
+
{
|
|
4122
|
+
"role": "stroke",
|
|
4123
|
+
"d": "M 9 11.6 L 9 16.4",
|
|
4124
|
+
"width": 1.6
|
|
4125
|
+
},
|
|
4126
|
+
{
|
|
4127
|
+
"role": "ink",
|
|
4128
|
+
"d": "M 17.6 13.4 L 18.72 16.06 L 21.59 16.3 L 19.41 18.19 L 20.07 21 L 17.6 19.5 L 15.13 21 L 15.79 18.19 L 13.61 16.3 L 16.48 16.06 Z"
|
|
4129
|
+
}
|
|
4130
|
+
]
|
|
4131
|
+
},
|
|
4132
|
+
"crosshairPolygon": {
|
|
4133
|
+
"box": 24,
|
|
4134
|
+
"hotspot": [
|
|
4135
|
+
9,
|
|
4136
|
+
9
|
|
4137
|
+
],
|
|
4138
|
+
"paths": [
|
|
4139
|
+
{
|
|
4140
|
+
"role": "stroke",
|
|
4141
|
+
"d": "M 1.6 9 L 6.4 9",
|
|
4142
|
+
"width": 1.6
|
|
4143
|
+
},
|
|
4144
|
+
{
|
|
4145
|
+
"role": "stroke",
|
|
4146
|
+
"d": "M 11.6 9 L 16.4 9",
|
|
4147
|
+
"width": 1.6
|
|
4148
|
+
},
|
|
4149
|
+
{
|
|
4150
|
+
"role": "stroke",
|
|
4151
|
+
"d": "M 9 1.6 L 9 6.4",
|
|
4152
|
+
"width": 1.6
|
|
4153
|
+
},
|
|
4154
|
+
{
|
|
4155
|
+
"role": "stroke",
|
|
4156
|
+
"d": "M 9 11.6 L 9 16.4",
|
|
4157
|
+
"width": 1.6
|
|
4158
|
+
},
|
|
4159
|
+
{
|
|
4160
|
+
"role": "ink",
|
|
4161
|
+
"d": "M 17.6 13.5 L 21.5 16.33 L 20.01 20.92 L 15.19 20.92 L 13.7 16.33 Z"
|
|
4162
|
+
}
|
|
4163
|
+
]
|
|
4164
|
+
},
|
|
4165
|
+
"resize": {
|
|
4166
|
+
"box": 24,
|
|
4167
|
+
"hotspot": [
|
|
4168
|
+
12,
|
|
4169
|
+
12
|
|
4170
|
+
],
|
|
4171
|
+
"paths": [
|
|
4172
|
+
{
|
|
4173
|
+
"role": "ink",
|
|
4174
|
+
"d": "M 2.5 12 L 7 8.8 L 7 10.7 L 17 10.7 L 17 8.8 L 21.5 12 L 17 15.2 L 17 13.3 L 7 13.3 L 7 15.2 Z"
|
|
4175
|
+
}
|
|
4176
|
+
]
|
|
4177
|
+
},
|
|
4178
|
+
"rotate": {
|
|
4179
|
+
"box": 24,
|
|
4180
|
+
"hotspot": [
|
|
4181
|
+
12,
|
|
4182
|
+
12
|
|
4183
|
+
],
|
|
4184
|
+
"paths": [
|
|
4185
|
+
{
|
|
4186
|
+
"role": "stroke",
|
|
4187
|
+
"d": "M 5.8 9.74 A 6.6 6.6 0 0 1 18.2 9.74",
|
|
4188
|
+
"width": 2.8
|
|
4189
|
+
},
|
|
4190
|
+
{
|
|
4191
|
+
"role": "ink",
|
|
4192
|
+
"d": "M 4.22 14.07 L 2.98 8.72 L 8.62 10.77 Z"
|
|
4193
|
+
},
|
|
4194
|
+
{
|
|
4195
|
+
"role": "ink",
|
|
4196
|
+
"d": "M 19.78 14.07 L 15.38 10.77 L 21.02 8.72 Z"
|
|
4197
|
+
}
|
|
4198
|
+
]
|
|
4199
|
+
}
|
|
4200
|
+
};
|
|
4201
|
+
var cache2 = /* @__PURE__ */ new Map();
|
|
4202
|
+
function cursorFor(name, opts = {}) {
|
|
4203
|
+
const size = opts.size ?? 24;
|
|
4204
|
+
const fallback = opts.fallback ?? "default";
|
|
4205
|
+
const step = quantizeCursorAngle(opts.angle ?? 0);
|
|
4206
|
+
const key = `${name}|${size}|${step}|${fallback}`;
|
|
4207
|
+
const hit = cache2.get(key);
|
|
4208
|
+
if (hit !== void 0) return hit;
|
|
4209
|
+
const glyph = GLYPHS[name];
|
|
4210
|
+
if (glyph === void 0) {
|
|
4211
|
+
throw new Error(`unknown cursor glyph: ${String(name)}`);
|
|
4212
|
+
}
|
|
4213
|
+
const css = bakeCursor(glyph, { size, fallback, angle: opts.angle ?? 0 });
|
|
4214
|
+
cache2.set(key, css);
|
|
4215
|
+
return css;
|
|
4216
|
+
}
|
|
4217
|
+
function resolveCursorTier(spec) {
|
|
4218
|
+
if (typeof spec === "string") return { kind: "css", css: spec };
|
|
4219
|
+
const { glyph, size, worldRadius, angle = 0, fallback } = spec;
|
|
4220
|
+
if (worldRadius !== void 0) {
|
|
4221
|
+
return { kind: "painted", glyph, angle, worldRadius };
|
|
4222
|
+
}
|
|
4223
|
+
if (size !== void 0 && size > CURSOR_MAX_CSS_PX) {
|
|
4224
|
+
return { kind: "painted", glyph, angle, size };
|
|
4225
|
+
}
|
|
4226
|
+
return {
|
|
4227
|
+
kind: "css",
|
|
4228
|
+
css: cursorFor(glyph, {
|
|
4229
|
+
...size !== void 0 ? { size } : {},
|
|
4230
|
+
...fallback !== void 0 ? { fallback } : {},
|
|
4231
|
+
angle
|
|
4232
|
+
})
|
|
4233
|
+
};
|
|
4234
|
+
}
|
|
4235
|
+
function resolveCursor(spec) {
|
|
4236
|
+
if (spec === void 0) return void 0;
|
|
4237
|
+
const r = resolveCursorTier(spec);
|
|
4238
|
+
return r.kind === "css" ? r.css : "none";
|
|
4239
|
+
}
|
|
4240
|
+
|
|
3844
4241
|
// ../history/dist/index.js
|
|
3845
4242
|
var RESUMERS = /* @__PURE__ */ new WeakMap();
|
|
3846
4243
|
function _resumeJournalInternal(j) {
|
|
@@ -4263,7 +4660,7 @@ function serialToEntry(se, custom, logger) {
|
|
|
4263
4660
|
};
|
|
4264
4661
|
}
|
|
4265
4662
|
|
|
4266
|
-
// ../core/dist/chunk-
|
|
4663
|
+
// ../core/dist/chunk-HYJL7OOJ.js
|
|
4267
4664
|
function worldToScreen(worldX, worldY, view) {
|
|
4268
4665
|
return [view.panX + worldX * view.zoom.x, view.panY + worldY * view.zoom.y];
|
|
4269
4666
|
}
|
|
@@ -5821,12 +6218,12 @@ function pointInContour(coords, start, end, x, y) {
|
|
|
5821
6218
|
}
|
|
5822
6219
|
return inside;
|
|
5823
6220
|
}
|
|
5824
|
-
var
|
|
6221
|
+
var cache3 = /* @__PURE__ */ new WeakMap();
|
|
5825
6222
|
function getMesh(path) {
|
|
5826
|
-
const cached2 =
|
|
6223
|
+
const cached2 = cache3.get(path);
|
|
5827
6224
|
if (cached2 !== void 0) return cached2;
|
|
5828
6225
|
const mesh = tessellate(path);
|
|
5829
|
-
|
|
6226
|
+
cache3.set(path, mesh);
|
|
5830
6227
|
return mesh;
|
|
5831
6228
|
}
|
|
5832
6229
|
function extractPolylines(path, opts = {}) {
|
|
@@ -6846,7 +7243,7 @@ function outlineMesh(key, d) {
|
|
|
6846
7243
|
}
|
|
6847
7244
|
var OUTLINE_STROKE_MESH_CACHE_LIMIT = 2048;
|
|
6848
7245
|
var WIDTH_QUANTUM = 1 / 1024;
|
|
6849
|
-
var
|
|
7246
|
+
var cache32 = /* @__PURE__ */ new Map();
|
|
6850
7247
|
function quantizeEmWidth(emWidth) {
|
|
6851
7248
|
return Math.round(emWidth / WIDTH_QUANTUM) * WIDTH_QUANTUM;
|
|
6852
7249
|
}
|
|
@@ -6861,15 +7258,15 @@ function outlineStrokeMesh(glyphKey, d, emWidth, stroke) {
|
|
|
6861
7258
|
stroke.align ?? "center",
|
|
6862
7259
|
(stroke.dash ?? []).join(",")
|
|
6863
7260
|
].join("|");
|
|
6864
|
-
const cached2 =
|
|
7261
|
+
const cached2 = cache32.get(key);
|
|
6865
7262
|
if (cached2 !== void 0) return cached2.indices.length === 0 ? null : cached2;
|
|
6866
|
-
if (
|
|
7263
|
+
if (cache32.size >= OUTLINE_STROKE_MESH_CACHE_LIMIT) cache32 = /* @__PURE__ */ new Map();
|
|
6867
7264
|
const mesh = tessellateStroke(
|
|
6868
7265
|
pathFromD(d),
|
|
6869
7266
|
{ ...stroke, width: emWidth },
|
|
6870
7267
|
{ flattenTolerance: OUTLINE_FLATTEN_TOLERANCE }
|
|
6871
7268
|
);
|
|
6872
|
-
|
|
7269
|
+
cache32.set(key, mesh);
|
|
6873
7270
|
return mesh.indices.length === 0 ? null : mesh;
|
|
6874
7271
|
}
|
|
6875
7272
|
function poly(pts, size, close = true) {
|
|
@@ -9768,8 +10165,8 @@ function runLayoutPass(scratch, moveCtx) {
|
|
|
9768
10165
|
for (const [cid, pose] of srcLayout.childPoses(srcContainer, srcChildren)) {
|
|
9769
10166
|
const cur = composeWorldPose(poseAdapter, cid, pc.compose);
|
|
9770
10167
|
const next = pose;
|
|
9771
|
-
const
|
|
9772
|
-
if (
|
|
10168
|
+
const same2 = cur.x === next.x && cur.y === next.y && cur.width === next.width && cur.height === next.height;
|
|
10169
|
+
if (same2) continue;
|
|
9773
10170
|
sourceReflow.set(cid, pose);
|
|
9774
10171
|
const parent = scene.get(asNodeId(cid))?.parent ?? null;
|
|
9775
10172
|
scratch.previews.set(asNodeId(cid), rebaseLocalPose(poseAdapter, pose, parent, pc.compose, pc.decompose));
|
|
@@ -11123,6 +11520,11 @@ var cloneAction = {
|
|
|
11123
11520
|
id: "clone",
|
|
11124
11521
|
label: "Clone",
|
|
11125
11522
|
defaultBinding: { kind: "drag" },
|
|
11523
|
+
// The platform's duplicate cursor, and the whole reason this field is
|
|
11524
|
+
// modifier-aware: the select tool binds clone behind `mods: { alt: true }`,
|
|
11525
|
+
// so the pump predicts it — and shows this — only while Alt is down.
|
|
11526
|
+
cursor: "copy",
|
|
11527
|
+
activeCursor: "copy",
|
|
11126
11528
|
eligible: { capability: ["edits-page", "creates-selection"] },
|
|
11127
11529
|
requires: ["selection", "scene", "applyOps"],
|
|
11128
11530
|
invoker: {
|
|
@@ -15513,7 +15915,7 @@ function createDispatcher(opts) {
|
|
|
15513
15915
|
}
|
|
15514
15916
|
function inFlightCursor() {
|
|
15515
15917
|
for (const action of inFlightActions.values()) {
|
|
15516
|
-
const cursor = action.activeCursor ?? action.cursor;
|
|
15918
|
+
const cursor = resolveCursor(action.activeCursor ?? action.cursor);
|
|
15517
15919
|
if (cursor) return cursor;
|
|
15518
15920
|
}
|
|
15519
15921
|
return null;
|
|
@@ -15735,7 +16137,7 @@ function computeMultiTouchGeometry(positions) {
|
|
|
15735
16137
|
return { centroid, spread };
|
|
15736
16138
|
}
|
|
15737
16139
|
function useGestureDispatcher(opts) {
|
|
15738
|
-
const { canvasRef, actions, toolsById, enabled = true, keyboard = true, affordanceAt, classifyTarget, dispatcher: dispatcherOpt, clientToWorld: clientToWorld2, requestRedraw, getRuleCtx, onDoubleClick, views } = opts;
|
|
16140
|
+
const { canvasRef, actions, toolsById, enabled = true, keyboard = true, affordanceAt, classifyTarget, dispatcher: dispatcherOpt, clientToWorld: clientToWorld2, requestRedraw, paintedCursor, getRuleCtx, onDoubleClick, views } = opts;
|
|
15739
16141
|
const onDoubleClickRef = useRef(onDoubleClick);
|
|
15740
16142
|
onDoubleClickRef.current = onDoubleClick;
|
|
15741
16143
|
const activeTool = useActiveToolContext();
|
|
@@ -15784,6 +16186,8 @@ function useGestureDispatcher(opts) {
|
|
|
15784
16186
|
];
|
|
15785
16187
|
const requestRedrawRef = useRef(requestRedraw);
|
|
15786
16188
|
requestRedrawRef.current = requestRedraw;
|
|
16189
|
+
const paintedCursorRef = useRef(paintedCursor);
|
|
16190
|
+
paintedCursorRef.current = paintedCursor;
|
|
15787
16191
|
const lastClickRef = useRef(null);
|
|
15788
16192
|
const prevActiveRef = useRef(activeTool.active);
|
|
15789
16193
|
useEffect(() => {
|
|
@@ -16123,20 +16527,39 @@ function useGestureDispatcher(opts) {
|
|
|
16123
16527
|
let lastHover = null;
|
|
16124
16528
|
let cursorOverridden = false;
|
|
16125
16529
|
const clearHoverCursor = () => {
|
|
16530
|
+
paintedCursorRef.current?.()?.setOverride(null);
|
|
16126
16531
|
if (cursorOverridden && canvas) {
|
|
16127
16532
|
canvas.style.cursor = "";
|
|
16128
16533
|
cursorOverridden = false;
|
|
16129
16534
|
}
|
|
16130
16535
|
};
|
|
16131
|
-
const applyHoverCursor = (
|
|
16132
|
-
|
|
16133
|
-
|
|
16134
|
-
|
|
16135
|
-
|
|
16536
|
+
const applyHoverCursor = (spec) => {
|
|
16537
|
+
const tier = spec === null ? null : resolveCursorTier(spec);
|
|
16538
|
+
if (!tier || !canvas) {
|
|
16539
|
+
clearHoverCursor();
|
|
16540
|
+
return;
|
|
16541
|
+
}
|
|
16542
|
+
const painted = tier.kind === "painted" ? tier : null;
|
|
16543
|
+
paintedCursorRef.current?.()?.setOverride(painted);
|
|
16544
|
+
const cursor = tier.kind === "css" ? tier.css : "none";
|
|
16545
|
+
if (!cursor) {
|
|
16136
16546
|
clearHoverCursor();
|
|
16547
|
+
return;
|
|
16137
16548
|
}
|
|
16549
|
+
canvas.style.cursor = cursor;
|
|
16550
|
+
cursorOverridden = true;
|
|
16138
16551
|
};
|
|
16552
|
+
function pushPaintedPointer() {
|
|
16553
|
+
const painted = paintedCursorRef.current?.();
|
|
16554
|
+
if (!painted?.active() || !canvas || !lastHover) return;
|
|
16555
|
+
const r = canvas.getBoundingClientRect();
|
|
16556
|
+
painted.setPointer(lastHover.clientX - r.left, lastHover.clientY - r.top);
|
|
16557
|
+
}
|
|
16139
16558
|
function refreshHoverCursor() {
|
|
16559
|
+
resolveHoverCursor();
|
|
16560
|
+
pushPaintedPointer();
|
|
16561
|
+
}
|
|
16562
|
+
function resolveHoverCursor() {
|
|
16140
16563
|
if (!canvas || !lastHover) return;
|
|
16141
16564
|
if (activePointers.size > 0 || dispatcherNow().inFlight().size > 0) {
|
|
16142
16565
|
applyHoverCursor(dispatcherNow().inFlightCursor());
|
|
@@ -16188,6 +16611,7 @@ function useGestureDispatcher(opts) {
|
|
|
16188
16611
|
};
|
|
16189
16612
|
const onHoverPointerLeave = () => {
|
|
16190
16613
|
lastHover = null;
|
|
16614
|
+
paintedCursorRef.current?.()?.clearPointer();
|
|
16191
16615
|
clearHoverCursor();
|
|
16192
16616
|
};
|
|
16193
16617
|
const onPointerUp = (e) => {
|
|
@@ -17697,7 +18121,7 @@ function validateId(id, kind) {
|
|
|
17697
18121
|
}
|
|
17698
18122
|
function defineTool(def) {
|
|
17699
18123
|
validateId(def.id, "tool");
|
|
17700
|
-
const
|
|
18124
|
+
const resolveCursor3 = (ctx) => {
|
|
17701
18125
|
if (def.cursor == null) return "";
|
|
17702
18126
|
return typeof def.cursor === "function" ? def.cursor(ctx) : def.cursor;
|
|
17703
18127
|
};
|
|
@@ -17715,7 +18139,7 @@ function defineTool(def) {
|
|
|
17715
18139
|
onActivate: def.onActivate,
|
|
17716
18140
|
onDeactivate: def.onDeactivate,
|
|
17717
18141
|
initScratch: def.initScratch ?? (() => null),
|
|
17718
|
-
cursor:
|
|
18142
|
+
cursor: resolveCursor3,
|
|
17719
18143
|
bindings: def.bindings,
|
|
17720
18144
|
overlay: def.overlay,
|
|
17721
18145
|
overlayPosition: def.overlayPosition
|
|
@@ -18715,10 +19139,10 @@ function findShapeInk(node, pose, ctx) {
|
|
|
18715
19139
|
function shapeCoversPoint(node, pose, x, y, opts = {}) {
|
|
18716
19140
|
const sil = findShapeSilhouette(node, pose, { derivedPath: opts.derivedPath });
|
|
18717
19141
|
if (sil === null) return true;
|
|
18718
|
-
const
|
|
19142
|
+
const ink2 = findShapeInk(node, pose, { scale: opts.scale }) ?? DEFAULT_INK;
|
|
18719
19143
|
const inside = pathContainsPoint(sil, x, y);
|
|
18720
|
-
if (
|
|
18721
|
-
const reach = (inside ?
|
|
19144
|
+
if (ink2.filled && inside) return true;
|
|
19145
|
+
const reach = (inside ? ink2.inset : ink2.outset) + (opts.tolerance ?? 0);
|
|
18722
19146
|
return reach > 0 && strokeHitTest(sil, x, y, reach);
|
|
18723
19147
|
}
|
|
18724
19148
|
var TEXT_PAINTER = {
|
|
@@ -19617,6 +20041,9 @@ function transformOf(state, targetId) {
|
|
|
19617
20041
|
identity: false
|
|
19618
20042
|
};
|
|
19619
20043
|
}
|
|
20044
|
+
function angleOf(xf) {
|
|
20045
|
+
return xf.identity ? 0 : Math.atan2(xf.sin, xf.cos);
|
|
20046
|
+
}
|
|
19620
20047
|
function localToWorld(xf, lx, ly) {
|
|
19621
20048
|
if (xf.identity) return { x: lx, y: ly };
|
|
19622
20049
|
const dx = lx - xf.cx;
|
|
@@ -19916,11 +20343,7 @@ var DEFAULT_PAINT = {
|
|
|
19916
20343
|
insetPx: 10
|
|
19917
20344
|
};
|
|
19918
20345
|
function createRotationAffordance(opts = {}) {
|
|
19919
|
-
const {
|
|
19920
|
-
bandPx = 24,
|
|
19921
|
-
paint = DEFAULT_PAINT,
|
|
19922
|
-
cursor = "grab"
|
|
19923
|
-
} = opts;
|
|
20346
|
+
const { bandPx = 24, paint = DEFAULT_PAINT, cursor } = opts;
|
|
19924
20347
|
const annulusPaint = (() => {
|
|
19925
20348
|
if (!paint) return null;
|
|
19926
20349
|
if ("paint" in paint) {
|
|
@@ -19958,7 +20381,14 @@ function createRotationAffordance(opts = {}) {
|
|
|
19958
20381
|
},
|
|
19959
20382
|
...annulusPaint ? { paint: annulusPaint } : {},
|
|
19960
20383
|
hitKind: "rotate-handle",
|
|
19961
|
-
|
|
20384
|
+
// Turned with the target, so the arc follows the selection it rotates.
|
|
20385
|
+
// Resolved per region rather than defaulted in the option list because
|
|
20386
|
+
// the angle is only known once a target is picked.
|
|
20387
|
+
cursor: cursor ?? {
|
|
20388
|
+
glyph: "rotate",
|
|
20389
|
+
angle: angleOf(transformOf(state, target.id)),
|
|
20390
|
+
fallback: "grab"
|
|
20391
|
+
},
|
|
19962
20392
|
bind: () => ({
|
|
19963
20393
|
initialScratch: {
|
|
19964
20394
|
targetId: target.id,
|
|
@@ -20368,7 +20798,7 @@ function usePenTool(options) {
|
|
|
20368
20798
|
hookName: "usePenTool",
|
|
20369
20799
|
// Reads the tool's own ref rather than a scratch handed in by a
|
|
20370
20800
|
// dispatcher — the pen owns this state and nothing else needs it.
|
|
20371
|
-
cursor: () => scratchRef.current?.closeHintActive ? "pointer" : "crosshair",
|
|
20801
|
+
cursor: () => scratchRef.current?.closeHintActive ? "pointer" : cursorFor("pen", { fallback: "crosshair" }),
|
|
20372
20802
|
presentation: {
|
|
20373
20803
|
label: "Pen",
|
|
20374
20804
|
icon: createElement(PenIcon),
|
|
@@ -20437,7 +20867,7 @@ function useRectTool() {
|
|
|
20437
20867
|
id: "rect",
|
|
20438
20868
|
capabilities: ["creates-shapes"],
|
|
20439
20869
|
hookName: "useRectTool",
|
|
20440
|
-
cursor: "crosshair",
|
|
20870
|
+
cursor: cursorFor("crosshairRect", { fallback: "crosshair" }),
|
|
20441
20871
|
presentation: {
|
|
20442
20872
|
label: "Rectangle",
|
|
20443
20873
|
icon: createElement(RectIcon),
|
|
@@ -20463,7 +20893,7 @@ function useEllipseTool() {
|
|
|
20463
20893
|
id: "ellipse",
|
|
20464
20894
|
capabilities: ["creates-shapes"],
|
|
20465
20895
|
hookName: "useEllipseTool",
|
|
20466
|
-
cursor: "crosshair",
|
|
20896
|
+
cursor: cursorFor("crosshairEllipse", { fallback: "crosshair" }),
|
|
20467
20897
|
presentation: {
|
|
20468
20898
|
label: "Ellipse",
|
|
20469
20899
|
group: "shape",
|
|
@@ -20486,7 +20916,7 @@ function useLineTool() {
|
|
|
20486
20916
|
id: "line",
|
|
20487
20917
|
capabilities: ["creates-shapes"],
|
|
20488
20918
|
hookName: "useLineTool",
|
|
20489
|
-
cursor: "crosshair",
|
|
20919
|
+
cursor: cursorFor("crosshairLine", { fallback: "crosshair" }),
|
|
20490
20920
|
presentation: {
|
|
20491
20921
|
label: "Line",
|
|
20492
20922
|
group: "shape",
|
|
@@ -20597,7 +21027,7 @@ function usePolygonTool(options = {}) {
|
|
|
20597
21027
|
id: "polygon",
|
|
20598
21028
|
capabilities: ["creates-shapes"],
|
|
20599
21029
|
hookName: "usePolygonTool",
|
|
20600
|
-
cursor: "crosshair",
|
|
21030
|
+
cursor: cursorFor("crosshairPolygon", { fallback: "crosshair" }),
|
|
20601
21031
|
// Registered by <ToolActionsMounter>, inside the ActionsProvider —
|
|
20602
21032
|
// see `ToolDef.actions` for why the hook can't register it itself.
|
|
20603
21033
|
actions: [adjustSidesAction],
|
|
@@ -20697,7 +21127,7 @@ function useStarTool(options = {}) {
|
|
|
20697
21127
|
id: "star",
|
|
20698
21128
|
capabilities: ["creates-shapes"],
|
|
20699
21129
|
hookName: "useStarTool",
|
|
20700
|
-
cursor: "crosshair",
|
|
21130
|
+
cursor: cursorFor("crosshairStar", { fallback: "crosshair" }),
|
|
20701
21131
|
// Registered by <ToolActionsMounter>, inside the ActionsProvider —
|
|
20702
21132
|
// see `ToolDef.actions` for why the hook can't register it itself.
|
|
20703
21133
|
actions: [adjustPointsAction],
|
|
@@ -20753,7 +21183,7 @@ function usePencilTool() {
|
|
|
20753
21183
|
id: "pencil",
|
|
20754
21184
|
capabilities: ["creates-paths"],
|
|
20755
21185
|
hookName: "usePencilTool",
|
|
20756
|
-
cursor: "crosshair",
|
|
21186
|
+
cursor: cursorFor("pencil", { fallback: "crosshair" }),
|
|
20757
21187
|
presentation: {
|
|
20758
21188
|
label: "Pencil",
|
|
20759
21189
|
group: "draw",
|
|
@@ -21734,6 +22164,111 @@ function buildSceneTree(adapter, drawOne, view, forLayer, derivedPathOf) {
|
|
|
21734
22164
|
}
|
|
21735
22165
|
return out;
|
|
21736
22166
|
}
|
|
22167
|
+
function same(a, b) {
|
|
22168
|
+
if (a === b) return true;
|
|
22169
|
+
if (!a || !b) return false;
|
|
22170
|
+
return a.glyph === b.glyph && a.angle === b.angle && a.size === b.size && a.worldRadius === b.worldRadius;
|
|
22171
|
+
}
|
|
22172
|
+
function createPaintedCursorState() {
|
|
22173
|
+
let base = null;
|
|
22174
|
+
let override = null;
|
|
22175
|
+
let at = null;
|
|
22176
|
+
const subs = /* @__PURE__ */ new Set();
|
|
22177
|
+
const notify2 = () => {
|
|
22178
|
+
for (const fn of subs) fn();
|
|
22179
|
+
};
|
|
22180
|
+
return {
|
|
22181
|
+
setBase(cursor) {
|
|
22182
|
+
if (same(base, cursor)) return;
|
|
22183
|
+
base = cursor;
|
|
22184
|
+
notify2();
|
|
22185
|
+
},
|
|
22186
|
+
setOverride(cursor) {
|
|
22187
|
+
if (same(override, cursor)) return;
|
|
22188
|
+
override = cursor;
|
|
22189
|
+
notify2();
|
|
22190
|
+
},
|
|
22191
|
+
setPointer(x, y) {
|
|
22192
|
+
if (at && at.x === x && at.y === y) return;
|
|
22193
|
+
at = { x, y };
|
|
22194
|
+
if (override ?? base) notify2();
|
|
22195
|
+
},
|
|
22196
|
+
clearPointer() {
|
|
22197
|
+
if (at === null) return;
|
|
22198
|
+
at = null;
|
|
22199
|
+
notify2();
|
|
22200
|
+
},
|
|
22201
|
+
active() {
|
|
22202
|
+
return (override ?? base) !== null;
|
|
22203
|
+
},
|
|
22204
|
+
current() {
|
|
22205
|
+
const cursor = override ?? base;
|
|
22206
|
+
if (!cursor || !at) return null;
|
|
22207
|
+
return { cursor, at };
|
|
22208
|
+
},
|
|
22209
|
+
subscribe(fn) {
|
|
22210
|
+
subs.add(fn);
|
|
22211
|
+
return () => {
|
|
22212
|
+
subs.delete(fn);
|
|
22213
|
+
};
|
|
22214
|
+
}
|
|
22215
|
+
};
|
|
22216
|
+
}
|
|
22217
|
+
var PAINTED_CURSOR_LAYER_ID = "painted-cursor";
|
|
22218
|
+
var pathCache = /* @__PURE__ */ new Map();
|
|
22219
|
+
function pathFor(d) {
|
|
22220
|
+
let p = pathCache.get(d);
|
|
22221
|
+
if (p === void 0) {
|
|
22222
|
+
p = pathFromD(d);
|
|
22223
|
+
pathCache.set(d, p);
|
|
22224
|
+
}
|
|
22225
|
+
return p;
|
|
22226
|
+
}
|
|
22227
|
+
function commandFor2(op) {
|
|
22228
|
+
return {
|
|
22229
|
+
kind: "path",
|
|
22230
|
+
path: pathFor(op.d),
|
|
22231
|
+
...op.fill !== void 0 ? { fill: { color: op.fill } } : {},
|
|
22232
|
+
...op.stroke !== void 0 ? {
|
|
22233
|
+
stroke: {
|
|
22234
|
+
paint: { color: op.stroke.color },
|
|
22235
|
+
width: op.stroke.width,
|
|
22236
|
+
cap: "round",
|
|
22237
|
+
join: "round"
|
|
22238
|
+
}
|
|
22239
|
+
} : {}
|
|
22240
|
+
};
|
|
22241
|
+
}
|
|
22242
|
+
function createPaintedCursorLayer(state) {
|
|
22243
|
+
return {
|
|
22244
|
+
id: PAINTED_CURSOR_LAYER_ID,
|
|
22245
|
+
label: "Painted cursor",
|
|
22246
|
+
space: "screen",
|
|
22247
|
+
draw: (_data, view) => {
|
|
22248
|
+
const frame = state.current();
|
|
22249
|
+
if (!frame) return [];
|
|
22250
|
+
const { cursor, at } = frame;
|
|
22251
|
+
const glyph = GLYPHS[cursor.glyph];
|
|
22252
|
+
if (!glyph) return [];
|
|
22253
|
+
const scale2 = (view.scale.x + view.scale.y) / 2;
|
|
22254
|
+
const worldSized = cursor.worldRadius !== void 0;
|
|
22255
|
+
const size = worldSized ? cursorWorldSize(glyph, cursor.worldRadius, scale2) : cursor.size ?? 24;
|
|
22256
|
+
if (!(size > 0) || !Number.isFinite(size)) return [];
|
|
22257
|
+
const ops = cursorPaintOps(
|
|
22258
|
+
glyph,
|
|
22259
|
+
worldSized ? { lineWidthScale: chromeLineWidthScale(glyph, size) } : {}
|
|
22260
|
+
);
|
|
22261
|
+
const [a, b, c, d, e, f] = cursorPaintMatrix(glyph, {
|
|
22262
|
+
size,
|
|
22263
|
+
angle: cursor.angle,
|
|
22264
|
+
at
|
|
22265
|
+
});
|
|
22266
|
+
const transform = new Float32Array([a, b, 0, c, d, 0, e, f, 1]);
|
|
22267
|
+
const children = ops.map(commandFor2);
|
|
22268
|
+
return [{ kind: "group", transform, children }];
|
|
22269
|
+
}
|
|
22270
|
+
};
|
|
22271
|
+
}
|
|
21737
22272
|
function mat3ToRenderMatrix(m) {
|
|
21738
22273
|
return new Float32Array([m[0], m[1], 0, m[2], m[3], 0, m[4], m[5], 1]);
|
|
21739
22274
|
}
|
|
@@ -22103,11 +22638,11 @@ function resolveToolsCursor(tools, ctxBase) {
|
|
|
22103
22638
|
const id = tools.hotkeyEngaged ?? tools.active;
|
|
22104
22639
|
const tool = tools.registry[id];
|
|
22105
22640
|
if (!tool?.cursor) return void 0;
|
|
22106
|
-
if (typeof tool.cursor
|
|
22641
|
+
if (typeof tool.cursor !== "function") return resolveCursorTier(tool.cursor);
|
|
22107
22642
|
if (!ctxBase) return void 0;
|
|
22108
22643
|
try {
|
|
22109
22644
|
const base = ctxBase();
|
|
22110
|
-
return tool.cursor({ ...base, scratch: null });
|
|
22645
|
+
return resolveCursorTier(tool.cursor({ ...base, scratch: null }));
|
|
22111
22646
|
} catch {
|
|
22112
22647
|
return void 0;
|
|
22113
22648
|
}
|
|
@@ -22272,6 +22807,14 @@ function CanvasInner(props, ref) {
|
|
|
22272
22807
|
viewSubsRef.current.delete(fn);
|
|
22273
22808
|
};
|
|
22274
22809
|
}, []);
|
|
22810
|
+
const paintedCursor = useMemo(() => createPaintedCursorState(), []);
|
|
22811
|
+
const paintedCursorLayer = useMemo(
|
|
22812
|
+
() => createPaintedCursorLayer(paintedCursor),
|
|
22813
|
+
[paintedCursor]
|
|
22814
|
+
);
|
|
22815
|
+
useEffect(() => paintedCursor.subscribe(() => {
|
|
22816
|
+
requestRedraw();
|
|
22817
|
+
}), [paintedCursor, requestRedraw]);
|
|
22275
22818
|
useImperativeHandle(ref, () => ({
|
|
22276
22819
|
// Named rather than read off `canvasRef` so the handle rebuilds when a
|
|
22277
22820
|
// detached surface's input element arrives, which is a render later.
|
|
@@ -22284,7 +22827,8 @@ function CanvasInner(props, ref) {
|
|
|
22284
22827
|
getView,
|
|
22285
22828
|
setView,
|
|
22286
22829
|
subscribeView,
|
|
22287
|
-
getPaintedVersion
|
|
22830
|
+
getPaintedVersion,
|
|
22831
|
+
paintedCursor
|
|
22288
22832
|
}), [
|
|
22289
22833
|
canvasRef,
|
|
22290
22834
|
ownCanvasRef,
|
|
@@ -22298,7 +22842,8 @@ function CanvasInner(props, ref) {
|
|
|
22298
22842
|
getView,
|
|
22299
22843
|
setView,
|
|
22300
22844
|
subscribeView,
|
|
22301
|
-
getPaintedVersion
|
|
22845
|
+
getPaintedVersion,
|
|
22846
|
+
paintedCursor
|
|
22302
22847
|
]);
|
|
22303
22848
|
const glRendererRef = useRef(null);
|
|
22304
22849
|
const layerCacheRef = useRef(/* @__PURE__ */ new Map());
|
|
@@ -22562,8 +23107,16 @@ function CanvasInner(props, ref) {
|
|
|
22562
23107
|
const layersWithDebug = useMemo(() => {
|
|
22563
23108
|
const withViews = viewRegistry ? [...layers, ...viewRegistry.list().map((r) => r.layer)] : layers;
|
|
22564
23109
|
const base = debugSink && resolvedDebugConfig ? [...withViews, createDebugOverlayLayer({ sink: debugSink, config: resolvedDebugConfig })] : withViews;
|
|
22565
|
-
return [...base, ...extrasRef.current];
|
|
22566
|
-
}, [
|
|
23110
|
+
return [...base, ...extrasRef.current, paintedCursorLayer];
|
|
23111
|
+
}, [
|
|
23112
|
+
layers,
|
|
23113
|
+
debugSink,
|
|
23114
|
+
resolvedDebugConfig,
|
|
23115
|
+
extrasVersion,
|
|
23116
|
+
viewRegistry,
|
|
23117
|
+
viewRegistryVersion,
|
|
23118
|
+
paintedCursorLayer
|
|
23119
|
+
]);
|
|
22567
23120
|
const shaderIdKey = shaders?.map((h) => h.id).join("|") ?? "";
|
|
22568
23121
|
const paintInputsRef = useRef({
|
|
22569
23122
|
layers: layersWithDebug,
|
|
@@ -22685,8 +23238,14 @@ function CanvasInner(props, ref) {
|
|
|
22685
23238
|
if (!renderer) return;
|
|
22686
23239
|
registerShadersOnRenderer(renderer, shaders);
|
|
22687
23240
|
}, [shaderIdKey]);
|
|
22688
|
-
const
|
|
23241
|
+
const toolsCursorTier = tools ? resolveToolsCursor(tools, toolsCtxBase) : void 0;
|
|
23242
|
+
const toolsCursor = toolsCursorTier === void 0 ? void 0 : toolsCursorTier.kind === "css" ? toolsCursorTier.css : "none";
|
|
22689
23243
|
const effectiveStyle = toolsCursor ? { ...style, cursor: toolsCursor } : style;
|
|
23244
|
+
const toolsPainted = toolsCursorTier?.kind === "painted" ? toolsCursorTier : null;
|
|
23245
|
+
const toolsPaintedKey = toolsPainted ? `${toolsPainted.glyph}|${toolsPainted.angle}|${toolsPainted.size}|${toolsPainted.worldRadius}` : "";
|
|
23246
|
+
useEffect(() => {
|
|
23247
|
+
paintedCursor.setBase(toolsPainted);
|
|
23248
|
+
}, [paintedCursor, toolsPaintedKey]);
|
|
22690
23249
|
const layersForMoveRef = useRef(layersWithDebug);
|
|
22691
23250
|
layersForMoveRef.current = layersWithDebug;
|
|
22692
23251
|
useEffect(() => {
|
|
@@ -24006,10 +24565,16 @@ function createCornerResizeAffordance(opts = {}) {
|
|
|
24006
24565
|
hitKind: c.kind,
|
|
24007
24566
|
// Diagonal by fixed-corner parity: a matched-axis anchor (min-min /
|
|
24008
24567
|
// max-max fixed) means the dragged corner sits on the ↘ diagonal;
|
|
24009
|
-
// mixed axes sit on the ↗ diagonal.
|
|
24010
|
-
//
|
|
24011
|
-
//
|
|
24012
|
-
|
|
24568
|
+
// mixed axes sit on the ↗ diagonal. The glyph is horizontal at angle
|
|
24569
|
+
// 0, so the diagonal is a half-quarter-turn either way, plus the
|
|
24570
|
+
// target's own rotation. The keyword is the fallback rather than the
|
|
24571
|
+
// answer: CSS has four of them, which cannot express a target
|
|
24572
|
+
// rotated to anything but a multiple of 45°.
|
|
24573
|
+
cursor: {
|
|
24574
|
+
glyph: "resize",
|
|
24575
|
+
angle: (c.anchor.x === c.anchor.y ? Math.PI / 4 : -Math.PI / 4) + angleOf(xf),
|
|
24576
|
+
fallback: c.anchor.x === c.anchor.y ? "nwse-resize" : "nesw-resize"
|
|
24577
|
+
},
|
|
24013
24578
|
bind: () => ({
|
|
24014
24579
|
initialScratch: {
|
|
24015
24580
|
anchor: c.anchor,
|
|
@@ -27946,6 +28511,10 @@ function GestureDispatcherMounter({
|
|
|
27946
28511
|
const requestRedraw = useCallback(() => {
|
|
27947
28512
|
canvasApiRef?.current?.requestRedraw?.();
|
|
27948
28513
|
}, [canvasApiRef]);
|
|
28514
|
+
const paintedCursor = useCallback(
|
|
28515
|
+
() => canvasApiRef?.current?.paintedCursor,
|
|
28516
|
+
[canvasApiRef]
|
|
28517
|
+
);
|
|
27949
28518
|
const views = useMemo(() => {
|
|
27950
28519
|
if (!viewRegistry) return void 0;
|
|
27951
28520
|
return {
|
|
@@ -27964,6 +28533,7 @@ function GestureDispatcherMounter({
|
|
|
27964
28533
|
dispatcher,
|
|
27965
28534
|
clientToWorld: clientToWorld2,
|
|
27966
28535
|
requestRedraw,
|
|
28536
|
+
paintedCursor,
|
|
27967
28537
|
getRuleCtx,
|
|
27968
28538
|
onDoubleClick,
|
|
27969
28539
|
...views ? { views } : {}
|
|
@@ -28816,5 +29386,5 @@ function oklchToOklab(L, C, h) {
|
|
|
28816
29386
|
}
|
|
28817
29387
|
|
|
28818
29388
|
export { ArrowIcon, EllipseIcon, FALLBACK_FIT_VIEW, LineIcon, MinimapCanvas, PATH_C, PATH_L, PATH_M, PATH_Q, PATH_Z, PathBuilder, PencilIcon, RectIcon, SCRIPT_METRICS, SceneCanvas, SceneViewCanvas, SelectIcon, TextIcon, UnknownIcon, WeaselProvider, asNodeId, boundsOfPath, buildSceneViewCommands, computeFitView, computeIndicatorCommand, createScene, eligibleContribution, ellipsePath, evaluateEnabled, getMarker, getPaintKind, isBuiltinToolPref, linePath, markerDrawCommands, oklabToSrgbU8, oklchToOklab, rectPath, renderSceneToCanvas, renderSceneToPixels, resolveStrokeWidth, rgbaToHex, sceneFromJSON, textCommand, tileGeometry, useActionsRegistry, useActiveToolContext, useOptionalDepRegistry, useVisibleRaf };
|
|
28819
|
-
//# sourceMappingURL=chunk-
|
|
28820
|
-
//# sourceMappingURL=chunk-
|
|
29389
|
+
//# sourceMappingURL=chunk-7VW3S44V.js.map
|
|
29390
|
+
//# sourceMappingURL=chunk-7VW3S44V.js.map
|