@weasel-js/labkit 1.4.0-pre.1 → 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/dist/_dts/{CanvasStackContext-LnCfqNBA.d.ts → CanvasStackContext-D6M0o8cQ.d.ts} +1 -1
- package/dist/_dts/{frac-C-2c72Ij.d.ts → frac-QS7XzvpG.d.ts} +2 -2
- 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 +6 -6
- 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-QB5SM4BM.js → chunk-4AMN4MMB.js} +5 -5
- package/dist/{chunk-QB5SM4BM.js.map → chunk-4AMN4MMB.js.map} +1 -1
- package/dist/{chunk-L5QJOOLV.js → chunk-7VW3S44V.js} +512 -56
- package/dist/chunk-7VW3S44V.js.map +1 -0
- package/dist/{chunk-ESIQNQ6K.js → chunk-B5VWJBWM.js} +12 -6
- package/dist/chunk-B5VWJBWM.js.map +1 -0
- package/dist/{chunk-RBGKL7NF.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-HHGVISVZ.js → chunk-QR5V3AFG.js} +6 -4
- package/dist/chunk-QR5V3AFG.js.map +1 -0
- package/dist/{chunk-6OEYTYML.js → chunk-UD7TEHZT.js} +15 -15
- package/dist/chunk-UD7TEHZT.js.map +1 -0
- package/dist/{chunk-HMFODCOX.js → chunk-VHFQKAUL.js} +3 -3
- package/dist/{chunk-HMFODCOX.js.map → chunk-VHFQKAUL.js.map} +1 -1
- package/dist/{chunk-TO2FUOKF.js → chunk-W3KSUXXR.js} +16 -13
- package/dist/chunk-W3KSUXXR.js.map +1 -0
- package/dist/{chunk-AE5CNVRU.js → chunk-XCBCZEBO.js} +3 -3
- package/dist/{chunk-AE5CNVRU.js.map → chunk-XCBCZEBO.js.map} +1 -1
- package/dist/{chunk-E2UQVZ44.js → chunk-Y2HK44TG.js} +3 -3
- package/dist/{chunk-E2UQVZ44.js.map → chunk-Y2HK44TG.js.map} +1 -1
- package/dist/{chunk-M75ZU6ZZ.js → chunk-YQGQUBKA.js} +3 -3
- package/dist/{chunk-M75ZU6ZZ.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 +55 -12
- package/dist/index.js +306 -159
- 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/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/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-6OEYTYML.js.map +0 -1
- package/dist/chunk-ESIQNQ6K.js.map +0 -1
- package/dist/chunk-HHGVISVZ.js.map +0 -1
- package/dist/chunk-L5QJOOLV.js.map +0 -1
- package/dist/chunk-RBGKL7NF.js.map +0 -1
- package/dist/chunk-TO2FUOKF.js.map +0 -1
- package/dist/chunk-XJ6N32QP.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());
|
|
@@ -3845,30 +3845,65 @@ function eligibleContribution(reg, entry) {
|
|
|
3845
3845
|
var CURSOR_INK = "#141418";
|
|
3846
3846
|
var CURSOR_HALO = "#ffffff";
|
|
3847
3847
|
var CURSOR_HALO_WIDTH = 2.6;
|
|
3848
|
+
var CURSOR_ANGLE_STEPS = 16;
|
|
3848
3849
|
var CURSOR_MAX_CSS_PX = 128;
|
|
3849
|
-
function
|
|
3850
|
+
function halo(p, k) {
|
|
3850
3851
|
switch (p.role) {
|
|
3851
3852
|
case "ink":
|
|
3852
3853
|
case "accent":
|
|
3853
|
-
return
|
|
3854
|
+
return { d: p.d, fill: CURSOR_HALO, stroke: { color: CURSOR_HALO, width: CURSOR_HALO_WIDTH * k } };
|
|
3854
3855
|
case "stroke":
|
|
3855
|
-
return
|
|
3856
|
+
return { d: p.d, stroke: { color: CURSOR_HALO, width: (p.width + CURSOR_HALO_WIDTH) * k } };
|
|
3856
3857
|
// A detail IS halo-coloured and sits on top of the ink; it has no halo.
|
|
3857
3858
|
case "detail":
|
|
3858
|
-
return
|
|
3859
|
+
return null;
|
|
3859
3860
|
}
|
|
3860
3861
|
}
|
|
3861
|
-
function
|
|
3862
|
+
function ink(p, k) {
|
|
3862
3863
|
switch (p.role) {
|
|
3863
3864
|
case "ink":
|
|
3864
|
-
return
|
|
3865
|
+
return { d: p.d, fill: CURSOR_INK };
|
|
3865
3866
|
case "stroke":
|
|
3866
|
-
return
|
|
3867
|
+
return { d: p.d, stroke: { color: CURSOR_INK, width: p.width * k } };
|
|
3867
3868
|
case "detail":
|
|
3868
|
-
return
|
|
3869
|
+
return { d: p.d, stroke: { color: CURSOR_HALO, width: p.width * k } };
|
|
3869
3870
|
case "accent":
|
|
3870
|
-
return
|
|
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);
|
|
3871
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}/>`;
|
|
3872
3907
|
}
|
|
3873
3908
|
function bakeCursor(glyph, opts = {}) {
|
|
3874
3909
|
const size = opts.size ?? 24;
|
|
@@ -3877,10 +3912,18 @@ function bakeCursor(glyph, opts = {}) {
|
|
|
3877
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.`
|
|
3878
3913
|
);
|
|
3879
3914
|
}
|
|
3880
|
-
const
|
|
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>`;
|
|
3881
3920
|
const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="${size}" height="${size}" viewBox="0 0 ${glyph.box} ${glyph.box}">${body}</svg>`;
|
|
3882
|
-
const
|
|
3883
|
-
const
|
|
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);
|
|
3884
3927
|
const uri = `data:image/svg+xml,${encodeURIComponent(svg)}`;
|
|
3885
3928
|
return `url("${uri}") ${hx} ${hy}, ${opts.fallback ?? "default"}`;
|
|
3886
3929
|
}
|
|
@@ -3937,23 +3980,263 @@ var GLYPHS = {
|
|
|
3937
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"
|
|
3938
3981
|
}
|
|
3939
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
|
+
]
|
|
3940
4199
|
}
|
|
3941
4200
|
};
|
|
3942
4201
|
var cache2 = /* @__PURE__ */ new Map();
|
|
3943
4202
|
function cursorFor(name, opts = {}) {
|
|
3944
4203
|
const size = opts.size ?? 24;
|
|
3945
4204
|
const fallback = opts.fallback ?? "default";
|
|
3946
|
-
const
|
|
4205
|
+
const step = quantizeCursorAngle(opts.angle ?? 0);
|
|
4206
|
+
const key = `${name}|${size}|${step}|${fallback}`;
|
|
3947
4207
|
const hit = cache2.get(key);
|
|
3948
4208
|
if (hit !== void 0) return hit;
|
|
3949
4209
|
const glyph = GLYPHS[name];
|
|
3950
4210
|
if (glyph === void 0) {
|
|
3951
4211
|
throw new Error(`unknown cursor glyph: ${String(name)}`);
|
|
3952
4212
|
}
|
|
3953
|
-
const css = bakeCursor(glyph, { size, fallback });
|
|
4213
|
+
const css = bakeCursor(glyph, { size, fallback, angle: opts.angle ?? 0 });
|
|
3954
4214
|
cache2.set(key, css);
|
|
3955
4215
|
return css;
|
|
3956
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
|
+
}
|
|
3957
4240
|
|
|
3958
4241
|
// ../history/dist/index.js
|
|
3959
4242
|
var RESUMERS = /* @__PURE__ */ new WeakMap();
|
|
@@ -4377,7 +4660,7 @@ function serialToEntry(se, custom, logger) {
|
|
|
4377
4660
|
};
|
|
4378
4661
|
}
|
|
4379
4662
|
|
|
4380
|
-
// ../core/dist/chunk-
|
|
4663
|
+
// ../core/dist/chunk-HYJL7OOJ.js
|
|
4381
4664
|
function worldToScreen(worldX, worldY, view) {
|
|
4382
4665
|
return [view.panX + worldX * view.zoom.x, view.panY + worldY * view.zoom.y];
|
|
4383
4666
|
}
|
|
@@ -9882,8 +10165,8 @@ function runLayoutPass(scratch, moveCtx) {
|
|
|
9882
10165
|
for (const [cid, pose] of srcLayout.childPoses(srcContainer, srcChildren)) {
|
|
9883
10166
|
const cur = composeWorldPose(poseAdapter, cid, pc.compose);
|
|
9884
10167
|
const next = pose;
|
|
9885
|
-
const
|
|
9886
|
-
if (
|
|
10168
|
+
const same2 = cur.x === next.x && cur.y === next.y && cur.width === next.width && cur.height === next.height;
|
|
10169
|
+
if (same2) continue;
|
|
9887
10170
|
sourceReflow.set(cid, pose);
|
|
9888
10171
|
const parent = scene.get(asNodeId(cid))?.parent ?? null;
|
|
9889
10172
|
scratch.previews.set(asNodeId(cid), rebaseLocalPose(poseAdapter, pose, parent, pc.compose, pc.decompose));
|
|
@@ -11237,6 +11520,11 @@ var cloneAction = {
|
|
|
11237
11520
|
id: "clone",
|
|
11238
11521
|
label: "Clone",
|
|
11239
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",
|
|
11240
11528
|
eligible: { capability: ["edits-page", "creates-selection"] },
|
|
11241
11529
|
requires: ["selection", "scene", "applyOps"],
|
|
11242
11530
|
invoker: {
|
|
@@ -15627,7 +15915,7 @@ function createDispatcher(opts) {
|
|
|
15627
15915
|
}
|
|
15628
15916
|
function inFlightCursor() {
|
|
15629
15917
|
for (const action of inFlightActions.values()) {
|
|
15630
|
-
const cursor = action.activeCursor ?? action.cursor;
|
|
15918
|
+
const cursor = resolveCursor(action.activeCursor ?? action.cursor);
|
|
15631
15919
|
if (cursor) return cursor;
|
|
15632
15920
|
}
|
|
15633
15921
|
return null;
|
|
@@ -15849,7 +16137,7 @@ function computeMultiTouchGeometry(positions) {
|
|
|
15849
16137
|
return { centroid, spread };
|
|
15850
16138
|
}
|
|
15851
16139
|
function useGestureDispatcher(opts) {
|
|
15852
|
-
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;
|
|
15853
16141
|
const onDoubleClickRef = useRef(onDoubleClick);
|
|
15854
16142
|
onDoubleClickRef.current = onDoubleClick;
|
|
15855
16143
|
const activeTool = useActiveToolContext();
|
|
@@ -15898,6 +16186,8 @@ function useGestureDispatcher(opts) {
|
|
|
15898
16186
|
];
|
|
15899
16187
|
const requestRedrawRef = useRef(requestRedraw);
|
|
15900
16188
|
requestRedrawRef.current = requestRedraw;
|
|
16189
|
+
const paintedCursorRef = useRef(paintedCursor);
|
|
16190
|
+
paintedCursorRef.current = paintedCursor;
|
|
15901
16191
|
const lastClickRef = useRef(null);
|
|
15902
16192
|
const prevActiveRef = useRef(activeTool.active);
|
|
15903
16193
|
useEffect(() => {
|
|
@@ -16237,20 +16527,39 @@ function useGestureDispatcher(opts) {
|
|
|
16237
16527
|
let lastHover = null;
|
|
16238
16528
|
let cursorOverridden = false;
|
|
16239
16529
|
const clearHoverCursor = () => {
|
|
16530
|
+
paintedCursorRef.current?.()?.setOverride(null);
|
|
16240
16531
|
if (cursorOverridden && canvas) {
|
|
16241
16532
|
canvas.style.cursor = "";
|
|
16242
16533
|
cursorOverridden = false;
|
|
16243
16534
|
}
|
|
16244
16535
|
};
|
|
16245
|
-
const applyHoverCursor = (
|
|
16246
|
-
|
|
16247
|
-
|
|
16248
|
-
cursorOverridden = true;
|
|
16249
|
-
} else {
|
|
16536
|
+
const applyHoverCursor = (spec) => {
|
|
16537
|
+
const tier = spec === null ? null : resolveCursorTier(spec);
|
|
16538
|
+
if (!tier || !canvas) {
|
|
16250
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) {
|
|
16546
|
+
clearHoverCursor();
|
|
16547
|
+
return;
|
|
16251
16548
|
}
|
|
16549
|
+
canvas.style.cursor = cursor;
|
|
16550
|
+
cursorOverridden = true;
|
|
16252
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
|
+
}
|
|
16253
16558
|
function refreshHoverCursor() {
|
|
16559
|
+
resolveHoverCursor();
|
|
16560
|
+
pushPaintedPointer();
|
|
16561
|
+
}
|
|
16562
|
+
function resolveHoverCursor() {
|
|
16254
16563
|
if (!canvas || !lastHover) return;
|
|
16255
16564
|
if (activePointers.size > 0 || dispatcherNow().inFlight().size > 0) {
|
|
16256
16565
|
applyHoverCursor(dispatcherNow().inFlightCursor());
|
|
@@ -16302,6 +16611,7 @@ function useGestureDispatcher(opts) {
|
|
|
16302
16611
|
};
|
|
16303
16612
|
const onHoverPointerLeave = () => {
|
|
16304
16613
|
lastHover = null;
|
|
16614
|
+
paintedCursorRef.current?.()?.clearPointer();
|
|
16305
16615
|
clearHoverCursor();
|
|
16306
16616
|
};
|
|
16307
16617
|
const onPointerUp = (e) => {
|
|
@@ -17811,7 +18121,7 @@ function validateId(id, kind) {
|
|
|
17811
18121
|
}
|
|
17812
18122
|
function defineTool(def) {
|
|
17813
18123
|
validateId(def.id, "tool");
|
|
17814
|
-
const
|
|
18124
|
+
const resolveCursor3 = (ctx) => {
|
|
17815
18125
|
if (def.cursor == null) return "";
|
|
17816
18126
|
return typeof def.cursor === "function" ? def.cursor(ctx) : def.cursor;
|
|
17817
18127
|
};
|
|
@@ -17829,7 +18139,7 @@ function defineTool(def) {
|
|
|
17829
18139
|
onActivate: def.onActivate,
|
|
17830
18140
|
onDeactivate: def.onDeactivate,
|
|
17831
18141
|
initScratch: def.initScratch ?? (() => null),
|
|
17832
|
-
cursor:
|
|
18142
|
+
cursor: resolveCursor3,
|
|
17833
18143
|
bindings: def.bindings,
|
|
17834
18144
|
overlay: def.overlay,
|
|
17835
18145
|
overlayPosition: def.overlayPosition
|
|
@@ -18829,10 +19139,10 @@ function findShapeInk(node, pose, ctx) {
|
|
|
18829
19139
|
function shapeCoversPoint(node, pose, x, y, opts = {}) {
|
|
18830
19140
|
const sil = findShapeSilhouette(node, pose, { derivedPath: opts.derivedPath });
|
|
18831
19141
|
if (sil === null) return true;
|
|
18832
|
-
const
|
|
19142
|
+
const ink2 = findShapeInk(node, pose, { scale: opts.scale }) ?? DEFAULT_INK;
|
|
18833
19143
|
const inside = pathContainsPoint(sil, x, y);
|
|
18834
|
-
if (
|
|
18835
|
-
const reach = (inside ?
|
|
19144
|
+
if (ink2.filled && inside) return true;
|
|
19145
|
+
const reach = (inside ? ink2.inset : ink2.outset) + (opts.tolerance ?? 0);
|
|
18836
19146
|
return reach > 0 && strokeHitTest(sil, x, y, reach);
|
|
18837
19147
|
}
|
|
18838
19148
|
var TEXT_PAINTER = {
|
|
@@ -19731,6 +20041,9 @@ function transformOf(state, targetId) {
|
|
|
19731
20041
|
identity: false
|
|
19732
20042
|
};
|
|
19733
20043
|
}
|
|
20044
|
+
function angleOf(xf) {
|
|
20045
|
+
return xf.identity ? 0 : Math.atan2(xf.sin, xf.cos);
|
|
20046
|
+
}
|
|
19734
20047
|
function localToWorld(xf, lx, ly) {
|
|
19735
20048
|
if (xf.identity) return { x: lx, y: ly };
|
|
19736
20049
|
const dx = lx - xf.cx;
|
|
@@ -20030,11 +20343,7 @@ var DEFAULT_PAINT = {
|
|
|
20030
20343
|
insetPx: 10
|
|
20031
20344
|
};
|
|
20032
20345
|
function createRotationAffordance(opts = {}) {
|
|
20033
|
-
const {
|
|
20034
|
-
bandPx = 24,
|
|
20035
|
-
paint = DEFAULT_PAINT,
|
|
20036
|
-
cursor = "grab"
|
|
20037
|
-
} = opts;
|
|
20346
|
+
const { bandPx = 24, paint = DEFAULT_PAINT, cursor } = opts;
|
|
20038
20347
|
const annulusPaint = (() => {
|
|
20039
20348
|
if (!paint) return null;
|
|
20040
20349
|
if ("paint" in paint) {
|
|
@@ -20072,7 +20381,14 @@ function createRotationAffordance(opts = {}) {
|
|
|
20072
20381
|
},
|
|
20073
20382
|
...annulusPaint ? { paint: annulusPaint } : {},
|
|
20074
20383
|
hitKind: "rotate-handle",
|
|
20075
|
-
|
|
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
|
+
},
|
|
20076
20392
|
bind: () => ({
|
|
20077
20393
|
initialScratch: {
|
|
20078
20394
|
targetId: target.id,
|
|
@@ -20551,7 +20867,7 @@ function useRectTool() {
|
|
|
20551
20867
|
id: "rect",
|
|
20552
20868
|
capabilities: ["creates-shapes"],
|
|
20553
20869
|
hookName: "useRectTool",
|
|
20554
|
-
cursor: "crosshair",
|
|
20870
|
+
cursor: cursorFor("crosshairRect", { fallback: "crosshair" }),
|
|
20555
20871
|
presentation: {
|
|
20556
20872
|
label: "Rectangle",
|
|
20557
20873
|
icon: createElement(RectIcon),
|
|
@@ -20577,7 +20893,7 @@ function useEllipseTool() {
|
|
|
20577
20893
|
id: "ellipse",
|
|
20578
20894
|
capabilities: ["creates-shapes"],
|
|
20579
20895
|
hookName: "useEllipseTool",
|
|
20580
|
-
cursor: "crosshair",
|
|
20896
|
+
cursor: cursorFor("crosshairEllipse", { fallback: "crosshair" }),
|
|
20581
20897
|
presentation: {
|
|
20582
20898
|
label: "Ellipse",
|
|
20583
20899
|
group: "shape",
|
|
@@ -20600,7 +20916,7 @@ function useLineTool() {
|
|
|
20600
20916
|
id: "line",
|
|
20601
20917
|
capabilities: ["creates-shapes"],
|
|
20602
20918
|
hookName: "useLineTool",
|
|
20603
|
-
cursor: "crosshair",
|
|
20919
|
+
cursor: cursorFor("crosshairLine", { fallback: "crosshair" }),
|
|
20604
20920
|
presentation: {
|
|
20605
20921
|
label: "Line",
|
|
20606
20922
|
group: "shape",
|
|
@@ -20711,7 +21027,7 @@ function usePolygonTool(options = {}) {
|
|
|
20711
21027
|
id: "polygon",
|
|
20712
21028
|
capabilities: ["creates-shapes"],
|
|
20713
21029
|
hookName: "usePolygonTool",
|
|
20714
|
-
cursor: "crosshair",
|
|
21030
|
+
cursor: cursorFor("crosshairPolygon", { fallback: "crosshair" }),
|
|
20715
21031
|
// Registered by <ToolActionsMounter>, inside the ActionsProvider —
|
|
20716
21032
|
// see `ToolDef.actions` for why the hook can't register it itself.
|
|
20717
21033
|
actions: [adjustSidesAction],
|
|
@@ -20811,7 +21127,7 @@ function useStarTool(options = {}) {
|
|
|
20811
21127
|
id: "star",
|
|
20812
21128
|
capabilities: ["creates-shapes"],
|
|
20813
21129
|
hookName: "useStarTool",
|
|
20814
|
-
cursor: "crosshair",
|
|
21130
|
+
cursor: cursorFor("crosshairStar", { fallback: "crosshair" }),
|
|
20815
21131
|
// Registered by <ToolActionsMounter>, inside the ActionsProvider —
|
|
20816
21132
|
// see `ToolDef.actions` for why the hook can't register it itself.
|
|
20817
21133
|
actions: [adjustPointsAction],
|
|
@@ -21848,6 +22164,111 @@ function buildSceneTree(adapter, drawOne, view, forLayer, derivedPathOf) {
|
|
|
21848
22164
|
}
|
|
21849
22165
|
return out;
|
|
21850
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
|
+
}
|
|
21851
22272
|
function mat3ToRenderMatrix(m) {
|
|
21852
22273
|
return new Float32Array([m[0], m[1], 0, m[2], m[3], 0, m[4], m[5], 1]);
|
|
21853
22274
|
}
|
|
@@ -22217,11 +22638,11 @@ function resolveToolsCursor(tools, ctxBase) {
|
|
|
22217
22638
|
const id = tools.hotkeyEngaged ?? tools.active;
|
|
22218
22639
|
const tool = tools.registry[id];
|
|
22219
22640
|
if (!tool?.cursor) return void 0;
|
|
22220
|
-
if (typeof tool.cursor
|
|
22641
|
+
if (typeof tool.cursor !== "function") return resolveCursorTier(tool.cursor);
|
|
22221
22642
|
if (!ctxBase) return void 0;
|
|
22222
22643
|
try {
|
|
22223
22644
|
const base = ctxBase();
|
|
22224
|
-
return tool.cursor({ ...base, scratch: null });
|
|
22645
|
+
return resolveCursorTier(tool.cursor({ ...base, scratch: null }));
|
|
22225
22646
|
} catch {
|
|
22226
22647
|
return void 0;
|
|
22227
22648
|
}
|
|
@@ -22386,6 +22807,14 @@ function CanvasInner(props, ref) {
|
|
|
22386
22807
|
viewSubsRef.current.delete(fn);
|
|
22387
22808
|
};
|
|
22388
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]);
|
|
22389
22818
|
useImperativeHandle(ref, () => ({
|
|
22390
22819
|
// Named rather than read off `canvasRef` so the handle rebuilds when a
|
|
22391
22820
|
// detached surface's input element arrives, which is a render later.
|
|
@@ -22398,7 +22827,8 @@ function CanvasInner(props, ref) {
|
|
|
22398
22827
|
getView,
|
|
22399
22828
|
setView,
|
|
22400
22829
|
subscribeView,
|
|
22401
|
-
getPaintedVersion
|
|
22830
|
+
getPaintedVersion,
|
|
22831
|
+
paintedCursor
|
|
22402
22832
|
}), [
|
|
22403
22833
|
canvasRef,
|
|
22404
22834
|
ownCanvasRef,
|
|
@@ -22412,7 +22842,8 @@ function CanvasInner(props, ref) {
|
|
|
22412
22842
|
getView,
|
|
22413
22843
|
setView,
|
|
22414
22844
|
subscribeView,
|
|
22415
|
-
getPaintedVersion
|
|
22845
|
+
getPaintedVersion,
|
|
22846
|
+
paintedCursor
|
|
22416
22847
|
]);
|
|
22417
22848
|
const glRendererRef = useRef(null);
|
|
22418
22849
|
const layerCacheRef = useRef(/* @__PURE__ */ new Map());
|
|
@@ -22676,8 +23107,16 @@ function CanvasInner(props, ref) {
|
|
|
22676
23107
|
const layersWithDebug = useMemo(() => {
|
|
22677
23108
|
const withViews = viewRegistry ? [...layers, ...viewRegistry.list().map((r) => r.layer)] : layers;
|
|
22678
23109
|
const base = debugSink && resolvedDebugConfig ? [...withViews, createDebugOverlayLayer({ sink: debugSink, config: resolvedDebugConfig })] : withViews;
|
|
22679
|
-
return [...base, ...extrasRef.current];
|
|
22680
|
-
}, [
|
|
23110
|
+
return [...base, ...extrasRef.current, paintedCursorLayer];
|
|
23111
|
+
}, [
|
|
23112
|
+
layers,
|
|
23113
|
+
debugSink,
|
|
23114
|
+
resolvedDebugConfig,
|
|
23115
|
+
extrasVersion,
|
|
23116
|
+
viewRegistry,
|
|
23117
|
+
viewRegistryVersion,
|
|
23118
|
+
paintedCursorLayer
|
|
23119
|
+
]);
|
|
22681
23120
|
const shaderIdKey = shaders?.map((h) => h.id).join("|") ?? "";
|
|
22682
23121
|
const paintInputsRef = useRef({
|
|
22683
23122
|
layers: layersWithDebug,
|
|
@@ -22799,8 +23238,14 @@ function CanvasInner(props, ref) {
|
|
|
22799
23238
|
if (!renderer) return;
|
|
22800
23239
|
registerShadersOnRenderer(renderer, shaders);
|
|
22801
23240
|
}, [shaderIdKey]);
|
|
22802
|
-
const
|
|
23241
|
+
const toolsCursorTier = tools ? resolveToolsCursor(tools, toolsCtxBase) : void 0;
|
|
23242
|
+
const toolsCursor = toolsCursorTier === void 0 ? void 0 : toolsCursorTier.kind === "css" ? toolsCursorTier.css : "none";
|
|
22803
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]);
|
|
22804
23249
|
const layersForMoveRef = useRef(layersWithDebug);
|
|
22805
23250
|
layersForMoveRef.current = layersWithDebug;
|
|
22806
23251
|
useEffect(() => {
|
|
@@ -24120,10 +24565,16 @@ function createCornerResizeAffordance(opts = {}) {
|
|
|
24120
24565
|
hitKind: c.kind,
|
|
24121
24566
|
// Diagonal by fixed-corner parity: a matched-axis anchor (min-min /
|
|
24122
24567
|
// max-max fixed) means the dragged corner sits on the ↘ diagonal;
|
|
24123
|
-
// mixed axes sit on the ↗ diagonal.
|
|
24124
|
-
//
|
|
24125
|
-
//
|
|
24126
|
-
|
|
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
|
+
},
|
|
24127
24578
|
bind: () => ({
|
|
24128
24579
|
initialScratch: {
|
|
24129
24580
|
anchor: c.anchor,
|
|
@@ -28060,6 +28511,10 @@ function GestureDispatcherMounter({
|
|
|
28060
28511
|
const requestRedraw = useCallback(() => {
|
|
28061
28512
|
canvasApiRef?.current?.requestRedraw?.();
|
|
28062
28513
|
}, [canvasApiRef]);
|
|
28514
|
+
const paintedCursor = useCallback(
|
|
28515
|
+
() => canvasApiRef?.current?.paintedCursor,
|
|
28516
|
+
[canvasApiRef]
|
|
28517
|
+
);
|
|
28063
28518
|
const views = useMemo(() => {
|
|
28064
28519
|
if (!viewRegistry) return void 0;
|
|
28065
28520
|
return {
|
|
@@ -28078,6 +28533,7 @@ function GestureDispatcherMounter({
|
|
|
28078
28533
|
dispatcher,
|
|
28079
28534
|
clientToWorld: clientToWorld2,
|
|
28080
28535
|
requestRedraw,
|
|
28536
|
+
paintedCursor,
|
|
28081
28537
|
getRuleCtx,
|
|
28082
28538
|
onDoubleClick,
|
|
28083
28539
|
...views ? { views } : {}
|
|
@@ -28930,5 +29386,5 @@ function oklchToOklab(L, C, h) {
|
|
|
28930
29386
|
}
|
|
28931
29387
|
|
|
28932
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 };
|
|
28933
|
-
//# sourceMappingURL=chunk-
|
|
28934
|
-
//# sourceMappingURL=chunk-
|
|
29389
|
+
//# sourceMappingURL=chunk-7VW3S44V.js.map
|
|
29390
|
+
//# sourceMappingURL=chunk-7VW3S44V.js.map
|