@weasel-js/labkit 1.4.0 → 1.4.1
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-D6M0o8cQ.d.ts → CanvasStackContext-BIRUVVGH.d.ts} +1 -1
- package/dist/_dts/PrefsForm.d-CgxUequc.d.ts +20 -0
- package/dist/_dts/{frac-QS7XzvpG.d.ts → frac-X7mWgd7y.d.ts} +9 -3
- package/dist/_dts/{index-B2X21G1c.d.ts → index-FEa1MudK.d.ts} +1 -1
- package/dist/_dts/{types-C1Zw7s5P.d.ts → types-lg4TSCb2.d.ts} +2 -1
- package/dist/_dts/weasel-canvas-FJTFi3ZZ.d.ts +5041 -0
- package/dist/canvas/index.d.ts +15 -15
- package/dist/canvas/index.js +2 -2
- package/dist/chrome/index.d.ts +5 -5
- package/dist/chrome/index.js +5 -5
- package/dist/{chunk-W3KSUXXR.js → chunk-53AZ2O2N.js} +4 -4
- package/dist/{chunk-W3KSUXXR.js.map → chunk-53AZ2O2N.js.map} +1 -1
- package/dist/{chunk-4AMN4MMB.js → chunk-7TRFMIWX.js} +53 -39
- package/dist/chunk-7TRFMIWX.js.map +1 -0
- package/dist/{chunk-UD7TEHZT.js → chunk-BMQWLKOL.js} +6 -6
- package/dist/{chunk-UD7TEHZT.js.map → chunk-BMQWLKOL.js.map} +1 -1
- package/dist/{chunk-YQGQUBKA.js → chunk-D7QIPGEB.js} +3 -3
- package/dist/{chunk-YQGQUBKA.js.map → chunk-D7QIPGEB.js.map} +1 -1
- package/dist/{chunk-7VW3S44V.js → chunk-DG2IFMLA.js} +802 -222
- package/dist/chunk-DG2IFMLA.js.map +1 -0
- package/dist/{chunk-LN6JDUGB.js → chunk-HXXTULDN.js} +2 -2
- package/dist/{chunk-LN6JDUGB.js.map → chunk-HXXTULDN.js.map} +1 -1
- package/dist/{chunk-L5WBGUVR.js → chunk-J6SBFZYT.js} +2131 -2174
- package/dist/chunk-J6SBFZYT.js.map +1 -0
- package/dist/{chunk-XCBCZEBO.js → chunk-MIT3ISW4.js} +37 -31
- package/dist/chunk-MIT3ISW4.js.map +1 -0
- package/dist/{chunk-QR5V3AFG.js → chunk-MSR7EVS6.js} +5 -5
- package/dist/{chunk-QR5V3AFG.js.map → chunk-MSR7EVS6.js.map} +1 -1
- package/dist/{chunk-B5VWJBWM.js → chunk-OFCBEZMU.js} +3 -3
- package/dist/{chunk-B5VWJBWM.js.map → chunk-OFCBEZMU.js.map} +1 -1
- package/dist/{chunk-VHFQKAUL.js → chunk-PP7ZWAMV.js} +83 -75
- package/dist/chunk-PP7ZWAMV.js.map +1 -0
- package/dist/{chunk-Y2HK44TG.js → chunk-RLOXQZW3.js} +3 -3
- package/dist/{chunk-Y2HK44TG.js.map → chunk-RLOXQZW3.js.map} +1 -1
- package/dist/controls/index.d.ts +4 -3
- package/dist/controls/index.js +3 -3
- package/dist/dragdrop/index.d.ts +4 -4
- package/dist/dragdrop/index.js +2 -2
- package/dist/index.d.ts +8 -71
- package/dist/index.js +21 -21
- package/dist/index.js.map +1 -1
- package/dist/job/index.js +1 -1
- package/dist/layers/index.d.ts +5 -5
- package/dist/layers/index.js +3 -3
- package/dist/loupe/index.d.ts +6 -12
- package/dist/loupe/index.js +2 -2
- package/dist/passthrough/weasel-canvas.d.ts +3 -343
- package/dist/passthrough/weasel-canvas.js +1 -1
- package/dist/passthrough/weasel-ui.d.ts +40 -3086
- package/dist/passthrough/weasel-ui.js +2 -2
- package/dist/primitives/index.js +4 -4
- package/dist/styles.css +10 -0
- package/dist/surface/index.js +2 -2
- package/dist/ui/layers/index.js +2 -2
- package/dist/undo/index.d.ts +5 -4
- package/package.json +8 -8
- package/src/canvas/CanvasStack.tsx +8 -13
- package/src/canvas/useOrbit.test.ts +93 -1
- package/src/canvas/useOrbit.ts +41 -34
- package/src/canvas/usePanZoom.test.ts +102 -1
- package/src/canvas/usePanZoom.ts +54 -36
- package/src/job/useJob.ts +1 -1
- package/src/lab/Workspace.tsx +1 -1
- package/src/layers/LayerList.test.tsx +72 -1
- package/src/layers/LayerList.tsx +40 -32
- package/src/primitives/FloatingPanel.test.tsx +82 -0
- package/src/primitives/FloatingPanel.tsx +59 -41
- package/dist/_dts/DrawCommand-B3bskUsC.d.ts +0 -564
- package/dist/_dts/PrefsForm-BkUJZx0A.d.ts +0 -204
- package/dist/_dts/fitViewToBounds-dZ2UDB6e.d.ts +0 -21
- package/dist/_dts/shapeKinds-Cx_rxwsa.d.ts +0 -87
- package/dist/_dts/types-C-gh9Ap-.d.ts +0 -695
- package/dist/chunk-4AMN4MMB.js.map +0 -1
- package/dist/chunk-7VW3S44V.js.map +0 -1
- package/dist/chunk-L5WBGUVR.js.map +0 -1
- package/dist/chunk-VHFQKAUL.js.map +0 -1
- package/dist/chunk-XCBCZEBO.js.map +0 -1
|
@@ -3,7 +3,7 @@ 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-TORKRNFY.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-TORKRNFY.js
|
|
291
291
|
var DepRegistryContext = createContext(null);
|
|
292
292
|
function DepRegistryProvider({ children }) {
|
|
293
293
|
const sourcesRef = useRef(/* @__PURE__ */ new Map());
|
|
@@ -437,6 +437,7 @@ function warnSharedScope() {
|
|
|
437
437
|
var ActionsContext = createContext(null);
|
|
438
438
|
function ActionsProvider({ children }) {
|
|
439
439
|
const actionsRef = useRef(/* @__PURE__ */ new Map());
|
|
440
|
+
const liveAction = (id) => actionsRef.current.get(id)?.at(-1);
|
|
440
441
|
const versionRef = useRef(0);
|
|
441
442
|
const cachedRef = useRef([]);
|
|
442
443
|
const cachedVerRef = useRef(-1);
|
|
@@ -451,7 +452,9 @@ function ActionsProvider({ children }) {
|
|
|
451
452
|
const snapshot = () => {
|
|
452
453
|
const v = versionRef.current;
|
|
453
454
|
if (cachedVerRef.current === v) return cachedRef.current;
|
|
454
|
-
const out = Object.freeze(
|
|
455
|
+
const out = Object.freeze(
|
|
456
|
+
Array.from(actionsRef.current.values(), (stack) => stack[stack.length - 1])
|
|
457
|
+
);
|
|
455
458
|
cachedRef.current = out;
|
|
456
459
|
cachedVerRef.current = v;
|
|
457
460
|
return out;
|
|
@@ -469,16 +472,23 @@ function ActionsProvider({ children }) {
|
|
|
469
472
|
register: (action) => {
|
|
470
473
|
validateActionId(action.id);
|
|
471
474
|
validateActionDefaultBinding(action);
|
|
472
|
-
actionsRef.current.
|
|
475
|
+
const stack = actionsRef.current.get(action.id);
|
|
476
|
+
if (stack) stack.push(action);
|
|
477
|
+
else actionsRef.current.set(action.id, [action]);
|
|
473
478
|
versionRef.current++;
|
|
474
479
|
notify2();
|
|
480
|
+
let released = false;
|
|
475
481
|
return () => {
|
|
482
|
+
if (released) return;
|
|
483
|
+
released = true;
|
|
476
484
|
const cur = actionsRef.current.get(action.id);
|
|
477
|
-
if (cur
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
485
|
+
if (!cur) return;
|
|
486
|
+
const i = cur.lastIndexOf(action);
|
|
487
|
+
if (i === -1) return;
|
|
488
|
+
cur.splice(i, 1);
|
|
489
|
+
if (cur.length === 0) actionsRef.current.delete(action.id);
|
|
490
|
+
versionRef.current++;
|
|
491
|
+
notify2();
|
|
482
492
|
};
|
|
483
493
|
},
|
|
484
494
|
unregister: (id) => {
|
|
@@ -489,7 +499,7 @@ function ActionsProvider({ children }) {
|
|
|
489
499
|
},
|
|
490
500
|
list: () => snapshot(),
|
|
491
501
|
trigger: (id, params) => {
|
|
492
|
-
const a =
|
|
502
|
+
const a = liveAction(id);
|
|
493
503
|
if (!a) return false;
|
|
494
504
|
try {
|
|
495
505
|
if (a.invoker && a.invoker.timing === "immediate") {
|
|
@@ -536,7 +546,7 @@ function ActionsProvider({ children }) {
|
|
|
536
546
|
const disp = dispatcherRef.current;
|
|
537
547
|
if (!disp) return null;
|
|
538
548
|
const r = wiredDepRegRef.current ?? depRegRef.current;
|
|
539
|
-
const a =
|
|
549
|
+
const a = liveAction(id);
|
|
540
550
|
const deps = !r ? {} : a?.requires ? buildDepsFromRequires(a, r) : {
|
|
541
551
|
selection: r.get("selection"),
|
|
542
552
|
scene: r.get("scene"),
|
|
@@ -4660,7 +4670,7 @@ function serialToEntry(se, custom, logger) {
|
|
|
4660
4670
|
};
|
|
4661
4671
|
}
|
|
4662
4672
|
|
|
4663
|
-
// ../core/dist/chunk-
|
|
4673
|
+
// ../core/dist/chunk-NU7D64RL.js
|
|
4664
4674
|
function worldToScreen(worldX, worldY, view) {
|
|
4665
4675
|
return [view.panX + worldX * view.zoom.x, view.panY + worldY * view.zoom.y];
|
|
4666
4676
|
}
|
|
@@ -4833,6 +4843,44 @@ void main() {
|
|
|
4833
4843
|
}
|
|
4834
4844
|
`
|
|
4835
4845
|
);
|
|
4846
|
+
var IMAGE_VOPACITY_VERT_SRC = (
|
|
4847
|
+
/* glsl */
|
|
4848
|
+
`#version 300 es
|
|
4849
|
+
in vec2 a_position;
|
|
4850
|
+
in vec2 a_uv;
|
|
4851
|
+
in float a_opacity;
|
|
4852
|
+
uniform mat3 u_proj;
|
|
4853
|
+
uniform mat3 u_model;
|
|
4854
|
+
out vec2 v_uv;
|
|
4855
|
+
out float v_opacity;
|
|
4856
|
+
void main() {
|
|
4857
|
+
vec3 screen = u_model * vec3(a_position, 1.0);
|
|
4858
|
+
vec3 clip = u_proj * vec3(screen.xy, 1.0);
|
|
4859
|
+
gl_Position = vec4(clip.xy, 0.0, 1.0);
|
|
4860
|
+
v_uv = a_uv;
|
|
4861
|
+
v_opacity = a_opacity;
|
|
4862
|
+
}
|
|
4863
|
+
`
|
|
4864
|
+
);
|
|
4865
|
+
var IMAGE_VOPACITY_FRAG_SRC = (
|
|
4866
|
+
/* glsl */
|
|
4867
|
+
`#version 300 es
|
|
4868
|
+
precision highp float;
|
|
4869
|
+
in vec2 v_uv;
|
|
4870
|
+
in float v_opacity;
|
|
4871
|
+
uniform sampler2D u_sampler;
|
|
4872
|
+
uniform float u_alpha;
|
|
4873
|
+
uniform mat4 u_colorMatrix;
|
|
4874
|
+
uniform vec4 u_colorBias;
|
|
4875
|
+
out vec4 outColor;
|
|
4876
|
+
void main() {
|
|
4877
|
+
vec4 texel = texture(u_sampler, v_uv);
|
|
4878
|
+
vec4 mapped = clamp(u_colorMatrix * texel + u_colorBias, 0.0, 1.0);
|
|
4879
|
+
float a = mapped.a * v_opacity * u_alpha;
|
|
4880
|
+
outColor = vec4(mapped.rgb * a, a);
|
|
4881
|
+
}
|
|
4882
|
+
`
|
|
4883
|
+
);
|
|
4836
4884
|
var IMAGE_FILL_UNIFORMS = [
|
|
4837
4885
|
"u_proj",
|
|
4838
4886
|
"u_model",
|
|
@@ -4843,6 +4891,15 @@ var IMAGE_FILL_UNIFORMS = [
|
|
|
4843
4891
|
"u_colorBias"
|
|
4844
4892
|
];
|
|
4845
4893
|
var IMAGE_FILL_ATTRIBUTES = ["a_position", "a_uv"];
|
|
4894
|
+
var IMAGE_VOPACITY_UNIFORMS = [
|
|
4895
|
+
"u_proj",
|
|
4896
|
+
"u_model",
|
|
4897
|
+
"u_sampler",
|
|
4898
|
+
"u_alpha",
|
|
4899
|
+
"u_colorMatrix",
|
|
4900
|
+
"u_colorBias"
|
|
4901
|
+
];
|
|
4902
|
+
var IMAGE_VOPACITY_ATTRIBUTES = ["a_position", "a_uv", "a_opacity"];
|
|
4846
4903
|
var GRAD_VERT_SRC = (
|
|
4847
4904
|
/* glsl */
|
|
4848
4905
|
`#version 300 es
|
|
@@ -5963,6 +6020,7 @@ seedBuiltins();
|
|
|
5963
6020
|
function getPaintKind(kind) {
|
|
5964
6021
|
return KINDS.get(kind ?? "solid");
|
|
5965
6022
|
}
|
|
6023
|
+
var SPRITE_STRIDE = 9;
|
|
5966
6024
|
function tessellate(path, opts = {}) {
|
|
5967
6025
|
if (path.kind === "rect") return tessellateRect(path);
|
|
5968
6026
|
return tessellatePolygon(path, opts);
|
|
@@ -7645,6 +7703,208 @@ var SolidBatch = class {
|
|
|
7645
7703
|
gl.deleteVertexArray(set.vao);
|
|
7646
7704
|
}
|
|
7647
7705
|
};
|
|
7706
|
+
var MAX_IMAGE_VERTICES_PER_BATCH = 32768;
|
|
7707
|
+
var FLOATS_PER_VERTEX2 = 5;
|
|
7708
|
+
var INITIAL_QUADS = 64;
|
|
7709
|
+
var TIERS = [
|
|
7710
|
+
{ quads: 1, slots: 64 },
|
|
7711
|
+
{ quads: 16, slots: 64 },
|
|
7712
|
+
{ quads: 256, slots: 16 }
|
|
7713
|
+
];
|
|
7714
|
+
TIERS[0].slots;
|
|
7715
|
+
var IMAGE_LARGE_RING_SIZE = 4;
|
|
7716
|
+
function doubledTo2(from, need) {
|
|
7717
|
+
let capacity = from;
|
|
7718
|
+
while (capacity < need) capacity *= 2;
|
|
7719
|
+
return capacity;
|
|
7720
|
+
}
|
|
7721
|
+
function quadIndices(quads) {
|
|
7722
|
+
const out = new Uint32Array(quads * 6);
|
|
7723
|
+
for (let q = 0; q < quads; q++) {
|
|
7724
|
+
const b = q * 4;
|
|
7725
|
+
const j = q * 6;
|
|
7726
|
+
out[j] = b;
|
|
7727
|
+
out[j + 1] = b + 1;
|
|
7728
|
+
out[j + 2] = b + 2;
|
|
7729
|
+
out[j + 3] = b;
|
|
7730
|
+
out[j + 4] = b + 2;
|
|
7731
|
+
out[j + 5] = b + 3;
|
|
7732
|
+
}
|
|
7733
|
+
return out;
|
|
7734
|
+
}
|
|
7735
|
+
var ImageBatch = class {
|
|
7736
|
+
gl;
|
|
7737
|
+
aPos;
|
|
7738
|
+
aUv;
|
|
7739
|
+
aOpacity;
|
|
7740
|
+
/** One ring per tier, cycled per flush. Slots are created on first use, so a
|
|
7741
|
+
* renderer that flushes rarely allocates as few as it flushes. */
|
|
7742
|
+
rings = TIERS.map((t) => new Array(t.slots).fill(void 0));
|
|
7743
|
+
nextInRing = TIERS.map(() => 0);
|
|
7744
|
+
/** For flushes past the largest tier; these sets grow to fit. */
|
|
7745
|
+
largeRing = new Array(IMAGE_LARGE_RING_SIZE).fill(void 0);
|
|
7746
|
+
nextLarge = 0;
|
|
7747
|
+
verts = new Float32Array(INITIAL_QUADS * 4 * FLOATS_PER_VERTEX2);
|
|
7748
|
+
nQuads = 0;
|
|
7749
|
+
constructor(gl, prog) {
|
|
7750
|
+
const aPos = prog.attribute("a_position");
|
|
7751
|
+
const aUv = prog.attribute("a_uv");
|
|
7752
|
+
const aOpacity = prog.attribute("a_opacity");
|
|
7753
|
+
if (aPos === void 0 || aUv === void 0 || aOpacity === void 0) {
|
|
7754
|
+
throw new Error(
|
|
7755
|
+
"ImageBatch: vertex-opacity program is missing a_position / a_uv / a_opacity"
|
|
7756
|
+
);
|
|
7757
|
+
}
|
|
7758
|
+
this.gl = gl;
|
|
7759
|
+
this.aPos = aPos;
|
|
7760
|
+
this.aUv = aUv;
|
|
7761
|
+
this.aOpacity = aOpacity;
|
|
7762
|
+
}
|
|
7763
|
+
/** Indices staged — what a caller passes to `drawElements`. */
|
|
7764
|
+
get length() {
|
|
7765
|
+
return this.nQuads * 6;
|
|
7766
|
+
}
|
|
7767
|
+
get quads() {
|
|
7768
|
+
return this.nQuads;
|
|
7769
|
+
}
|
|
7770
|
+
/** Whether staging one more quad would put the run past the per-flush cap. */
|
|
7771
|
+
wouldOverflow() {
|
|
7772
|
+
return (this.nQuads + 1) * 4 > MAX_IMAGE_VERTICES_PER_BATCH;
|
|
7773
|
+
}
|
|
7774
|
+
/**
|
|
7775
|
+
* Append one image quad: the destination rect `(x, y, w, h)` mapped through
|
|
7776
|
+
* `m`, sampling `(u0, v0)`-`(u1, v1)`, every corner carrying `opacity`.
|
|
7777
|
+
*
|
|
7778
|
+
* An affine maps a rect to a parallelogram, so two triangles still cover it
|
|
7779
|
+
* and the batch draws at `u_model` identity. Corners wind top-left,
|
|
7780
|
+
* top-right, bottom-right, bottom-left, with UVs following — the flips a
|
|
7781
|
+
* command asks for are already in the `u`/`v` the caller passes.
|
|
7782
|
+
*/
|
|
7783
|
+
pushQuad(x, y, w, h, m, u0, v0, u1, v1, opacity) {
|
|
7784
|
+
this.reserve();
|
|
7785
|
+
const v = this.verts;
|
|
7786
|
+
let i = this.nQuads * 4 * FLOATS_PER_VERTEX2;
|
|
7787
|
+
const ma = m[0], mb = m[1], mc = m[3], md = m[4], mtx = m[6], mty = m[7];
|
|
7788
|
+
const x1 = x + w;
|
|
7789
|
+
const y1 = y + h;
|
|
7790
|
+
const ax = ma * x + mc * y + mtx, ay = mb * x + md * y + mty;
|
|
7791
|
+
const bx = ma * x1 + mc * y + mtx, by = mb * x1 + md * y + mty;
|
|
7792
|
+
const cx = ma * x1 + mc * y1 + mtx, cy = mb * x1 + md * y1 + mty;
|
|
7793
|
+
const dx = ma * x + mc * y1 + mtx, dy = mb * x + md * y1 + mty;
|
|
7794
|
+
v[i++] = ax;
|
|
7795
|
+
v[i++] = ay;
|
|
7796
|
+
v[i++] = u0;
|
|
7797
|
+
v[i++] = v0;
|
|
7798
|
+
v[i++] = opacity;
|
|
7799
|
+
v[i++] = bx;
|
|
7800
|
+
v[i++] = by;
|
|
7801
|
+
v[i++] = u1;
|
|
7802
|
+
v[i++] = v0;
|
|
7803
|
+
v[i++] = opacity;
|
|
7804
|
+
v[i++] = cx;
|
|
7805
|
+
v[i++] = cy;
|
|
7806
|
+
v[i++] = u1;
|
|
7807
|
+
v[i++] = v1;
|
|
7808
|
+
v[i++] = opacity;
|
|
7809
|
+
v[i++] = dx;
|
|
7810
|
+
v[i++] = dy;
|
|
7811
|
+
v[i++] = u0;
|
|
7812
|
+
v[i++] = v1;
|
|
7813
|
+
v[i++] = opacity;
|
|
7814
|
+
this.nQuads += 1;
|
|
7815
|
+
}
|
|
7816
|
+
/** Upload the staged geometry into the next set of buffers and bind its VAO.
|
|
7817
|
+
* Returns the index count for the caller's `drawElements`. */
|
|
7818
|
+
uploadAndBind() {
|
|
7819
|
+
const gl = this.gl;
|
|
7820
|
+
const tier = TIERS.findIndex((t) => this.nQuads <= t.quads);
|
|
7821
|
+
const set = tier < 0 ? this.nextLargeSlot() : this.nextRingSlot(tier);
|
|
7822
|
+
gl.bindVertexArray(set.vao);
|
|
7823
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, set.vbo);
|
|
7824
|
+
gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.verts, 0, this.nQuads * 4 * FLOATS_PER_VERTEX2);
|
|
7825
|
+
return this.nQuads * 6;
|
|
7826
|
+
}
|
|
7827
|
+
reset() {
|
|
7828
|
+
this.nQuads = 0;
|
|
7829
|
+
}
|
|
7830
|
+
dispose() {
|
|
7831
|
+
for (const set of [...this.rings.flat(), ...this.largeRing]) {
|
|
7832
|
+
if (set) this.deleteSet(set);
|
|
7833
|
+
}
|
|
7834
|
+
for (const ring of this.rings) ring.fill(void 0);
|
|
7835
|
+
this.largeRing.fill(void 0);
|
|
7836
|
+
}
|
|
7837
|
+
/** Grow the CPU arrays so one more quad fits. */
|
|
7838
|
+
reserve() {
|
|
7839
|
+
const need = (this.nQuads + 1) * 4 * FLOATS_PER_VERTEX2;
|
|
7840
|
+
if (need <= this.verts.length) return;
|
|
7841
|
+
const grown = new Float32Array(doubledTo2(this.verts.length, need));
|
|
7842
|
+
grown.set(this.verts);
|
|
7843
|
+
this.verts = grown;
|
|
7844
|
+
}
|
|
7845
|
+
nextRingSlot(tier) {
|
|
7846
|
+
const ring = this.rings[tier];
|
|
7847
|
+
const slot = this.nextInRing[tier];
|
|
7848
|
+
this.nextInRing[tier] = (slot + 1) % ring.length;
|
|
7849
|
+
const existing = ring[slot];
|
|
7850
|
+
if (existing) return existing;
|
|
7851
|
+
const set = this.createSet(TIERS[tier].quads);
|
|
7852
|
+
ring[slot] = set;
|
|
7853
|
+
return set;
|
|
7854
|
+
}
|
|
7855
|
+
nextLargeSlot() {
|
|
7856
|
+
const gl = this.gl;
|
|
7857
|
+
const slot = this.nextLarge;
|
|
7858
|
+
this.nextLarge = (slot + 1) % IMAGE_LARGE_RING_SIZE;
|
|
7859
|
+
let set = this.largeRing[slot];
|
|
7860
|
+
if (!set) {
|
|
7861
|
+
set = this.createSet(doubledTo2(TIERS[TIERS.length - 1].quads, this.nQuads));
|
|
7862
|
+
this.largeRing[slot] = set;
|
|
7863
|
+
return set;
|
|
7864
|
+
}
|
|
7865
|
+
if (this.nQuads > set.quadCapacity) {
|
|
7866
|
+
set.quadCapacity = doubledTo2(set.quadCapacity, this.nQuads);
|
|
7867
|
+
gl.bindVertexArray(set.vao);
|
|
7868
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, set.vbo);
|
|
7869
|
+
gl.bufferData(
|
|
7870
|
+
gl.ARRAY_BUFFER,
|
|
7871
|
+
set.quadCapacity * 4 * FLOATS_PER_VERTEX2 * 4,
|
|
7872
|
+
gl.DYNAMIC_DRAW
|
|
7873
|
+
);
|
|
7874
|
+
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, set.ibo);
|
|
7875
|
+
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, quadIndices(set.quadCapacity), gl.STATIC_DRAW);
|
|
7876
|
+
gl.bindVertexArray(null);
|
|
7877
|
+
}
|
|
7878
|
+
return set;
|
|
7879
|
+
}
|
|
7880
|
+
createSet(quads) {
|
|
7881
|
+
const gl = this.gl;
|
|
7882
|
+
const vao = gl.createVertexArray();
|
|
7883
|
+
const vbo = gl.createBuffer();
|
|
7884
|
+
const ibo = gl.createBuffer();
|
|
7885
|
+
if (!vao || !vbo || !ibo) throw new Error("ImageBatch: failed to create GL objects");
|
|
7886
|
+
const stride = FLOATS_PER_VERTEX2 * 4;
|
|
7887
|
+
gl.bindVertexArray(vao);
|
|
7888
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
|
|
7889
|
+
gl.bufferData(gl.ARRAY_BUFFER, quads * 4 * stride, gl.DYNAMIC_DRAW);
|
|
7890
|
+
gl.enableVertexAttribArray(this.aPos);
|
|
7891
|
+
gl.vertexAttribPointer(this.aPos, 2, gl.FLOAT, false, stride, 0);
|
|
7892
|
+
gl.enableVertexAttribArray(this.aUv);
|
|
7893
|
+
gl.vertexAttribPointer(this.aUv, 2, gl.FLOAT, false, stride, 8);
|
|
7894
|
+
gl.enableVertexAttribArray(this.aOpacity);
|
|
7895
|
+
gl.vertexAttribPointer(this.aOpacity, 1, gl.FLOAT, false, stride, 16);
|
|
7896
|
+
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ibo);
|
|
7897
|
+
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, quadIndices(quads), gl.STATIC_DRAW);
|
|
7898
|
+
gl.bindVertexArray(null);
|
|
7899
|
+
return { vao, vbo, ibo, quadCapacity: quads };
|
|
7900
|
+
}
|
|
7901
|
+
deleteSet(set) {
|
|
7902
|
+
const gl = this.gl;
|
|
7903
|
+
gl.deleteBuffer(set.vbo);
|
|
7904
|
+
gl.deleteBuffer(set.ibo);
|
|
7905
|
+
gl.deleteVertexArray(set.vao);
|
|
7906
|
+
}
|
|
7907
|
+
};
|
|
7648
7908
|
var FRAME_UPLOADS = /* @__PURE__ */ new WeakMap();
|
|
7649
7909
|
var FRAME_PROJ = /* @__PURE__ */ new WeakMap();
|
|
7650
7910
|
function uploadedFor(ctx, prog) {
|
|
@@ -7738,13 +7998,14 @@ function dispatch(ctx, cmd) {
|
|
|
7738
7998
|
case "path":
|
|
7739
7999
|
return drawPath(ctx, cmd);
|
|
7740
8000
|
case "text":
|
|
7741
|
-
|
|
8001
|
+
flushBatches(ctx);
|
|
7742
8002
|
return drawText(ctx, cmd);
|
|
7743
8003
|
case "image":
|
|
7744
|
-
flushSolids(ctx);
|
|
7745
8004
|
return drawImage(ctx, cmd);
|
|
8005
|
+
case "sprites":
|
|
8006
|
+
return drawSprites(ctx, cmd);
|
|
7746
8007
|
case "shader":
|
|
7747
|
-
|
|
8008
|
+
flushBatches(ctx);
|
|
7748
8009
|
return drawShader(ctx, cmd);
|
|
7749
8010
|
}
|
|
7750
8011
|
}
|
|
@@ -7921,6 +8182,7 @@ function canBatchMesh(mesh) {
|
|
|
7921
8182
|
return !mesh.requiresStencil && mesh.vertices.length >> 1 <= MAX_BATCHED_MESH_VERTICES;
|
|
7922
8183
|
}
|
|
7923
8184
|
function stageSolid(ctx, vertices) {
|
|
8185
|
+
flushImages(ctx);
|
|
7924
8186
|
if (ctx.solidState !== void 0 && !stagedStateIsLive(ctx, ctx.solidState)) flushSolids(ctx);
|
|
7925
8187
|
if (ctx.solidBatch.wouldOverflow(vertices)) flushSolids(ctx);
|
|
7926
8188
|
if (ctx.solidState === void 0) {
|
|
@@ -7964,7 +8226,7 @@ function tryStageSolid(ctx, mesh, paint) {
|
|
|
7964
8226
|
pushMesh(ctx, mesh, paint);
|
|
7965
8227
|
return true;
|
|
7966
8228
|
}
|
|
7967
|
-
|
|
8229
|
+
flushBatches(ctx);
|
|
7968
8230
|
return false;
|
|
7969
8231
|
}
|
|
7970
8232
|
function flushSolids(ctx) {
|
|
@@ -7985,6 +8247,56 @@ function flushSolids(ctx) {
|
|
|
7985
8247
|
batch.reset();
|
|
7986
8248
|
ctx.solidState = void 0;
|
|
7987
8249
|
}
|
|
8250
|
+
function stagedImageStateIsLive(ctx, staged, image, sampling) {
|
|
8251
|
+
if (staged.image !== image) return false;
|
|
8252
|
+
if (staged.sampling !== sampling) return false;
|
|
8253
|
+
if (staged.clipDepth !== ctx.clipDepth) return false;
|
|
8254
|
+
const colorMatrix = ctx.state.colorMatrix;
|
|
8255
|
+
return staged.colorMatrix === colorMatrix || sameValues(staged.colorMatrix, colorMatrix);
|
|
8256
|
+
}
|
|
8257
|
+
function stageImage(ctx, image, sampling) {
|
|
8258
|
+
flushSolids(ctx);
|
|
8259
|
+
if (ctx.imageState !== void 0 && !stagedImageStateIsLive(ctx, ctx.imageState, image, sampling)) {
|
|
8260
|
+
flushImages(ctx);
|
|
8261
|
+
}
|
|
8262
|
+
if (ctx.imageBatch.wouldOverflow()) flushImages(ctx);
|
|
8263
|
+
if (ctx.imageState === void 0) {
|
|
8264
|
+
ctx.imageState = {
|
|
8265
|
+
image,
|
|
8266
|
+
sampling,
|
|
8267
|
+
colorMatrix: ctx.state.colorMatrix,
|
|
8268
|
+
clipDepth: ctx.clipDepth
|
|
8269
|
+
};
|
|
8270
|
+
}
|
|
8271
|
+
}
|
|
8272
|
+
function flushImages(ctx) {
|
|
8273
|
+
const batch = ctx.imageBatch;
|
|
8274
|
+
const staged = ctx.imageState;
|
|
8275
|
+
if (batch.length === 0 || staged === void 0) return;
|
|
8276
|
+
const gl = ctx.gl;
|
|
8277
|
+
const prog = ctx.imageFillVOpacity;
|
|
8278
|
+
gl.useProgram(prog.handle);
|
|
8279
|
+
const indexCount = batch.uploadAndBind();
|
|
8280
|
+
setProjAndModel(ctx, prog, BATCH_MODEL);
|
|
8281
|
+
setAlphaUniform(ctx, prog, 1);
|
|
8282
|
+
setColorMatrixUniforms(ctx, prog, staged.colorMatrix);
|
|
8283
|
+
ctx.imageCache.bind(staged.image, 0);
|
|
8284
|
+
gl.texParameteri(
|
|
8285
|
+
gl.TEXTURE_2D,
|
|
8286
|
+
gl.TEXTURE_MAG_FILTER,
|
|
8287
|
+
staged.sampling === "nearest" ? gl.NEAREST : gl.LINEAR
|
|
8288
|
+
);
|
|
8289
|
+
gl.uniform1i(prog.uniform("u_sampler"), 0);
|
|
8290
|
+
applyClipTest(ctx, staged.clipDepth);
|
|
8291
|
+
gl.drawElements(gl.TRIANGLES, indexCount, gl.UNSIGNED_INT, 0);
|
|
8292
|
+
gl.bindVertexArray(null);
|
|
8293
|
+
batch.reset();
|
|
8294
|
+
ctx.imageState = void 0;
|
|
8295
|
+
}
|
|
8296
|
+
function flushBatches(ctx) {
|
|
8297
|
+
flushSolids(ctx);
|
|
8298
|
+
flushImages(ctx);
|
|
8299
|
+
}
|
|
7988
8300
|
function expandAnchorColors(perAnchor, handle) {
|
|
7989
8301
|
const aA = handle.anchorA;
|
|
7990
8302
|
const aB = handle.anchorB;
|
|
@@ -8188,7 +8500,7 @@ function rasterizePathToStencil(ctx, path) {
|
|
|
8188
8500
|
gl.bindVertexArray(null);
|
|
8189
8501
|
}
|
|
8190
8502
|
function pushClip(ctx, path, newDepth) {
|
|
8191
|
-
|
|
8503
|
+
flushBatches(ctx);
|
|
8192
8504
|
const gl = ctx.gl;
|
|
8193
8505
|
const ancestors = ancestorMask(newDepth - 1);
|
|
8194
8506
|
const newBit = 1 << newDepth;
|
|
@@ -8203,7 +8515,7 @@ function pushClip(ctx, path, newDepth) {
|
|
|
8203
8515
|
gl.stencilMask(255);
|
|
8204
8516
|
}
|
|
8205
8517
|
function popClip(ctx, path, oldDepth) {
|
|
8206
|
-
|
|
8518
|
+
flushBatches(ctx);
|
|
8207
8519
|
const gl = ctx.gl;
|
|
8208
8520
|
gl.enable(gl.STENCIL_TEST);
|
|
8209
8521
|
const oldBit = 1 << oldDepth + 1;
|
|
@@ -8250,7 +8562,7 @@ function drawPathStroke(ctx, rawCmd) {
|
|
|
8250
8562
|
const stroke = cmd.stroke;
|
|
8251
8563
|
const align = stroke.align ?? "center";
|
|
8252
8564
|
if (cmd.path.kind === "polygon" && align !== "center") {
|
|
8253
|
-
|
|
8565
|
+
flushBatches(ctx);
|
|
8254
8566
|
drawPathStrokeStenciled(ctx, cmd, align);
|
|
8255
8567
|
return;
|
|
8256
8568
|
}
|
|
@@ -8598,45 +8910,6 @@ function drawTextGroup(ctx, group, prog, dx, dy) {
|
|
|
8598
8910
|
gl.drawElements(gl.TRIANGLES, group.quads.length * 6, gl.UNSIGNED_INT, 0);
|
|
8599
8911
|
gl.bindVertexArray(null);
|
|
8600
8912
|
}
|
|
8601
|
-
var IMAGE_QUAD_RING_SIZE = 64;
|
|
8602
|
-
var IMAGE_QUAD_RINGS = /* @__PURE__ */ new WeakMap();
|
|
8603
|
-
var IMAGE_QUAD_INDICES = new Uint32Array([0, 1, 2, 1, 3, 2]);
|
|
8604
|
-
var IMAGE_QUAD_STRIDE = 16;
|
|
8605
|
-
function imageQuadRing(gl, prog) {
|
|
8606
|
-
const existing = IMAGE_QUAD_RINGS.get(prog);
|
|
8607
|
-
if (existing) return existing;
|
|
8608
|
-
const aPosLoc = prog.attribute("a_position");
|
|
8609
|
-
const aUvLoc = prog.attribute("a_uv");
|
|
8610
|
-
const ibo = gl.createBuffer();
|
|
8611
|
-
if (!ibo) throw new Error("drawImage: createBuffer (IBO) returned null");
|
|
8612
|
-
const vaos = [];
|
|
8613
|
-
const vbos = [];
|
|
8614
|
-
for (let slot = 0; slot < IMAGE_QUAD_RING_SIZE; slot++) {
|
|
8615
|
-
const vao = gl.createVertexArray();
|
|
8616
|
-
const vbo = gl.createBuffer();
|
|
8617
|
-
if (!vao) throw new Error("drawImage: createVertexArray returned null");
|
|
8618
|
-
if (!vbo) throw new Error("drawImage: createBuffer returned null");
|
|
8619
|
-
gl.bindVertexArray(vao);
|
|
8620
|
-
gl.bindBuffer(gl.ARRAY_BUFFER, vbo);
|
|
8621
|
-
gl.bufferData(gl.ARRAY_BUFFER, 4 * IMAGE_QUAD_STRIDE, gl.DYNAMIC_DRAW);
|
|
8622
|
-
if (aPosLoc !== void 0) {
|
|
8623
|
-
gl.enableVertexAttribArray(aPosLoc);
|
|
8624
|
-
gl.vertexAttribPointer(aPosLoc, 2, gl.FLOAT, false, IMAGE_QUAD_STRIDE, 0);
|
|
8625
|
-
}
|
|
8626
|
-
if (aUvLoc !== void 0) {
|
|
8627
|
-
gl.enableVertexAttribArray(aUvLoc);
|
|
8628
|
-
gl.vertexAttribPointer(aUvLoc, 2, gl.FLOAT, false, IMAGE_QUAD_STRIDE, 8);
|
|
8629
|
-
}
|
|
8630
|
-
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, ibo);
|
|
8631
|
-
if (slot === 0) gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, IMAGE_QUAD_INDICES, gl.STATIC_DRAW);
|
|
8632
|
-
gl.bindVertexArray(null);
|
|
8633
|
-
vaos.push(vao);
|
|
8634
|
-
vbos.push(vbo);
|
|
8635
|
-
}
|
|
8636
|
-
const ring = { vaos, vbos, ibo, next: 0 };
|
|
8637
|
-
IMAGE_QUAD_RINGS.set(prog, ring);
|
|
8638
|
-
return ring;
|
|
8639
|
-
}
|
|
8640
8913
|
var TEXT_QUAD_RING_SIZE = 64;
|
|
8641
8914
|
var TEXT_QUAD_RINGS = /* @__PURE__ */ new WeakMap();
|
|
8642
8915
|
function grownTo(need) {
|
|
@@ -8714,22 +8987,9 @@ function disposeTextQuads(gl, prog) {
|
|
|
8714
8987
|
gl.deleteBuffer(ring.ibo);
|
|
8715
8988
|
TEXT_QUAD_RINGS.delete(prog);
|
|
8716
8989
|
}
|
|
8717
|
-
function disposeImageQuads(gl, prog) {
|
|
8718
|
-
const ring = IMAGE_QUAD_RINGS.get(prog);
|
|
8719
|
-
if (!ring) return;
|
|
8720
|
-
for (const vao of ring.vaos) gl.deleteVertexArray(vao);
|
|
8721
|
-
for (const vbo of ring.vbos) gl.deleteBuffer(vbo);
|
|
8722
|
-
gl.deleteBuffer(ring.ibo);
|
|
8723
|
-
IMAGE_QUAD_RINGS.delete(prog);
|
|
8724
|
-
}
|
|
8725
|
-
var IMAGE_QUAD_VERTICES = new Float32Array(16);
|
|
8726
8990
|
function drawImage(ctx, cmd) {
|
|
8727
8991
|
ctx.imageCache.upload(cmd.image, cmd.image);
|
|
8728
|
-
|
|
8729
|
-
const prog = ctx.imageFill;
|
|
8730
|
-
gl.useProgram(prog.handle);
|
|
8731
|
-
const x0 = cmd.x, y0 = cmd.y;
|
|
8732
|
-
const x1 = cmd.x + cmd.w, y1 = cmd.y + cmd.h;
|
|
8992
|
+
stageImage(ctx, cmd.image, cmd.sampling ?? "linear");
|
|
8733
8993
|
const src = cmd.source;
|
|
8734
8994
|
let u0 = 0, v0 = 0, u1 = 1, v1 = 1;
|
|
8735
8995
|
if (src) {
|
|
@@ -8749,43 +9009,50 @@ function drawImage(ctx, cmd) {
|
|
|
8749
9009
|
v0 = v1;
|
|
8750
9010
|
v1 = t;
|
|
8751
9011
|
}
|
|
8752
|
-
|
|
8753
|
-
|
|
8754
|
-
|
|
8755
|
-
|
|
8756
|
-
|
|
8757
|
-
|
|
8758
|
-
|
|
8759
|
-
|
|
8760
|
-
|
|
8761
|
-
|
|
8762
|
-
|
|
8763
|
-
v[10] = u0;
|
|
8764
|
-
v[11] = v1;
|
|
8765
|
-
v[12] = x1;
|
|
8766
|
-
v[13] = y1;
|
|
8767
|
-
v[14] = u1;
|
|
8768
|
-
v[15] = v1;
|
|
8769
|
-
const ring = imageQuadRing(gl, prog);
|
|
8770
|
-
const slot = ring.next;
|
|
8771
|
-
ring.next = (slot + 1) % IMAGE_QUAD_RING_SIZE;
|
|
8772
|
-
gl.bindVertexArray(ring.vaos[slot]);
|
|
8773
|
-
gl.bindBuffer(gl.ARRAY_BUFFER, ring.vbos[slot]);
|
|
8774
|
-
gl.bufferSubData(gl.ARRAY_BUFFER, 0, v);
|
|
8775
|
-
setProjAndModel(ctx, prog);
|
|
8776
|
-
setColorMatrixUniforms(ctx, prog);
|
|
8777
|
-
ctx.imageCache.bind(cmd.image, 0);
|
|
8778
|
-
gl.texParameteri(
|
|
8779
|
-
gl.TEXTURE_2D,
|
|
8780
|
-
gl.TEXTURE_MAG_FILTER,
|
|
8781
|
-
cmd.sampling === "nearest" ? gl.NEAREST : gl.LINEAR
|
|
9012
|
+
ctx.imageBatch.pushQuad(
|
|
9013
|
+
cmd.x,
|
|
9014
|
+
cmd.y,
|
|
9015
|
+
cmd.w,
|
|
9016
|
+
cmd.h,
|
|
9017
|
+
ctx.state.transform,
|
|
9018
|
+
u0,
|
|
9019
|
+
v0,
|
|
9020
|
+
u1,
|
|
9021
|
+
v1,
|
|
9022
|
+
(cmd.opacity ?? 1) * ctx.state.alpha
|
|
8782
9023
|
);
|
|
8783
|
-
|
|
8784
|
-
|
|
8785
|
-
|
|
8786
|
-
|
|
8787
|
-
|
|
8788
|
-
|
|
9024
|
+
}
|
|
9025
|
+
function drawSprites(ctx, cmd) {
|
|
9026
|
+
const data = cmd.sprites;
|
|
9027
|
+
const count = Math.floor(data.length / SPRITE_STRIDE);
|
|
9028
|
+
if (count === 0) return;
|
|
9029
|
+
ctx.imageCache.upload(cmd.image, cmd.image);
|
|
9030
|
+
const sampling = cmd.sampling ?? "linear";
|
|
9031
|
+
stageImage(ctx, cmd.image, sampling);
|
|
9032
|
+
const batch = ctx.imageBatch;
|
|
9033
|
+
const m = ctx.state.transform;
|
|
9034
|
+
const groupAlpha = ctx.state.alpha;
|
|
9035
|
+
const tw = cmd.image.width;
|
|
9036
|
+
const th = cmd.image.height;
|
|
9037
|
+
for (let s = 0, i = 0; s < count; s++, i += SPRITE_STRIDE) {
|
|
9038
|
+
if (batch.wouldOverflow()) {
|
|
9039
|
+
flushImages(ctx);
|
|
9040
|
+
stageImage(ctx, cmd.image, sampling);
|
|
9041
|
+
}
|
|
9042
|
+
const sx = data[i + 4], sy = data[i + 5], sw = data[i + 6], sh = data[i + 7];
|
|
9043
|
+
batch.pushQuad(
|
|
9044
|
+
data[i],
|
|
9045
|
+
data[i + 1],
|
|
9046
|
+
data[i + 2],
|
|
9047
|
+
data[i + 3],
|
|
9048
|
+
m,
|
|
9049
|
+
sx / tw,
|
|
9050
|
+
sy / th,
|
|
9051
|
+
(sx + sw) / tw,
|
|
9052
|
+
(sy + sh) / th,
|
|
9053
|
+
data[i + 8] * groupAlpha
|
|
9054
|
+
);
|
|
9055
|
+
}
|
|
8789
9056
|
}
|
|
8790
9057
|
var CUSTOM_VERT_SRC = (
|
|
8791
9058
|
/* glsl */
|
|
@@ -8874,6 +9141,7 @@ var WeaselRenderer = class {
|
|
|
8874
9141
|
textSdf;
|
|
8875
9142
|
textSdfR8;
|
|
8876
9143
|
imageFill;
|
|
9144
|
+
imageFillVOpacity;
|
|
8877
9145
|
gradFill;
|
|
8878
9146
|
patternFill;
|
|
8879
9147
|
meshCache;
|
|
@@ -8884,6 +9152,7 @@ var WeaselRenderer = class {
|
|
|
8884
9152
|
quadVbo = null;
|
|
8885
9153
|
quadIbo = null;
|
|
8886
9154
|
solidBatch;
|
|
9155
|
+
imageBatch;
|
|
8887
9156
|
groupState = new GroupState();
|
|
8888
9157
|
widthCss;
|
|
8889
9158
|
heightCss;
|
|
@@ -8948,6 +9217,13 @@ var WeaselRenderer = class {
|
|
|
8948
9217
|
this.imageFill = new ShaderProgram(this.gl, IMAGE_VERT_SRC, IMAGE_FRAG_SRC);
|
|
8949
9218
|
this.imageFill.lookupUniforms(IMAGE_FILL_UNIFORMS);
|
|
8950
9219
|
this.imageFill.lookupAttributes(IMAGE_FILL_ATTRIBUTES);
|
|
9220
|
+
this.imageFillVOpacity = new ShaderProgram(
|
|
9221
|
+
this.gl,
|
|
9222
|
+
IMAGE_VOPACITY_VERT_SRC,
|
|
9223
|
+
IMAGE_VOPACITY_FRAG_SRC
|
|
9224
|
+
);
|
|
9225
|
+
this.imageFillVOpacity.lookupUniforms(IMAGE_VOPACITY_UNIFORMS);
|
|
9226
|
+
this.imageFillVOpacity.lookupAttributes(IMAGE_VOPACITY_ATTRIBUTES);
|
|
8951
9227
|
this.gradFill = new ShaderProgram(this.gl, GRAD_VERT_SRC, GRAD_FRAG_SRC);
|
|
8952
9228
|
this.gradFill.lookupUniforms(GRAD_FILL_UNIFORMS);
|
|
8953
9229
|
this.gradFill.lookupAttributes(GRAD_FILL_ATTRIBUTES);
|
|
@@ -8962,6 +9238,7 @@ var WeaselRenderer = class {
|
|
|
8962
9238
|
this.gradRampCache = new GradientRampCache(this.gl);
|
|
8963
9239
|
this.uploadQuadGeometry();
|
|
8964
9240
|
this.solidBatch = new SolidBatch(this.gl, this.pathFillVColor);
|
|
9241
|
+
this.imageBatch = new ImageBatch(this.gl, this.imageFillVOpacity);
|
|
8965
9242
|
}
|
|
8966
9243
|
uploadQuadGeometry() {
|
|
8967
9244
|
const gl = this.gl;
|
|
@@ -9085,6 +9362,13 @@ var WeaselRenderer = class {
|
|
|
9085
9362
|
this.imageFill = new ShaderProgram(this.gl, IMAGE_VERT_SRC, IMAGE_FRAG_SRC);
|
|
9086
9363
|
this.imageFill.lookupUniforms(IMAGE_FILL_UNIFORMS);
|
|
9087
9364
|
this.imageFill.lookupAttributes(IMAGE_FILL_ATTRIBUTES);
|
|
9365
|
+
this.imageFillVOpacity = new ShaderProgram(
|
|
9366
|
+
this.gl,
|
|
9367
|
+
IMAGE_VOPACITY_VERT_SRC,
|
|
9368
|
+
IMAGE_VOPACITY_FRAG_SRC
|
|
9369
|
+
);
|
|
9370
|
+
this.imageFillVOpacity.lookupUniforms(IMAGE_VOPACITY_UNIFORMS);
|
|
9371
|
+
this.imageFillVOpacity.lookupAttributes(IMAGE_VOPACITY_ATTRIBUTES);
|
|
9088
9372
|
this.gradFill = new ShaderProgram(this.gl, GRAD_VERT_SRC, GRAD_FRAG_SRC);
|
|
9089
9373
|
this.gradFill.lookupUniforms(GRAD_FILL_UNIFORMS);
|
|
9090
9374
|
this.gradFill.lookupAttributes(GRAD_FILL_ATTRIBUTES);
|
|
@@ -9099,6 +9383,7 @@ var WeaselRenderer = class {
|
|
|
9099
9383
|
this.gradRampCache = new GradientRampCache(this.gl);
|
|
9100
9384
|
this.uploadQuadGeometry();
|
|
9101
9385
|
this.solidBatch = new SolidBatch(this.gl, this.pathFillVColor);
|
|
9386
|
+
this.imageBatch = new ImageBatch(this.gl, this.imageFillVOpacity);
|
|
9102
9387
|
for (const id of this.programRegistry.keys()) {
|
|
9103
9388
|
const src = getProgramSource(id);
|
|
9104
9389
|
if (!src) continue;
|
|
@@ -9147,7 +9432,7 @@ var WeaselRenderer = class {
|
|
|
9147
9432
|
}
|
|
9148
9433
|
this.meshCache.freeTransient();
|
|
9149
9434
|
this.meshCache.drainPendingDeletes();
|
|
9150
|
-
for (const prog of [this.pathFill, this.pathFillVColor, this.textSdf, this.textSdfR8, this.imageFill, this.gradFill, this.patternFill]) {
|
|
9435
|
+
for (const prog of [this.pathFill, this.pathFillVColor, this.textSdf, this.textSdfR8, this.imageFill, this.imageFillVOpacity, this.gradFill, this.patternFill]) {
|
|
9151
9436
|
gl.deleteProgram(prog.handle);
|
|
9152
9437
|
}
|
|
9153
9438
|
for (const prog of this.programRegistry.values()) {
|
|
@@ -9158,9 +9443,9 @@ var WeaselRenderer = class {
|
|
|
9158
9443
|
this.gradRampCache.free();
|
|
9159
9444
|
if (this.quadVbo) gl.deleteBuffer(this.quadVbo);
|
|
9160
9445
|
if (this.quadIbo) gl.deleteBuffer(this.quadIbo);
|
|
9161
|
-
disposeImageQuads(gl, this.imageFill);
|
|
9162
9446
|
for (const prog of [this.textSdf, this.textSdfR8, this.pathFill]) disposeTextQuads(gl, prog);
|
|
9163
9447
|
this.solidBatch.dispose();
|
|
9448
|
+
this.imageBatch.dispose();
|
|
9164
9449
|
}
|
|
9165
9450
|
/**
|
|
9166
9451
|
* Draw one frame.
|
|
@@ -9189,6 +9474,7 @@ var WeaselRenderer = class {
|
|
|
9189
9474
|
textSdf: this.textSdf,
|
|
9190
9475
|
textSdfR8: this.textSdfR8,
|
|
9191
9476
|
imageFill: this.imageFill,
|
|
9477
|
+
imageFillVOpacity: this.imageFillVOpacity,
|
|
9192
9478
|
gradFill: this.gradFill,
|
|
9193
9479
|
patternFill: this.patternFill,
|
|
9194
9480
|
meshCache: this.meshCache,
|
|
@@ -9200,6 +9486,7 @@ var WeaselRenderer = class {
|
|
|
9200
9486
|
quadVbo: this.quadVbo,
|
|
9201
9487
|
quadIbo: this.quadIbo,
|
|
9202
9488
|
solidBatch: this.solidBatch,
|
|
9489
|
+
imageBatch: this.imageBatch,
|
|
9203
9490
|
state: this.groupState,
|
|
9204
9491
|
widthCss: this.widthCss,
|
|
9205
9492
|
heightCss: this.heightCss,
|
|
@@ -9209,7 +9496,7 @@ var WeaselRenderer = class {
|
|
|
9209
9496
|
viewMatrix: viewMatrix2
|
|
9210
9497
|
};
|
|
9211
9498
|
for (const cmd of commands) dispatch(ctx, cmd);
|
|
9212
|
-
|
|
9499
|
+
flushBatches(ctx);
|
|
9213
9500
|
this.meshCache.freeTransient();
|
|
9214
9501
|
}
|
|
9215
9502
|
resize(dims) {
|
|
@@ -9243,6 +9530,10 @@ var WeaselRenderer = class {
|
|
|
9243
9530
|
return this.solidBatch;
|
|
9244
9531
|
}
|
|
9245
9532
|
/** @internal */
|
|
9533
|
+
_imageBatch() {
|
|
9534
|
+
return this.imageBatch;
|
|
9535
|
+
}
|
|
9536
|
+
/** @internal */
|
|
9246
9537
|
_textSdf() {
|
|
9247
9538
|
return this.textSdf;
|
|
9248
9539
|
}
|
|
@@ -9255,6 +9546,10 @@ var WeaselRenderer = class {
|
|
|
9255
9546
|
return this.imageFill;
|
|
9256
9547
|
}
|
|
9257
9548
|
/** @internal */
|
|
9549
|
+
_imageFillVOpacity() {
|
|
9550
|
+
return this.imageFillVOpacity;
|
|
9551
|
+
}
|
|
9552
|
+
/** @internal */
|
|
9258
9553
|
_gradFill() {
|
|
9259
9554
|
return this.gradFill;
|
|
9260
9555
|
}
|
|
@@ -9850,6 +10145,82 @@ function clientToCanvas(canvas, clientX, clientY) {
|
|
|
9850
10145
|
function clientToCanvasRect(rect, clientX, clientY) {
|
|
9851
10146
|
return [clientX - rect.left, clientY - rect.top];
|
|
9852
10147
|
}
|
|
10148
|
+
var LOST_CAPTURE_EVENT = "lostpointercapture";
|
|
10149
|
+
function reportsButtons(down) {
|
|
10150
|
+
return !!down.buttons;
|
|
10151
|
+
}
|
|
10152
|
+
function isMissedRelease(move) {
|
|
10153
|
+
return move.buttons === 0;
|
|
10154
|
+
}
|
|
10155
|
+
function openPointerSession(origin, down, cb, opts = {}) {
|
|
10156
|
+
const pointerId = down.pointerId;
|
|
10157
|
+
const doc = origin.ownerDocument ?? document;
|
|
10158
|
+
const buttonsReported = reportsButtons(down);
|
|
10159
|
+
let active = true;
|
|
10160
|
+
const teardown = () => {
|
|
10161
|
+
active = false;
|
|
10162
|
+
doc.removeEventListener("pointermove", onMove, true);
|
|
10163
|
+
doc.removeEventListener("pointerup", onUp, true);
|
|
10164
|
+
doc.removeEventListener("pointercancel", onPointerCancel, true);
|
|
10165
|
+
doc.removeEventListener("pointerdown", onRepress, true);
|
|
10166
|
+
origin.removeEventListener(LOST_CAPTURE_EVENT, onLostCapture);
|
|
10167
|
+
if (opts.capture !== false) {
|
|
10168
|
+
try {
|
|
10169
|
+
origin.releasePointerCapture?.(pointerId);
|
|
10170
|
+
} catch {
|
|
10171
|
+
}
|
|
10172
|
+
}
|
|
10173
|
+
};
|
|
10174
|
+
const mine = (e) => e.pointerId === pointerId;
|
|
10175
|
+
const end = (e) => {
|
|
10176
|
+
if (!active) return;
|
|
10177
|
+
teardown();
|
|
10178
|
+
cb.onEnd?.(e);
|
|
10179
|
+
};
|
|
10180
|
+
const abort = (reason) => {
|
|
10181
|
+
if (!active) return;
|
|
10182
|
+
teardown();
|
|
10183
|
+
cb.onCancel?.(reason);
|
|
10184
|
+
};
|
|
10185
|
+
function onMove(e) {
|
|
10186
|
+
if (!active || !mine(e)) return;
|
|
10187
|
+
if (buttonsReported && isMissedRelease(e)) {
|
|
10188
|
+
end(e);
|
|
10189
|
+
return;
|
|
10190
|
+
}
|
|
10191
|
+
cb.onMove?.(e);
|
|
10192
|
+
}
|
|
10193
|
+
function onUp(e) {
|
|
10194
|
+
if (mine(e)) end(e);
|
|
10195
|
+
}
|
|
10196
|
+
function onPointerCancel(e) {
|
|
10197
|
+
if (mine(e)) abort("pointercancel");
|
|
10198
|
+
}
|
|
10199
|
+
function onRepress(e) {
|
|
10200
|
+
if (mine(e)) abort("superseded");
|
|
10201
|
+
}
|
|
10202
|
+
function onLostCapture(e) {
|
|
10203
|
+
if (e.pointerId === pointerId) abort("lostcapture");
|
|
10204
|
+
}
|
|
10205
|
+
if (opts.capture !== false) {
|
|
10206
|
+
try {
|
|
10207
|
+
origin.setPointerCapture?.(pointerId);
|
|
10208
|
+
} catch {
|
|
10209
|
+
}
|
|
10210
|
+
}
|
|
10211
|
+
doc.addEventListener("pointermove", onMove, true);
|
|
10212
|
+
doc.addEventListener("pointerup", onUp, true);
|
|
10213
|
+
doc.addEventListener("pointercancel", onPointerCancel, true);
|
|
10214
|
+
doc.addEventListener("pointerdown", onRepress, true);
|
|
10215
|
+
origin.addEventListener(LOST_CAPTURE_EVENT, onLostCapture);
|
|
10216
|
+
return {
|
|
10217
|
+
pointerId,
|
|
10218
|
+
get active() {
|
|
10219
|
+
return active;
|
|
10220
|
+
},
|
|
10221
|
+
cancel: () => abort("aborted")
|
|
10222
|
+
};
|
|
10223
|
+
}
|
|
9853
10224
|
var BASE_PX = {
|
|
9854
10225
|
handle: 8,
|
|
9855
10226
|
anchor: 8,
|
|
@@ -11609,6 +11980,28 @@ var cloneAction = {
|
|
|
11609
11980
|
},
|
|
11610
11981
|
enabled: () => true
|
|
11611
11982
|
};
|
|
11983
|
+
function createVelocityTracker() {
|
|
11984
|
+
let samples = [];
|
|
11985
|
+
return {
|
|
11986
|
+
record(dx, dy, t) {
|
|
11987
|
+
samples.push({ dx, dy, t });
|
|
11988
|
+
const cutoff = t - 100;
|
|
11989
|
+
samples = samples.filter((s) => s.t >= cutoff);
|
|
11990
|
+
},
|
|
11991
|
+
getVelocity() {
|
|
11992
|
+
const s = samples;
|
|
11993
|
+
if (s.length < 2) return { vx: 0, vy: 0 };
|
|
11994
|
+
const dt = s[s.length - 1].t - s[0].t;
|
|
11995
|
+
if (dt === 0) return { vx: 0, vy: 0 };
|
|
11996
|
+
const totalDx = s.slice(1).reduce((acc, p) => acc + p.dx, 0);
|
|
11997
|
+
const totalDy = s.slice(1).reduce((acc, p) => acc + p.dy, 0);
|
|
11998
|
+
return { vx: totalDx / dt, vy: totalDy / dt };
|
|
11999
|
+
},
|
|
12000
|
+
reset() {
|
|
12001
|
+
samples = [];
|
|
12002
|
+
}
|
|
12003
|
+
};
|
|
12004
|
+
}
|
|
11612
12005
|
var viewportDragPanAction = {
|
|
11613
12006
|
id: "viewport.dragPan",
|
|
11614
12007
|
label: "Drag to pan viewport",
|
|
@@ -11626,17 +12019,37 @@ var viewportDragPanAction = {
|
|
|
11626
12019
|
requires: ["view"],
|
|
11627
12020
|
invoker: {
|
|
11628
12021
|
timing: "ongoing",
|
|
11629
|
-
start(ctx) {
|
|
12022
|
+
start(ctx, opts) {
|
|
11630
12023
|
const view = ctx.deps.view;
|
|
11631
12024
|
if (!view) return {};
|
|
11632
12025
|
const startView = view.get();
|
|
11633
|
-
const
|
|
12026
|
+
const params = resolveParams(opts?.params) ?? {};
|
|
12027
|
+
const inertia = params.inertia === false ? void 0 : params.inertia;
|
|
12028
|
+
const scratch = {
|
|
12029
|
+
startView,
|
|
12030
|
+
view,
|
|
12031
|
+
axis: params.axis ?? "both",
|
|
12032
|
+
inertia,
|
|
12033
|
+
// Only track when a coast could actually happen, so the common
|
|
12034
|
+
// no-inertia drag does no per-move work.
|
|
12035
|
+
tracker: inertia && view.decay ? createVelocityTracker() : void 0,
|
|
12036
|
+
lastScreen: { x: 0, y: 0 }
|
|
12037
|
+
};
|
|
11634
12038
|
return {
|
|
11635
12039
|
kind: "pan",
|
|
11636
12040
|
onMove(moveCtx) {
|
|
11637
12041
|
if (!moveCtx.drag) return;
|
|
11638
12042
|
const screen = moveCtx.drag.screenDelta ?? moveCtx.drag.delta;
|
|
11639
|
-
const
|
|
12043
|
+
const screenDx = scratch.axis === "y" ? 0 : screen.x;
|
|
12044
|
+
const screenDy = scratch.axis === "x" ? 0 : screen.y;
|
|
12045
|
+
if (scratch.tracker) {
|
|
12046
|
+
scratch.tracker.record(
|
|
12047
|
+
screenDx - scratch.lastScreen.x,
|
|
12048
|
+
screenDy - scratch.lastScreen.y,
|
|
12049
|
+
performance.now()
|
|
12050
|
+
);
|
|
12051
|
+
scratch.lastScreen = { x: screenDx, y: screenDy };
|
|
12052
|
+
}
|
|
11640
12053
|
const sv = scratch.startView;
|
|
11641
12054
|
scratch.view.set({
|
|
11642
12055
|
...sv,
|
|
@@ -11644,7 +12057,24 @@ var viewportDragPanAction = {
|
|
|
11644
12057
|
y: sv.y - screenDy / sv.scale.y
|
|
11645
12058
|
});
|
|
11646
12059
|
},
|
|
11647
|
-
onEnd() {
|
|
12060
|
+
onEnd(_endCtx, reason) {
|
|
12061
|
+
const { tracker, inertia: inertia2, view: v } = scratch;
|
|
12062
|
+
if (reason === "cancel" || !tracker || !inertia2 || !v.decay) return;
|
|
12063
|
+
const { vx, vy } = tracker.getVelocity();
|
|
12064
|
+
const scale2 = scratch.startView.scale;
|
|
12065
|
+
v.decay({
|
|
12066
|
+
// Screen px/ms → world units/ms, matching the onMove conversion.
|
|
12067
|
+
velocity: { vx: -vx / scale2.x, vy: -vy / scale2.y },
|
|
12068
|
+
friction: inertia2.friction,
|
|
12069
|
+
minSpeed: inertia2.minSpeed,
|
|
12070
|
+
boundary: inertia2.boundary,
|
|
12071
|
+
viewBounds: inertia2.bounds,
|
|
12072
|
+
initialPosition: { x: v.get().x, y: v.get().y },
|
|
12073
|
+
onTick: (dx, dy) => {
|
|
12074
|
+
const cur = v.get();
|
|
12075
|
+
v.set({ ...cur, x: cur.x + dx, y: cur.y + dy });
|
|
12076
|
+
}
|
|
12077
|
+
});
|
|
11648
12078
|
}
|
|
11649
12079
|
};
|
|
11650
12080
|
}
|
|
@@ -11745,6 +12175,52 @@ function makeViewportZoomAction(opts = {}) {
|
|
|
11745
12175
|
};
|
|
11746
12176
|
}
|
|
11747
12177
|
makeViewportZoomAction();
|
|
12178
|
+
var viewportWheelPanAction = {
|
|
12179
|
+
id: "viewport.wheelPan",
|
|
12180
|
+
label: "Pan (wheel)",
|
|
12181
|
+
group: "viewport",
|
|
12182
|
+
/**
|
|
12183
|
+
* Plain wheel → pan; Shift+wheel → horizontal pan (axis swap).
|
|
12184
|
+
* Cmd+wheel is claimed by `viewportZoomAction`. The matcher's strict
|
|
12185
|
+
* modifier check keeps the bindings exclusive: omitting `mods` forbids
|
|
12186
|
+
* any modifier, and `mods: { shift: true }` forbids the others.
|
|
12187
|
+
*/
|
|
12188
|
+
defaultBinding: [
|
|
12189
|
+
{ spec: { kind: "wheel" }, opts: {} },
|
|
12190
|
+
{ spec: { kind: "wheel", mods: { shift: true } }, opts: { params: { swapAxis: true } } }
|
|
12191
|
+
],
|
|
12192
|
+
requires: ["view"],
|
|
12193
|
+
invoker: {
|
|
12194
|
+
timing: "immediate",
|
|
12195
|
+
run(deps, params) {
|
|
12196
|
+
const view = deps.view;
|
|
12197
|
+
if (!view) return;
|
|
12198
|
+
const axis = params?.axis ?? "both";
|
|
12199
|
+
const deltaX = params?.deltaX ?? 0;
|
|
12200
|
+
const deltaY = params?.deltaY ?? 0;
|
|
12201
|
+
const current = view.get();
|
|
12202
|
+
const swap = params?.swapAxis === true;
|
|
12203
|
+
const dx = swap ? (deltaX !== 0 ? deltaX : deltaY) / current.scale.x : deltaX / current.scale.x;
|
|
12204
|
+
const dy = swap ? 0 : deltaY / current.scale.y;
|
|
12205
|
+
view.set({
|
|
12206
|
+
...current,
|
|
12207
|
+
x: current.x + (axis === "y" ? 0 : dx),
|
|
12208
|
+
y: current.y + (axis === "x" ? 0 : dy)
|
|
12209
|
+
});
|
|
12210
|
+
}
|
|
12211
|
+
},
|
|
12212
|
+
enabled: () => true
|
|
12213
|
+
};
|
|
12214
|
+
function makeViewportWheelPanAction(opts = {}) {
|
|
12215
|
+
const axis = opts.axis ?? "both";
|
|
12216
|
+
return {
|
|
12217
|
+
...viewportWheelPanAction,
|
|
12218
|
+
defaultBinding: [
|
|
12219
|
+
{ spec: { kind: "wheel" }, opts: { params: { axis } } },
|
|
12220
|
+
{ spec: { kind: "wheel", mods: { shift: true } }, opts: { params: { swapAxis: true, axis } } }
|
|
12221
|
+
]
|
|
12222
|
+
};
|
|
12223
|
+
}
|
|
11748
12224
|
function bodyPredicate(fn) {
|
|
11749
12225
|
return Object.assign(fn, { readsAffordance: false });
|
|
11750
12226
|
}
|
|
@@ -16248,6 +16724,7 @@ function useGestureDispatcher(opts) {
|
|
|
16248
16724
|
};
|
|
16249
16725
|
const heldKeys = /* @__PURE__ */ new Set();
|
|
16250
16726
|
const activePointers = /* @__PURE__ */ new Set();
|
|
16727
|
+
const buttonsReportedFor = /* @__PURE__ */ new Set();
|
|
16251
16728
|
const pointerPositions = /* @__PURE__ */ new Map();
|
|
16252
16729
|
let multiTouchStart = null;
|
|
16253
16730
|
const TAP_THRESHOLD_PX = 8;
|
|
@@ -16390,8 +16867,10 @@ function useGestureDispatcher(opts) {
|
|
|
16390
16867
|
};
|
|
16391
16868
|
const onPointerDown = (e) => {
|
|
16392
16869
|
if ((e.button ?? 0) !== 0) return;
|
|
16870
|
+
if (activePointers.has(e.pointerId)) onPointerUp(e);
|
|
16393
16871
|
routeDown(e.pointerId, e.clientX, e.clientY);
|
|
16394
16872
|
activePointers.add(e.pointerId);
|
|
16873
|
+
if (reportsButtons(e)) buttonsReportedFor.add(e.pointerId);
|
|
16395
16874
|
pointerPositions.set(e.pointerId, { x: e.clientX, y: e.clientY });
|
|
16396
16875
|
try {
|
|
16397
16876
|
canvas?.setPointerCapture?.(e.pointerId);
|
|
@@ -16470,6 +16949,10 @@ function useGestureDispatcher(opts) {
|
|
|
16470
16949
|
}
|
|
16471
16950
|
};
|
|
16472
16951
|
const onPointerMove = (e) => {
|
|
16952
|
+
if (activePointers.has(e.pointerId) && buttonsReportedFor.has(e.pointerId) && isMissedRelease(e)) {
|
|
16953
|
+
onPointerUp(e);
|
|
16954
|
+
return;
|
|
16955
|
+
}
|
|
16473
16956
|
routeAt(e.pointerId, e.clientX, e.clientY);
|
|
16474
16957
|
if (activePointers.has(e.pointerId)) {
|
|
16475
16958
|
pointerPositions.set(e.pointerId, { x: e.clientX, y: e.clientY });
|
|
@@ -16619,6 +17102,7 @@ function useGestureDispatcher(opts) {
|
|
|
16619
17102
|
cancelLongPress(e.pointerId);
|
|
16620
17103
|
const prevSize = activePointers.size;
|
|
16621
17104
|
activePointers.delete(e.pointerId);
|
|
17105
|
+
buttonsReportedFor.delete(e.pointerId);
|
|
16622
17106
|
pointerPositions.delete(e.pointerId);
|
|
16623
17107
|
const staysUnderThreshold = bufferedDown.delete(e.pointerId);
|
|
16624
17108
|
if (prevSize >= 2 && activePointers.size < 2) {
|
|
@@ -16726,6 +17210,7 @@ function useGestureDispatcher(opts) {
|
|
|
16726
17210
|
routeAt(e.pointerId, e.clientX, e.clientY);
|
|
16727
17211
|
cancelLongPress(e.pointerId);
|
|
16728
17212
|
activePointers.delete(e.pointerId);
|
|
17213
|
+
buttonsReportedFor.delete(e.pointerId);
|
|
16729
17214
|
pointerPositions.delete(e.pointerId);
|
|
16730
17215
|
lastPointerDown.delete(e.pointerId);
|
|
16731
17216
|
bufferedDown.delete(e.pointerId);
|
|
@@ -16741,6 +17226,11 @@ function useGestureDispatcher(opts) {
|
|
|
16741
17226
|
dispatch2(ev);
|
|
16742
17227
|
routeRelease(e.pointerId);
|
|
16743
17228
|
};
|
|
17229
|
+
const onLostCapture = (e) => {
|
|
17230
|
+
const pe = e;
|
|
17231
|
+
if (!activePointers.has(pe.pointerId)) return;
|
|
17232
|
+
onPointerCancel(pe);
|
|
17233
|
+
};
|
|
16744
17234
|
const onContextMenu = (e) => {
|
|
16745
17235
|
e.preventDefault();
|
|
16746
17236
|
routeAt(null, e.clientX, e.clientY);
|
|
@@ -16830,6 +17320,7 @@ function useGestureDispatcher(opts) {
|
|
|
16830
17320
|
canvas?.addEventListener("pointermove", onPointerMove);
|
|
16831
17321
|
canvas?.addEventListener("pointerup", onPointerUp);
|
|
16832
17322
|
canvas?.addEventListener("pointercancel", onPointerCancel);
|
|
17323
|
+
canvas?.addEventListener(LOST_CAPTURE_EVENT, onLostCapture);
|
|
16833
17324
|
canvas?.addEventListener("contextmenu", onContextMenu);
|
|
16834
17325
|
canvas?.addEventListener("dragenter", onDragOver);
|
|
16835
17326
|
canvas?.addEventListener("dragover", onDragOver);
|
|
@@ -16850,6 +17341,7 @@ function useGestureDispatcher(opts) {
|
|
|
16850
17341
|
canvas?.removeEventListener("pointermove", onPointerMove);
|
|
16851
17342
|
canvas?.removeEventListener("pointerup", onPointerUp);
|
|
16852
17343
|
canvas?.removeEventListener("pointercancel", onPointerCancel);
|
|
17344
|
+
canvas?.removeEventListener(LOST_CAPTURE_EVENT, onLostCapture);
|
|
16853
17345
|
canvas?.removeEventListener("contextmenu", onContextMenu);
|
|
16854
17346
|
canvas?.removeEventListener("dragenter", onDragOver);
|
|
16855
17347
|
canvas?.removeEventListener("dragover", onDragOver);
|
|
@@ -16864,6 +17356,132 @@ function useGestureDispatcher(opts) {
|
|
|
16864
17356
|
};
|
|
16865
17357
|
}, [enabled, keyboard, canvasRef]);
|
|
16866
17358
|
}
|
|
17359
|
+
var SPRING_DAMPING = 0.5;
|
|
17360
|
+
function useDecayLoop() {
|
|
17361
|
+
const stateRef = useRef(null);
|
|
17362
|
+
const frameLoop = useVisibleRaf(
|
|
17363
|
+
(now) => {
|
|
17364
|
+
tick(now);
|
|
17365
|
+
},
|
|
17366
|
+
{
|
|
17367
|
+
// Coasting does not continue while suspended: dropping `lastTime` makes
|
|
17368
|
+
// the resuming frame seed a fresh interval instead of applying an hour of
|
|
17369
|
+
// friction at once, which would end the decay before it was seen.
|
|
17370
|
+
onResume: useCallback(() => {
|
|
17371
|
+
if (stateRef.current) stateRef.current.lastTime = null;
|
|
17372
|
+
}, [])
|
|
17373
|
+
}
|
|
17374
|
+
);
|
|
17375
|
+
const cancel = useCallback(() => {
|
|
17376
|
+
frameLoop.cancel();
|
|
17377
|
+
stateRef.current = null;
|
|
17378
|
+
}, [frameLoop]);
|
|
17379
|
+
const tick = useCallback((now) => {
|
|
17380
|
+
const s = stateRef.current;
|
|
17381
|
+
if (!s) return;
|
|
17382
|
+
if (s.lastTime === null) {
|
|
17383
|
+
s.lastTime = now;
|
|
17384
|
+
frameLoop.request();
|
|
17385
|
+
return;
|
|
17386
|
+
}
|
|
17387
|
+
const dt = Math.min(now - s.lastTime, 64);
|
|
17388
|
+
s.lastTime = now;
|
|
17389
|
+
const f = Math.pow(s.friction, dt / 16.67);
|
|
17390
|
+
s.vx *= f;
|
|
17391
|
+
s.vy *= f;
|
|
17392
|
+
const speed = Math.sqrt(s.vx * s.vx + s.vy * s.vy);
|
|
17393
|
+
if (speed < s.minSpeed) {
|
|
17394
|
+
stateRef.current = null;
|
|
17395
|
+
frameLoop.cancel();
|
|
17396
|
+
s.onEnd?.();
|
|
17397
|
+
return;
|
|
17398
|
+
}
|
|
17399
|
+
let dx = s.vx * dt;
|
|
17400
|
+
let dy = s.vy * dt;
|
|
17401
|
+
if (s.viewBounds && s.boundary) {
|
|
17402
|
+
const { minX, maxX, minY, maxY } = s.viewBounds;
|
|
17403
|
+
const newX = s.posX + dx;
|
|
17404
|
+
const newY = s.posY + dy;
|
|
17405
|
+
if (s.boundary === "stop") {
|
|
17406
|
+
if (minX !== void 0 && newX < minX) {
|
|
17407
|
+
dx = minX - s.posX;
|
|
17408
|
+
s.vx = 0;
|
|
17409
|
+
} else if (maxX !== void 0 && newX > maxX) {
|
|
17410
|
+
dx = maxX - s.posX;
|
|
17411
|
+
s.vx = 0;
|
|
17412
|
+
}
|
|
17413
|
+
if (minY !== void 0 && newY < minY) {
|
|
17414
|
+
dy = minY - s.posY;
|
|
17415
|
+
s.vy = 0;
|
|
17416
|
+
} else if (maxY !== void 0 && newY > maxY) {
|
|
17417
|
+
dy = maxY - s.posY;
|
|
17418
|
+
s.vy = 0;
|
|
17419
|
+
}
|
|
17420
|
+
} else if (s.boundary === "spring") {
|
|
17421
|
+
if (minX !== void 0 && newX < minX) {
|
|
17422
|
+
dx = minX - s.posX;
|
|
17423
|
+
s.vx = Math.abs(s.vx) * SPRING_DAMPING;
|
|
17424
|
+
} else if (maxX !== void 0 && newX > maxX) {
|
|
17425
|
+
dx = maxX - s.posX;
|
|
17426
|
+
s.vx = -Math.abs(s.vx) * SPRING_DAMPING;
|
|
17427
|
+
}
|
|
17428
|
+
if (minY !== void 0 && newY < minY) {
|
|
17429
|
+
dy = minY - s.posY;
|
|
17430
|
+
s.vy = Math.abs(s.vy) * SPRING_DAMPING;
|
|
17431
|
+
} else if (maxY !== void 0 && newY > maxY) {
|
|
17432
|
+
dy = maxY - s.posY;
|
|
17433
|
+
s.vy = -Math.abs(s.vy) * SPRING_DAMPING;
|
|
17434
|
+
}
|
|
17435
|
+
} else {
|
|
17436
|
+
if (minX !== void 0 && newX < minX) {
|
|
17437
|
+
dx = minX - s.posX;
|
|
17438
|
+
s.vx = Math.abs(s.vx);
|
|
17439
|
+
} else if (maxX !== void 0 && newX > maxX) {
|
|
17440
|
+
dx = maxX - s.posX;
|
|
17441
|
+
s.vx = -Math.abs(s.vx);
|
|
17442
|
+
}
|
|
17443
|
+
if (minY !== void 0 && newY < minY) {
|
|
17444
|
+
dy = minY - s.posY;
|
|
17445
|
+
s.vy = Math.abs(s.vy);
|
|
17446
|
+
} else if (maxY !== void 0 && newY > maxY) {
|
|
17447
|
+
dy = maxY - s.posY;
|
|
17448
|
+
s.vy = -Math.abs(s.vy);
|
|
17449
|
+
}
|
|
17450
|
+
}
|
|
17451
|
+
s.posX += dx;
|
|
17452
|
+
s.posY += dy;
|
|
17453
|
+
}
|
|
17454
|
+
s.onTick(dx, dy);
|
|
17455
|
+
frameLoop.request();
|
|
17456
|
+
}, [frameLoop]);
|
|
17457
|
+
const start = useCallback((config) => {
|
|
17458
|
+
cancel();
|
|
17459
|
+
const { velocity, friction = 0.92, minSpeed = 0.01, viewBounds, boundary, initialPosition, onTick, onEnd } = config;
|
|
17460
|
+
const speed = Math.sqrt(velocity.vx ** 2 + velocity.vy ** 2);
|
|
17461
|
+
if (speed < minSpeed) {
|
|
17462
|
+
onEnd?.();
|
|
17463
|
+
return;
|
|
17464
|
+
}
|
|
17465
|
+
stateRef.current = {
|
|
17466
|
+
vx: velocity.vx,
|
|
17467
|
+
vy: velocity.vy,
|
|
17468
|
+
friction,
|
|
17469
|
+
minSpeed,
|
|
17470
|
+
lastTime: null,
|
|
17471
|
+
posX: initialPosition?.x ?? 0,
|
|
17472
|
+
posY: initialPosition?.y ?? 0,
|
|
17473
|
+
viewBounds,
|
|
17474
|
+
boundary,
|
|
17475
|
+
onTick,
|
|
17476
|
+
onEnd
|
|
17477
|
+
};
|
|
17478
|
+
frameLoop.request();
|
|
17479
|
+
}, [cancel, frameLoop]);
|
|
17480
|
+
useEffect(() => () => {
|
|
17481
|
+
cancel();
|
|
17482
|
+
}, [cancel]);
|
|
17483
|
+
return { start, cancel };
|
|
17484
|
+
}
|
|
16867
17485
|
function dist(a, b) {
|
|
16868
17486
|
return Math.hypot(b.x - a.x, b.y - a.y);
|
|
16869
17487
|
}
|
|
@@ -20485,7 +21103,9 @@ function useRotateTool(adapter, options) {
|
|
|
20485
21103
|
[overlay]
|
|
20486
21104
|
);
|
|
20487
21105
|
}
|
|
20488
|
-
function useHandTool(
|
|
21106
|
+
function useHandTool(opts = {}) {
|
|
21107
|
+
const optsRef = useRef(opts);
|
|
21108
|
+
optsRef.current = opts;
|
|
20489
21109
|
return useMemo(
|
|
20490
21110
|
() => Object.assign(defineViewportTool({
|
|
20491
21111
|
id: "hand",
|
|
@@ -20503,7 +21123,16 @@ function useHandTool(_opts = {}) {
|
|
|
20503
21123
|
// viewportDragPanAction, which also owns the grabbing cursor
|
|
20504
21124
|
// (`Action.activeCursor`) the tool used to declare as an `engaged`
|
|
20505
21125
|
// phase entry.
|
|
20506
|
-
bindings: [{
|
|
21126
|
+
bindings: [{
|
|
21127
|
+
spec: { kind: "drag" },
|
|
21128
|
+
actionId: "viewport.dragPan",
|
|
21129
|
+
opts: {
|
|
21130
|
+
params: () => ({
|
|
21131
|
+
axis: optsRef.current.axis ?? "both",
|
|
21132
|
+
inertia: optsRef.current.inertia
|
|
21133
|
+
})
|
|
21134
|
+
}
|
|
21135
|
+
}]
|
|
20507
21136
|
}),
|
|
20508
21137
|
[]
|
|
20509
21138
|
);
|
|
@@ -21764,6 +22393,20 @@ function projectBounds(b, view) {
|
|
|
21764
22393
|
const [sx, sy] = worldToScreen(b.x, b.y, t);
|
|
21765
22394
|
return { ...b, x: sx, y: sy, width: b.width * view.scale.x, height: b.height * view.scale.y };
|
|
21766
22395
|
}
|
|
22396
|
+
function leavesOf(id, getChildren, isContainer) {
|
|
22397
|
+
if (!isContainer(id)) return [id];
|
|
22398
|
+
const out = [];
|
|
22399
|
+
const visit = (nid) => {
|
|
22400
|
+
const kids = getChildren(nid);
|
|
22401
|
+
if (kids.length === 0) {
|
|
22402
|
+
if (!isContainer(nid)) out.push(nid);
|
|
22403
|
+
return;
|
|
22404
|
+
}
|
|
22405
|
+
for (const k of kids) visit(k);
|
|
22406
|
+
};
|
|
22407
|
+
visit(id);
|
|
22408
|
+
return out;
|
|
22409
|
+
}
|
|
21767
22410
|
function makeContainerAwareBoundsResolver(getPose, getBounds, getChildren, isContainer) {
|
|
21768
22411
|
if (getChildren === void 0 || isContainer === void 0) {
|
|
21769
22412
|
return (id) => {
|
|
@@ -21771,26 +22414,12 @@ function makeContainerAwareBoundsResolver(getPose, getBounds, getChildren, isCon
|
|
|
21771
22414
|
return p === null ? null : getBounds(p);
|
|
21772
22415
|
};
|
|
21773
22416
|
}
|
|
21774
|
-
const leavesOf = (id) => {
|
|
21775
|
-
if (!isContainer(id)) return [id];
|
|
21776
|
-
const out = [];
|
|
21777
|
-
const visit = (nid) => {
|
|
21778
|
-
const kids = getChildren(nid);
|
|
21779
|
-
if (kids.length === 0) {
|
|
21780
|
-
if (!isContainer(nid)) out.push(nid);
|
|
21781
|
-
return;
|
|
21782
|
-
}
|
|
21783
|
-
for (const k of kids) visit(k);
|
|
21784
|
-
};
|
|
21785
|
-
visit(id);
|
|
21786
|
-
return out;
|
|
21787
|
-
};
|
|
21788
22417
|
return (id) => {
|
|
21789
22418
|
if (!isContainer(id)) {
|
|
21790
22419
|
const p = getPose(id);
|
|
21791
22420
|
return p === null ? null : getBounds(p);
|
|
21792
22421
|
}
|
|
21793
|
-
const leaves = leavesOf(id);
|
|
22422
|
+
const leaves = leavesOf(id, getChildren, isContainer);
|
|
21794
22423
|
if (leaves.length === 0) return null;
|
|
21795
22424
|
const leafBounds = [];
|
|
21796
22425
|
for (const leafId of leaves) {
|
|
@@ -22923,7 +23552,7 @@ function CanvasInner(props, ref) {
|
|
|
22923
23552
|
return {
|
|
22924
23553
|
worldX,
|
|
22925
23554
|
worldY,
|
|
22926
|
-
modifiers: m ? { alt: m.alt, shift: m.shift, meta: m.meta, ctrl: m.ctrl
|
|
23555
|
+
modifiers: m ? { alt: m.alt, shift: m.shift, meta: m.meta, ctrl: m.ctrl } : { alt: false, shift: false, meta: false, ctrl: false },
|
|
22927
23556
|
selection: effectiveSelectionRefForCtx.current,
|
|
22928
23557
|
adapter: effectiveAdapterRefForCtx.current,
|
|
22929
23558
|
applyOps: (ops, label) => {
|
|
@@ -26567,10 +27196,10 @@ function boundsOf(coords) {
|
|
|
26567
27196
|
}
|
|
26568
27197
|
return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };
|
|
26569
27198
|
}
|
|
26570
|
-
function useViewDepSource(currentViewRef, onViewChange, recenter, hostSize, animation) {
|
|
26571
|
-
const wiring = useRef({ currentViewRef, onViewChange, recenter, hostSize, animation });
|
|
26572
|
-
wiring.current = { currentViewRef, onViewChange, recenter, hostSize, animation };
|
|
26573
|
-
const shape = `${recenter ? "r" : ""}${hostSize ? "h" : ""}${animation ? "a" : ""}`;
|
|
27199
|
+
function useViewDepSource(currentViewRef, onViewChange, recenter, hostSize, animation, decay) {
|
|
27200
|
+
const wiring = useRef({ currentViewRef, onViewChange, recenter, hostSize, animation, decay });
|
|
27201
|
+
wiring.current = { currentViewRef, onViewChange, recenter, hostSize, animation, decay };
|
|
27202
|
+
const shape = `${recenter ? "r" : ""}${hostSize ? "h" : ""}${animation ? "a" : ""}${decay ? "d" : ""}`;
|
|
26574
27203
|
const shapeRef = useRef(null);
|
|
26575
27204
|
const viewApiRef = useRef(null);
|
|
26576
27205
|
if (viewApiRef.current === null || shapeRef.current !== shape) {
|
|
@@ -26589,6 +27218,10 @@ function useViewDepSource(currentViewRef, onViewChange, recenter, hostSize, anim
|
|
|
26589
27218
|
animate: (to, opts) => wiring.current.animation.animate(to, opts),
|
|
26590
27219
|
stopAnimation: () => wiring.current.animation.stop(),
|
|
26591
27220
|
animationTarget: () => wiring.current.animation.target()
|
|
27221
|
+
} : {},
|
|
27222
|
+
...decay ? {
|
|
27223
|
+
decay: (config) => wiring.current.decay.start(config),
|
|
27224
|
+
stopDecay: () => wiring.current.decay.cancel()
|
|
26592
27225
|
} : {}
|
|
26593
27226
|
};
|
|
26594
27227
|
}
|
|
@@ -27321,7 +27954,6 @@ function useActionsPropResolver(actions) {
|
|
|
27321
27954
|
}
|
|
27322
27955
|
if (!prop) return;
|
|
27323
27956
|
const unregisters = [];
|
|
27324
|
-
const restores = [];
|
|
27325
27957
|
const warnedIds = /* @__PURE__ */ new Set();
|
|
27326
27958
|
for (const [slotId, entry] of Object.entries(prop)) {
|
|
27327
27959
|
if (entry === null) {
|
|
@@ -27349,60 +27981,30 @@ function useActionsPropResolver(actions) {
|
|
|
27349
27981
|
}
|
|
27350
27982
|
const { id: _drop, ...rest } = entry;
|
|
27351
27983
|
const merged = { ...existing, ...rest };
|
|
27352
|
-
restores.push(() => {
|
|
27353
|
-
reg.register(existing);
|
|
27354
|
-
});
|
|
27355
27984
|
unregisters.push(reg.register(merged));
|
|
27356
27985
|
}
|
|
27357
27986
|
return () => {
|
|
27358
27987
|
for (const u of unregisters) u();
|
|
27359
|
-
for (const r of restores) r();
|
|
27360
27988
|
};
|
|
27361
27989
|
}, [reg, actions]);
|
|
27362
27990
|
}
|
|
27363
|
-
var viewportWheelPanAction = {
|
|
27364
|
-
id: "viewport.wheelPan",
|
|
27365
|
-
label: "Pan (wheel)",
|
|
27366
|
-
group: "viewport",
|
|
27367
|
-
/**
|
|
27368
|
-
* Plain wheel → pan; Shift+wheel → horizontal pan (axis swap).
|
|
27369
|
-
* Cmd+wheel is claimed by `viewportZoomAction`. The matcher's strict
|
|
27370
|
-
* modifier check keeps the bindings exclusive: omitting `mods` forbids
|
|
27371
|
-
* any modifier, and `mods: { shift: true }` forbids the others.
|
|
27372
|
-
*/
|
|
27373
|
-
defaultBinding: [
|
|
27374
|
-
{ spec: { kind: "wheel" }, opts: {} },
|
|
27375
|
-
{ spec: { kind: "wheel", mods: { shift: true } }, opts: { params: { swapAxis: true } } }
|
|
27376
|
-
],
|
|
27377
|
-
requires: ["view"],
|
|
27378
|
-
invoker: {
|
|
27379
|
-
timing: "immediate",
|
|
27380
|
-
run(deps, params) {
|
|
27381
|
-
const view = deps.view;
|
|
27382
|
-
if (!view) return;
|
|
27383
|
-
const deltaX = params?.deltaX ?? 0;
|
|
27384
|
-
const deltaY = params?.deltaY ?? 0;
|
|
27385
|
-
const current = view.get();
|
|
27386
|
-
const swap = params?.swapAxis === true;
|
|
27387
|
-
const dx = swap ? (deltaX !== 0 ? deltaX : deltaY) / current.scale.x : deltaX / current.scale.x;
|
|
27388
|
-
const dy = swap ? 0 : deltaY / current.scale.y;
|
|
27389
|
-
view.set({ ...current, x: current.x + dx, y: current.y + dy });
|
|
27390
|
-
}
|
|
27391
|
-
},
|
|
27392
|
-
enabled: () => true
|
|
27393
|
-
};
|
|
27394
27991
|
function useViewportActions(args) {
|
|
27395
27992
|
const { pan, zoom, pinchZoom } = args;
|
|
27396
27993
|
const reg = useActionsRegistry();
|
|
27397
27994
|
const regRef = useRef(reg);
|
|
27398
27995
|
regRef.current = reg;
|
|
27996
|
+
const panKey = typeof pan === "object" ? JSON.stringify(pan) : String(pan);
|
|
27399
27997
|
const zoomKey = typeof zoom === "object" ? JSON.stringify(zoom) : String(zoom);
|
|
27400
27998
|
const pinchKey = typeof pinchZoom === "object" ? JSON.stringify(pinchZoom) : String(pinchZoom);
|
|
27401
27999
|
useEffect(() => {
|
|
27402
28000
|
const r = regRef.current;
|
|
27403
28001
|
if (!r) return;
|
|
27404
28002
|
const unregisters = [];
|
|
27405
|
-
if (pan)
|
|
28003
|
+
if (pan) {
|
|
28004
|
+
unregisters.push(
|
|
28005
|
+
r.register(makeViewportWheelPanAction(typeof pan === "object" ? pan : {}))
|
|
28006
|
+
);
|
|
28007
|
+
}
|
|
27406
28008
|
if (zoom) {
|
|
27407
28009
|
const zoomAction = typeof zoom === "object" ? makeViewportZoomAction(zoom) : makeViewportZoomAction();
|
|
27408
28010
|
unregisters.push(r.register(zoomAction));
|
|
@@ -27417,7 +28019,7 @@ function useViewportActions(args) {
|
|
|
27417
28019
|
return () => {
|
|
27418
28020
|
for (const u of unregisters) u();
|
|
27419
28021
|
};
|
|
27420
|
-
}, [
|
|
28022
|
+
}, [panKey, zoomKey, pinchKey]);
|
|
27421
28023
|
}
|
|
27422
28024
|
function createNodeRouting() {
|
|
27423
28025
|
const entries = [];
|
|
@@ -27841,13 +28443,13 @@ function SceneCanvasInner(props, ref) {
|
|
|
27841
28443
|
const viewportRegistered = !!viewport;
|
|
27842
28444
|
const inertiaEnabled = !!viewport?.inertia;
|
|
27843
28445
|
const inertiaObj = typeof viewport?.inertia === "object" ? viewport.inertia : void 0;
|
|
27844
|
-
const handToolInertia = inertiaEnabled
|
|
27845
|
-
friction: inertiaObj
|
|
27846
|
-
minSpeed: inertiaObj
|
|
27847
|
-
boundary: inertiaObj
|
|
27848
|
-
bounds: inertiaObj
|
|
28446
|
+
const handToolInertia = inertiaEnabled ? {
|
|
28447
|
+
friction: inertiaObj?.friction,
|
|
28448
|
+
minSpeed: inertiaObj?.minSpeed,
|
|
28449
|
+
boundary: inertiaObj?.boundary,
|
|
28450
|
+
bounds: inertiaObj?.bounds
|
|
27849
28451
|
} : void 0;
|
|
27850
|
-
const handTool = useHandTool(handToolInertia ? {} : {});
|
|
28452
|
+
const handTool = useHandTool(handToolInertia ? { inertia: handToolInertia } : {});
|
|
27851
28453
|
const viewportAmbient = [];
|
|
27852
28454
|
const baseRequestedTools = defaultTools ?? (toolBundle ? BUNDLE_TOOLS[toolBundle] : null) ?? (viewportRegistered ? ["select", "rotate", "hand"] : ["select", "rotate"]);
|
|
27853
28455
|
const KNOWN_BUILTIN_IDS = /* @__PURE__ */ new Set([
|
|
@@ -28300,7 +28902,7 @@ function SceneCanvasInner(props, ref) {
|
|
|
28300
28902
|
dispatcher,
|
|
28301
28903
|
getActionRef,
|
|
28302
28904
|
pickEvery: internalPickEvery,
|
|
28303
|
-
viewportPanEnabled: viewport?.pan
|
|
28905
|
+
viewportPanEnabled: viewport?.pan ?? true,
|
|
28304
28906
|
viewportZoom: resolvedViewportZoom,
|
|
28305
28907
|
viewportPinchZoom: viewport?.pinchZoom ?? true,
|
|
28306
28908
|
viewportRecenter: viewport?.recenter,
|
|
@@ -28591,6 +29193,7 @@ function StandardActionsRegistrar({
|
|
|
28591
29193
|
getActionRef.current = null;
|
|
28592
29194
|
};
|
|
28593
29195
|
}, [registry22, getActionRef]);
|
|
29196
|
+
const decayLoop = useDecayLoop();
|
|
28594
29197
|
const view = useViewDepSource(
|
|
28595
29198
|
currentViewRef,
|
|
28596
29199
|
onViewChange,
|
|
@@ -28599,7 +29202,8 @@ function StandardActionsRegistrar({
|
|
|
28599
29202
|
const el = canvasRef.current;
|
|
28600
29203
|
return el ? { width: el.clientWidth, height: el.clientHeight } : null;
|
|
28601
29204
|
},
|
|
28602
|
-
viewAnimation
|
|
29205
|
+
viewAnimation,
|
|
29206
|
+
decayLoop
|
|
28603
29207
|
);
|
|
28604
29208
|
const sceneAsHistory = scene;
|
|
28605
29209
|
useStandardActions({ selection, scene, view, history: sceneAsHistory });
|
|
@@ -29032,8 +29636,7 @@ function MinimapCanvasInner(props) {
|
|
|
29032
29636
|
}, [mainView, mainViewDims, indicatorStyle]);
|
|
29033
29637
|
const extraCommands = useMemo(() => [indicatorCmd], [indicatorCmd]);
|
|
29034
29638
|
const localCanvasRef = useRef(null);
|
|
29035
|
-
const
|
|
29036
|
-
const capturedPointerIdRef = useRef(null);
|
|
29639
|
+
const sessionRef = useRef(null);
|
|
29037
29640
|
const mainViewRef = useRef(mainView);
|
|
29038
29641
|
const mainViewDimsRef = useRef(mainViewDims);
|
|
29039
29642
|
const onMainViewChangeRef = useRef(onMainViewChange);
|
|
@@ -29062,36 +29665,18 @@ function MinimapCanvasInner(props) {
|
|
|
29062
29665
|
}, []);
|
|
29063
29666
|
const handlePointerDown = useCallback((ev) => {
|
|
29064
29667
|
const canvas = localCanvasRef.current;
|
|
29065
|
-
if (!canvas) return;
|
|
29668
|
+
if (!canvas || sessionRef.current) return;
|
|
29066
29669
|
if (ev.pointerType === "mouse" && ev.button !== 0) return;
|
|
29067
|
-
|
|
29068
|
-
|
|
29069
|
-
}
|
|
29070
|
-
|
|
29071
|
-
|
|
29072
|
-
|
|
29073
|
-
|
|
29074
|
-
|
|
29075
|
-
const handlePointerMove = useCallback((ev) => {
|
|
29076
|
-
if (!dragActiveRef.current) return;
|
|
29077
|
-
if (capturedPointerIdRef.current !== null && ev.pointerId !== capturedPointerIdRef.current) {
|
|
29078
|
-
return;
|
|
29079
|
-
}
|
|
29670
|
+
const done = () => {
|
|
29671
|
+
sessionRef.current = null;
|
|
29672
|
+
};
|
|
29673
|
+
sessionRef.current = openPointerSession(canvas, ev, {
|
|
29674
|
+
onMove: recenterFromPointer,
|
|
29675
|
+
onEnd: done,
|
|
29676
|
+
onCancel: done
|
|
29677
|
+
});
|
|
29080
29678
|
recenterFromPointer(ev);
|
|
29081
29679
|
}, [recenterFromPointer]);
|
|
29082
|
-
const releaseCapture = useCallback((ev) => {
|
|
29083
|
-
const canvas = localCanvasRef.current;
|
|
29084
|
-
if (canvas) {
|
|
29085
|
-
try {
|
|
29086
|
-
if (canvas.hasPointerCapture?.(ev.pointerId)) {
|
|
29087
|
-
canvas.releasePointerCapture(ev.pointerId);
|
|
29088
|
-
}
|
|
29089
|
-
} catch {
|
|
29090
|
-
}
|
|
29091
|
-
}
|
|
29092
|
-
dragActiveRef.current = false;
|
|
29093
|
-
capturedPointerIdRef.current = null;
|
|
29094
|
-
}, []);
|
|
29095
29680
|
const setCanvasRef = useCallback((el) => {
|
|
29096
29681
|
localCanvasRef.current = el;
|
|
29097
29682
|
if (typeof canvasRef === "function") {
|
|
@@ -29104,16 +29689,11 @@ function MinimapCanvasInner(props) {
|
|
|
29104
29689
|
const canvas = localCanvasRef.current;
|
|
29105
29690
|
if (!canvas) return;
|
|
29106
29691
|
canvas.addEventListener("pointerdown", handlePointerDown);
|
|
29107
|
-
canvas.addEventListener("pointermove", handlePointerMove);
|
|
29108
|
-
canvas.addEventListener("pointerup", releaseCapture);
|
|
29109
|
-
canvas.addEventListener("pointercancel", releaseCapture);
|
|
29110
29692
|
return () => {
|
|
29111
29693
|
canvas.removeEventListener("pointerdown", handlePointerDown);
|
|
29112
|
-
|
|
29113
|
-
canvas.removeEventListener("pointerup", releaseCapture);
|
|
29114
|
-
canvas.removeEventListener("pointercancel", releaseCapture);
|
|
29694
|
+
sessionRef.current?.cancel();
|
|
29115
29695
|
};
|
|
29116
|
-
}, [handlePointerDown
|
|
29696
|
+
}, [handlePointerDown]);
|
|
29117
29697
|
return /* @__PURE__ */ jsx(
|
|
29118
29698
|
SceneViewCanvas,
|
|
29119
29699
|
{
|
|
@@ -29385,6 +29965,6 @@ function oklchToOklab(L, C, h) {
|
|
|
29385
29965
|
return [L, C * Math.cos(h), C * Math.sin(h)];
|
|
29386
29966
|
}
|
|
29387
29967
|
|
|
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 };
|
|
29389
|
-
//# sourceMappingURL=chunk-
|
|
29390
|
-
//# sourceMappingURL=chunk-
|
|
29968
|
+
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, openPointerSession, rectPath, renderSceneToCanvas, renderSceneToPixels, resolveStrokeWidth, rgbaToHex, sceneFromJSON, textCommand, tileGeometry, useActionsRegistry, useActiveToolContext, useOptionalDepRegistry, useVisibleRaf };
|
|
29969
|
+
//# sourceMappingURL=chunk-DG2IFMLA.js.map
|
|
29970
|
+
//# sourceMappingURL=chunk-DG2IFMLA.js.map
|