stickyflow 0.9.2 → 0.10.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.
Files changed (58) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +1 -1
  3. package/dist/binding/index.cjs +9 -9
  4. package/dist/binding/index.d.cts +3 -3
  5. package/dist/binding/index.d.ts +3 -3
  6. package/dist/binding/index.js +3 -3
  7. package/dist/{chunk-EURX7QT3.cjs → chunk-5PJ55GPG.cjs} +883 -830
  8. package/dist/chunk-5PJ55GPG.cjs.map +1 -0
  9. package/dist/{chunk-AAP24GBG.js → chunk-EGUPN56K.js} +3 -3
  10. package/dist/chunk-EGUPN56K.js.map +1 -0
  11. package/dist/{chunk-Q6FBISNP.js → chunk-HRU6VOEC.js} +545 -331
  12. package/dist/chunk-HRU6VOEC.js.map +1 -0
  13. package/dist/{chunk-3EOG34QN.cjs → chunk-KRSX4UZ7.cjs} +308 -252
  14. package/dist/chunk-KRSX4UZ7.cjs.map +1 -0
  15. package/dist/{chunk-XNNNIOJU.js → chunk-L7CEX5JV.js} +5 -5
  16. package/dist/{chunk-XNNNIOJU.js.map → chunk-L7CEX5JV.js.map} +1 -1
  17. package/dist/{chunk-C25NWWIH.cjs → chunk-LSEMXRB5.cjs} +549 -331
  18. package/dist/chunk-LSEMXRB5.cjs.map +1 -0
  19. package/dist/{chunk-MR32IJQO.cjs → chunk-SCD3AHMY.cjs} +15 -15
  20. package/dist/chunk-SCD3AHMY.cjs.map +1 -0
  21. package/dist/{chunk-G2N3KJYJ.js → chunk-SDOHUNBW.js} +237 -184
  22. package/dist/chunk-SDOHUNBW.js.map +1 -0
  23. package/dist/{chunk-2GKXPZRL.cjs → chunk-TECWZVIM.cjs} +23 -23
  24. package/dist/chunk-TECWZVIM.cjs.map +1 -0
  25. package/dist/{chunk-C3LVKPWQ.js → chunk-VPNOVRWP.js} +279 -223
  26. package/dist/chunk-VPNOVRWP.js.map +1 -0
  27. package/dist/index.cjs +36 -36
  28. package/dist/index.d.cts +33 -28
  29. package/dist/index.d.ts +33 -28
  30. package/dist/index.js +5 -5
  31. package/dist/interaction/index.cjs +358 -337
  32. package/dist/interaction/index.cjs.map +1 -1
  33. package/dist/interaction/index.js +133 -112
  34. package/dist/interaction/index.js.map +1 -1
  35. package/dist/{runtime-DG8X3Fwf.d.cts → runtime-Bkv7QW7H.d.cts} +1 -1
  36. package/dist/{runtime-kqD1RS17.d.ts → runtime-DJ4K4_HZ.d.ts} +1 -1
  37. package/dist/{runtimeTypes-CvjlBZds.d.cts → runtimeTypes-BvJBZLkr.d.cts} +1 -1
  38. package/dist/{runtimeTypes-vRaHOIHi.d.ts → runtimeTypes-C1shzoyr.d.ts} +1 -1
  39. package/dist/stickyflow-diagram.global.js +41 -41
  40. package/dist/stickyflow-diagram.global.js.map +1 -1
  41. package/dist/viewer/index.cjs +9 -9
  42. package/dist/viewer/index.d.cts +1 -1
  43. package/dist/viewer/index.d.ts +1 -1
  44. package/dist/viewer/index.js +4 -4
  45. package/dist/web-component/index.cjs +6 -6
  46. package/dist/web-component/index.cjs.map +1 -1
  47. package/dist/web-component/index.js +4 -4
  48. package/dist/web-component/index.js.map +1 -1
  49. package/package.json +1 -1
  50. package/dist/chunk-2GKXPZRL.cjs.map +0 -1
  51. package/dist/chunk-3EOG34QN.cjs.map +0 -1
  52. package/dist/chunk-AAP24GBG.js.map +0 -1
  53. package/dist/chunk-C25NWWIH.cjs.map +0 -1
  54. package/dist/chunk-C3LVKPWQ.js.map +0 -1
  55. package/dist/chunk-EURX7QT3.cjs.map +0 -1
  56. package/dist/chunk-G2N3KJYJ.js.map +0 -1
  57. package/dist/chunk-MR32IJQO.cjs.map +0 -1
  58. package/dist/chunk-Q6FBISNP.js.map +0 -1
@@ -1,6 +1,6 @@
1
- import { render } from './chunk-G2N3KJYJ.js';
2
- import { parseContractVersion, isContractCompatible, Emitter, resolveOwner, CHANGE_COLOR, findOwnerNode, isPrimary, linkSelectionOverlay, pathSelectionOverlay, isometricSelectionOverlay, shapeSelectionOverlay, DERIVED_HEIGHT_ROLES, quickDuplicateBubbles, isCameraGesture, linkChangeOverlay, shapeChangeOverlay, startChangeFade, REDUCED_MOTION_DURATION_MS, FLASH_DURATION_MS } from './chunk-AAP24GBG.js';
3
- import { getComponentDescriptor, formatRollingNumber, DEFAULT_ROLLING_NUMBER_STYLE } from './chunk-Q6FBISNP.js';
1
+ import { render } from './chunk-SDOHUNBW.js';
2
+ import { parseContractVersion, isContractCompatible, Emitter, resolveOwner, CHANGE_COLOR, findOwnerNode, isPrimary, linkSelectionOverlay, pathSelectionOverlay, isometricSelectionOverlay, shapeSelectionOverlay, DERIVED_HEIGHT_ROLES, quickDuplicateBubbles, isCameraGesture, linkChangeOverlay, shapeChangeOverlay, startChangeFade, REDUCED_MOTION_DURATION_MS, FLASH_DURATION_MS } from './chunk-EGUPN56K.js';
3
+ import { getComponentDescriptor, formatRollingNumber, DEFAULT_ROLLING_NUMBER_STYLE, parseHexRgb } from './chunk-HRU6VOEC.js';
4
4
 
5
5
  // src/runtime/viewer/components/rollingNumberDom.ts
6
6
  var HTML_NAMESPACE = "http://www.w3.org/1999/xhtml";
@@ -275,10 +275,14 @@ function parameters(surface) {
275
275
  function positive(value, fallback) {
276
276
  return Number(value) > 0 ? Number(value) : fallback;
277
277
  }
278
+ function rangeOf(params) {
279
+ return {
280
+ min: Number(params.min) || 0,
281
+ max: Number.isFinite(Number(params.max)) && params.max !== void 0 ? Number(params.max) : 100
282
+ };
283
+ }
278
284
  function rulerProgress(surface, value) {
279
- const params = parameters(surface);
280
- const min = Number(params.min) || 0;
281
- const max = Number.isFinite(Number(params.max)) && params.max !== void 0 ? Number(params.max) : 100;
285
+ const { min, max } = rangeOf(parameters(surface));
282
286
  return clamp01(max === min ? 0 : (value - min) / (max - min));
283
287
  }
284
288
  function move(node, dx, dy) {
@@ -289,19 +293,11 @@ function move(node, dx, dy) {
289
293
  written.set(node, next);
290
294
  node.setAttribute("transform", next);
291
295
  }
292
- function hexToRgb(value) {
293
- const match = /^#([0-9a-f]{6})$/i.exec(value.trim());
294
- if (!match) {
295
- return null;
296
- }
297
- const number2 = parseInt(match[1], 16);
298
- return [number2 >> 16 & 255, number2 >> 8 & 255, number2 & 255];
299
- }
300
296
  var WHITE = [255, 255, 255];
301
297
  function shade(node, bump, target) {
302
298
  const base = fills.get(node) ?? node.getAttribute("fill") ?? "";
303
299
  fills.set(node, base);
304
- const rgb = hexToRgb(base);
300
+ const rgb = parseHexRgb(base);
305
301
  if (!rgb) {
306
302
  return;
307
303
  }
@@ -312,61 +308,84 @@ function shade(node, bump, target) {
312
308
  child.style.fill = fill;
313
309
  }
314
310
  }
311
+ function rulerOf(surface, progressOf) {
312
+ const params = parameters(surface);
313
+ const id = surface.getAttribute("data-sf-id") ?? "";
314
+ const width = Number(surface.getAttribute("width"));
315
+ const height = Number(surface.getAttribute("height"));
316
+ const horizontal = params.axis === "horizontal";
317
+ const across = horizontal ? height : width;
318
+ const dent = params.dent === void 0 ? 1 : Number(params.dent);
319
+ return {
320
+ id,
321
+ params,
322
+ x: Number(surface.getAttribute("x")),
323
+ y: Number(surface.getAttribute("y")),
324
+ width,
325
+ height,
326
+ horizontal,
327
+ progress: clamp01(progressOf(id) ?? Number(params.progress)),
328
+ inset: positive(params.inset, 0.05),
329
+ extent: horizontal ? width : height,
330
+ across,
331
+ depth: (dent < 0 ? 1 : dent) * 0.16 * across
332
+ };
333
+ }
334
+ function placeKnob(svg, ruler) {
335
+ const { params, x, y, width, height, horizontal, across, depth } = ruler;
336
+ const knobId = typeof params.knob === "string" ? params.knob : "";
337
+ if (!knobId) {
338
+ return void 0;
339
+ }
340
+ const nodes = [...svg.querySelectorAll(`[data-sf-id="${CSS.escape(knobId)}"]`)];
341
+ const primary = nodes.find((node) => node.hasAttribute("data-sf-primary"));
342
+ if (!primary?.getBBox) {
343
+ return void 0;
344
+ }
345
+ move(primary, 0, 0);
346
+ const box = primary.getBBox();
347
+ const half = (horizontal ? box.height : box.width) / 2;
348
+ const along = ruler.inset + (1 - 2 * ruler.inset) * ruler.progress;
349
+ const line = positive(params.line, 0.7);
350
+ const gap = (params.gap === void 0 ? 0.04 : Number(params.gap)) * across;
351
+ const side = line * across - depth + half + gap;
352
+ const target = horizontal ? { x: x + width * along, y: y + side } : { x: x + side, y: y + height * (1 - along) };
353
+ const dx = target.x - (box.x + box.width / 2);
354
+ const dy = target.y - (box.y + box.height / 2);
355
+ for (const node of nodes) {
356
+ move(node, dx, dy);
357
+ }
358
+ return half / across;
359
+ }
360
+ function liftLabels(svg, ruler) {
361
+ const { id, params, horizontal, extent, inset, progress, depth } = ruler;
362
+ const { min, max } = rangeOf(params);
363
+ const peak = (typeof params.peak === "string" ? parseHexRgb(params.peak) : null) ?? WHITE;
364
+ const spread = positive(params.spread, 0.07) * extent;
365
+ const start = inset * extent;
366
+ const span = (1 - 2 * inset) * extent;
367
+ const knobAt = start + span * progress;
368
+ for (const label of svg.querySelectorAll(`text[data-sf-id="${CSS.escape(id)}"]`)) {
369
+ const value = Number(label.textContent);
370
+ if (!Number.isFinite(value) || max === min) {
371
+ continue;
372
+ }
373
+ const labelAt = start + span * clamp01((value - min) / (max - min));
374
+ const bump = Math.exp(-(((labelAt - knobAt) / spread) ** 2));
375
+ const shift = depth * 0.4 * bump;
376
+ move(label, horizontal ? 0 : -shift, horizontal ? -shift : 0);
377
+ shade(label, bump, peak);
378
+ }
379
+ }
315
380
  function placeRulerKnobs(svg, progressOf) {
316
381
  const radii = /* @__PURE__ */ new Map();
317
382
  for (const surface of svg.querySelectorAll('foreignObject[data-sf-shader="ruler"]')) {
318
- const params = parameters(surface);
319
- const peak = (typeof params.peak === "string" ? hexToRgb(params.peak) : null) ?? WHITE;
320
- const id = surface.getAttribute("data-sf-id") ?? "";
321
- const x = Number(surface.getAttribute("x"));
322
- const y = Number(surface.getAttribute("y"));
323
- const width = Number(surface.getAttribute("width"));
324
- const height = Number(surface.getAttribute("height"));
325
- const horizontal = params.axis === "horizontal";
326
- const progress = clamp01(progressOf(id) ?? Number(params.progress));
327
- const inset = positive(params.inset, 0.05);
328
- const line = positive(params.line, 0.7);
329
- const extent = horizontal ? width : height;
330
- const across = horizontal ? height : width;
331
- const along = inset + (1 - 2 * inset) * progress;
332
- const dent = params.dent === void 0 ? 1 : Number(params.dent);
333
- const depth = (dent < 0 ? 1 : dent) * 0.16 * across;
334
- const knobId = typeof params.knob === "string" ? params.knob : "";
335
- if (knobId) {
336
- const nodes = [...svg.querySelectorAll(`[data-sf-id="${CSS.escape(knobId)}"]`)];
337
- const primary = nodes.find((node) => node.hasAttribute("data-sf-primary"));
338
- if (primary?.getBBox) {
339
- move(primary, 0, 0);
340
- const box = primary.getBBox();
341
- const half = (horizontal ? box.height : box.width) / 2;
342
- radii.set(id, half / across);
343
- const gap = (params.gap === void 0 ? 0.04 : Number(params.gap)) * across;
344
- const side = line * across - depth + half + gap;
345
- const target = horizontal ? { x: x + width * along, y: y + side } : { x: x + side, y: y + height * (1 - along) };
346
- const dx = target.x - (box.x + box.width / 2);
347
- const dy = target.y - (box.y + box.height / 2);
348
- for (const node of nodes) {
349
- move(node, dx, dy);
350
- }
351
- }
352
- }
353
- const min = Number(params.min) || 0;
354
- const max = Number.isFinite(Number(params.max)) && params.max !== void 0 ? Number(params.max) : 100;
355
- const spread = positive(params.spread, 0.07) * extent;
356
- const start = inset * extent;
357
- const span = (1 - 2 * inset) * extent;
358
- const knobAt = start + span * progress;
359
- for (const label of svg.querySelectorAll(`text[data-sf-id="${CSS.escape(id)}"]`)) {
360
- const value = Number(label.textContent);
361
- if (!Number.isFinite(value) || max === min) {
362
- continue;
363
- }
364
- const labelAt = start + span * clamp01((value - min) / (max - min));
365
- const bump = Math.exp(-(((labelAt - knobAt) / spread) ** 2));
366
- const shift = depth * 0.4 * bump;
367
- move(label, horizontal ? 0 : -shift, horizontal ? -shift : 0);
368
- shade(label, bump, peak);
383
+ const ruler = rulerOf(surface, progressOf);
384
+ const radius = placeKnob(svg, ruler);
385
+ if (radius !== void 0) {
386
+ radii.set(ruler.id, radius);
369
387
  }
388
+ liftLabels(svg, ruler);
370
389
  }
371
390
  return radii;
372
391
  }
@@ -4042,8 +4061,7 @@ function applyBackdrop(surface, backdrop) {
4042
4061
  }
4043
4062
  var MAX_SURFACE_PIXELS = 2560;
4044
4063
  var TRAIL_LENGTH = 16;
4045
- function renderSurface(surface, seconds) {
4046
- const { canvas, gl, parameters: parameters3 } = surface;
4064
+ function fitCanvas(canvas) {
4047
4065
  const shown = canvas.getBoundingClientRect();
4048
4066
  const density = Math.min(globalThis.devicePixelRatio || 1, 3);
4049
4067
  const fit = Math.min(1, MAX_SURFACE_PIXELS / Math.max(1, shown.width * density, shown.height * density));
@@ -4053,32 +4071,22 @@ function renderSurface(surface, seconds) {
4053
4071
  canvas.width = width;
4054
4072
  canvas.height = height;
4055
4073
  }
4056
- gl.viewport(0, 0, width, height);
4057
- gl.clearColor(0, 0, 0, 0);
4058
- gl.clear(gl.COLOR_BUFFER_BIT);
4059
- gl.useProgram(surface.program);
4060
- const resolution = gl.getUniformLocation(surface.program, "uResolution");
4061
- if (resolution) {
4062
- gl.uniform2f(resolution, width, height);
4063
- }
4064
- const logicalWidth = Number(surface.owner.getAttribute("width"));
4065
- uniform1f(
4066
- surface,
4067
- "uPixelScale",
4068
- Number.isFinite(logicalWidth) && logicalWidth > 0 ? width / logicalWidth : density * fit
4069
- );
4070
- uniform1f(surface, "uTime", seconds);
4071
- if (surface.backdropTexture) {
4072
- syncBackdropBounds(surface);
4073
- gl.activeTexture(gl.TEXTURE0);
4074
- gl.bindTexture(gl.TEXTURE_2D, surface.backdropTexture);
4075
- const sampler = gl.getUniformLocation(surface.program, "uBackdrop");
4076
- if (sampler) {
4077
- gl.uniform1i(sampler, 0);
4078
- }
4079
- uniform2f(surface, "uBackdropOrigin", surface.backdropOrigin);
4080
- uniform2f(surface, "uBackdropScale", surface.backdropScale);
4074
+ return { width, height, density, fit };
4075
+ }
4076
+ function bindBackdrop(surface, texture) {
4077
+ const { gl } = surface;
4078
+ syncBackdropBounds(surface);
4079
+ gl.activeTexture(gl.TEXTURE0);
4080
+ gl.bindTexture(gl.TEXTURE_2D, texture);
4081
+ const sampler = gl.getUniformLocation(surface.program, "uBackdrop");
4082
+ if (sampler) {
4083
+ gl.uniform1i(sampler, 0);
4081
4084
  }
4085
+ uniform2f(surface, "uBackdropOrigin", surface.backdropOrigin);
4086
+ uniform2f(surface, "uBackdropScale", surface.backdropScale);
4087
+ }
4088
+ function uploadParameters(surface) {
4089
+ const { parameters: parameters3 } = surface;
4082
4090
  for (const [key, fallback] of Object.entries(SHADER_DEFAULTS.numbers)) {
4083
4091
  uniform1f(surface, uniformName(key), number(parameters3[key], fallback));
4084
4092
  }
@@ -4086,9 +4094,9 @@ function renderSurface(surface, seconds) {
4086
4094
  uniform3f(surface, uniformName(key), color(parameters3[key], [...fallback]));
4087
4095
  }
4088
4096
  uniform3f(surface, "uShapeColor", surface.shapeColor);
4089
- const elapsed = surface.lastSeconds === void 0 ? 0 : Math.max(0, Math.min(seconds - surface.lastSeconds, 0.1));
4090
- surface.lastSeconds = seconds;
4091
- applyParameters(surface, elapsed);
4097
+ }
4098
+ function uploadPointer(surface, seconds, elapsed) {
4099
+ const { gl, parameters: parameters3 } = surface;
4092
4100
  surface.hover += ((surface.hovering ? 1 : 0) - surface.hover) * (1 - Math.exp(-elapsed / 0.18));
4093
4101
  uniform2f(surface, "uPointer", [surface.pointer.x, surface.pointer.y]);
4094
4102
  uniform1f(surface, "uHover", surface.hover);
@@ -4103,13 +4111,44 @@ function renderSurface(surface, seconds) {
4103
4111
  if (trail) {
4104
4112
  gl.uniform3fv(trail, places);
4105
4113
  }
4106
- if (surface.reactiveLight) {
4107
- uniform1f(surface, "uLightX", surface.reactiveLight.x);
4108
- uniform1f(surface, "uLightY", surface.reactiveLight.y);
4109
- uniform1f(surface, "uLightStrength", surface.reactiveLight.strength);
4110
- uniform1f(surface, "uGlowRadius", surface.reactiveLight.radius);
4111
- uniform3f(surface, "uLightColor", surface.reactiveLight.color);
4114
+ }
4115
+ function uploadReactiveLight(surface) {
4116
+ if (!surface.reactiveLight) {
4117
+ return;
4112
4118
  }
4119
+ uniform1f(surface, "uLightX", surface.reactiveLight.x);
4120
+ uniform1f(surface, "uLightY", surface.reactiveLight.y);
4121
+ uniform1f(surface, "uLightStrength", surface.reactiveLight.strength);
4122
+ uniform1f(surface, "uGlowRadius", surface.reactiveLight.radius);
4123
+ uniform3f(surface, "uLightColor", surface.reactiveLight.color);
4124
+ }
4125
+ function renderSurface(surface, seconds) {
4126
+ const { canvas, gl } = surface;
4127
+ const { width, height, density, fit } = fitCanvas(canvas);
4128
+ gl.viewport(0, 0, width, height);
4129
+ gl.clearColor(0, 0, 0, 0);
4130
+ gl.clear(gl.COLOR_BUFFER_BIT);
4131
+ gl.useProgram(surface.program);
4132
+ const resolution = gl.getUniformLocation(surface.program, "uResolution");
4133
+ if (resolution) {
4134
+ gl.uniform2f(resolution, width, height);
4135
+ }
4136
+ const logicalWidth = Number(surface.owner.getAttribute("width"));
4137
+ uniform1f(
4138
+ surface,
4139
+ "uPixelScale",
4140
+ Number.isFinite(logicalWidth) && logicalWidth > 0 ? width / logicalWidth : density * fit
4141
+ );
4142
+ uniform1f(surface, "uTime", seconds);
4143
+ if (surface.backdropTexture) {
4144
+ bindBackdrop(surface, surface.backdropTexture);
4145
+ }
4146
+ uploadParameters(surface);
4147
+ const elapsed = surface.lastSeconds === void 0 ? 0 : Math.max(0, Math.min(seconds - surface.lastSeconds, 0.1));
4148
+ surface.lastSeconds = seconds;
4149
+ applyParameters(surface, elapsed);
4150
+ uploadPointer(surface, seconds, elapsed);
4151
+ uploadReactiveLight(surface);
4113
4152
  uniform1f(surface, "uSurfacePadding", surface.surfacePadding);
4114
4153
  gl.drawArrays(gl.TRIANGLES, 0, 6);
4115
4154
  }
@@ -4184,152 +4223,169 @@ function watchSvgChanges(svg, view, onChange) {
4184
4223
  sizes?.disconnect();
4185
4224
  };
4186
4225
  }
4187
- function mountShaderSurfaces(svg) {
4188
- let surfaces = [];
4189
- let frame;
4190
- let backdropGeneration = 0;
4191
- let recapture;
4192
- const view = svg.ownerDocument.defaultView;
4193
- const clock = createSurfaceClock(view);
4194
- const draw = (milliseconds) => {
4195
- if (!clock.paused()) {
4196
- updateReactiveLightFields(surfaces);
4197
- for (const surface of surfaces) {
4198
- renderSurface(surface, milliseconds / 1e3 - clock.spent());
4226
+ function rememberSurfaces(surfaces) {
4227
+ return new Map(
4228
+ surfaces.flatMap((surface) => {
4229
+ const ownerId = surface.owner.getAttribute("data-sf-id");
4230
+ return ownerId ? [
4231
+ [
4232
+ ownerId,
4233
+ {
4234
+ smoothed: new Map(surface.smoothed),
4235
+ reactiveLight: surface.reactiveLight,
4236
+ pointer: surface.pointer,
4237
+ hover: surface.hover,
4238
+ hovering: surface.hovering,
4239
+ trail: surface.trail
4240
+ }
4241
+ ]
4242
+ ] : [];
4243
+ })
4244
+ );
4245
+ }
4246
+ function createSurfaces(svg, memory) {
4247
+ return [...svg.querySelectorAll("canvas[data-sf-shader-canvas]")].flatMap((canvas) => {
4248
+ const surface = createSurface(canvas);
4249
+ const ownerId = surface?.owner.getAttribute("data-sf-id");
4250
+ const previous = ownerId ? memory.get(ownerId) : void 0;
4251
+ if (surface && previous) {
4252
+ Object.assign(surface, previous);
4253
+ }
4254
+ return surface ? [surface] : [];
4255
+ });
4256
+ }
4257
+ function followPointer(surface, event, now) {
4258
+ const box = surface.canvas.getBoundingClientRect();
4259
+ const inside = box.width > 0 && box.height > 0 && event.clientX >= box.left && event.clientX <= box.right && event.clientY >= box.top && event.clientY <= box.bottom;
4260
+ surface.hovering = inside;
4261
+ if (!inside) {
4262
+ return;
4263
+ }
4264
+ surface.pointer = { x: (event.clientX - box.left) / box.width, y: 1 - (event.clientY - box.top) / box.height };
4265
+ const last = surface.trail[surface.trail.length - 1];
4266
+ if (!last || now - last.at >= TRAIL_SPACING) {
4267
+ surface.trail.push({ ...surface.pointer, at: now });
4268
+ if (surface.trail.length > TRAIL_LENGTH2) {
4269
+ surface.trail.shift();
4270
+ }
4271
+ }
4272
+ }
4273
+ var ShaderSurfaces = class {
4274
+ constructor(svg) {
4275
+ this.svg = svg;
4276
+ this.view = svg.ownerDocument.defaultView;
4277
+ this.clock = createSurfaceClock(this.view);
4278
+ this.unwatch = watchSvgChanges(svg, this.view, this.scheduleRecapture);
4279
+ svg.addEventListener("pointermove", this.track);
4280
+ svg.addEventListener("pointerleave", this.leave);
4281
+ this.refresh();
4282
+ }
4283
+ svg;
4284
+ surfaces = [];
4285
+ frame;
4286
+ backdropGeneration = 0;
4287
+ recapture;
4288
+ view;
4289
+ clock;
4290
+ unwatch;
4291
+ capture() {
4292
+ return capturePngs(this.svg, this.surfaces, this.clock.now());
4293
+ }
4294
+ setParameters(ownerId, parameters3) {
4295
+ return updateParameters(this.surfaces, ownerId, parameters3, this.clock.now());
4296
+ }
4297
+ setPaused(paused) {
4298
+ this.clock.setPaused(paused);
4299
+ }
4300
+ refresh() {
4301
+ const memory = rememberSurfaces(this.surfaces);
4302
+ this.stop();
4303
+ const generation = ++this.backdropGeneration;
4304
+ this.surfaces = createSurfaces(this.svg, memory);
4305
+ updateReactiveLightFields(this.surfaces);
4306
+ this.captureBackdrops(generation);
4307
+ if (this.surfaces.length > 0) {
4308
+ this.startFrames();
4309
+ }
4310
+ }
4311
+ destroy() {
4312
+ this.backdropGeneration += 1;
4313
+ this.unwatch();
4314
+ this.svg.removeEventListener("pointermove", this.track);
4315
+ this.svg.removeEventListener("pointerleave", this.leave);
4316
+ if (this.recapture !== void 0) {
4317
+ this.view?.clearTimeout(this.recapture);
4318
+ }
4319
+ this.stop();
4320
+ }
4321
+ draw = (milliseconds) => {
4322
+ if (!this.clock.paused()) {
4323
+ updateReactiveLightFields(this.surfaces);
4324
+ for (const surface of this.surfaces) {
4325
+ renderSurface(surface, milliseconds / 1e3 - this.clock.spent());
4199
4326
  }
4200
4327
  }
4201
- frame = view?.requestAnimationFrame(draw);
4328
+ this.frame = this.view?.requestAnimationFrame(this.draw);
4202
4329
  };
4203
- const stop = () => {
4204
- if (frame !== void 0) {
4205
- view?.cancelAnimationFrame(frame);
4206
- frame = void 0;
4330
+ stop() {
4331
+ if (this.frame !== void 0) {
4332
+ this.view?.cancelAnimationFrame(this.frame);
4333
+ this.frame = void 0;
4207
4334
  }
4208
- for (const surface of surfaces) {
4335
+ for (const surface of this.surfaces) {
4209
4336
  releaseSurface(surface);
4210
4337
  }
4211
- surfaces = [];
4212
- };
4213
- const captureBackdrops = (generation) => {
4214
- for (const surface of surfaces) {
4338
+ this.surfaces = [];
4339
+ }
4340
+ captureBackdrops(generation) {
4341
+ for (const surface of this.surfaces) {
4215
4342
  if (!surface.usesBackdrop) {
4216
4343
  continue;
4217
4344
  }
4218
- void captureShaderBackdrop(svg, surface.owner).then((backdrop) => {
4219
- if (backdrop && generation === backdropGeneration) {
4345
+ void captureShaderBackdrop(this.svg, surface.owner).then((backdrop) => {
4346
+ if (backdrop && generation === this.backdropGeneration) {
4220
4347
  applyBackdrop(surface, backdrop);
4221
4348
  }
4222
4349
  });
4223
4350
  }
4224
- };
4225
- const startFrames = () => {
4226
- if (!view?.requestAnimationFrame) {
4227
- for (const surface of surfaces) {
4351
+ }
4352
+ startFrames() {
4353
+ if (!this.view?.requestAnimationFrame) {
4354
+ for (const surface of this.surfaces) {
4228
4355
  renderSurface(surface, 0);
4229
4356
  }
4230
4357
  return;
4231
4358
  }
4232
- if (clock.paused()) {
4233
- for (const surface of surfaces) {
4234
- renderSurface(surface, clock.now());
4235
- }
4236
- }
4237
- frame = view.requestAnimationFrame(draw);
4238
- };
4239
- const refresh = () => {
4240
- const previousState = new Map(
4241
- surfaces.flatMap((surface) => {
4242
- const ownerId = surface.owner.getAttribute("data-sf-id");
4243
- return ownerId ? [
4244
- [
4245
- ownerId,
4246
- {
4247
- smoothed: new Map(surface.smoothed),
4248
- reactiveLight: surface.reactiveLight,
4249
- pointer: surface.pointer,
4250
- hover: surface.hover,
4251
- hovering: surface.hovering,
4252
- trail: surface.trail
4253
- }
4254
- ]
4255
- ] : [];
4256
- })
4257
- );
4258
- stop();
4259
- const generation = ++backdropGeneration;
4260
- surfaces = [...svg.querySelectorAll("canvas[data-sf-shader-canvas]")].flatMap((canvas) => {
4261
- const surface = createSurface(canvas);
4262
- const ownerId = surface?.owner.getAttribute("data-sf-id");
4263
- const previous = ownerId ? previousState.get(ownerId) : void 0;
4264
- if (surface && previous) {
4265
- surface.smoothed = previous.smoothed;
4266
- surface.reactiveLight = previous.reactiveLight;
4267
- surface.pointer = previous.pointer;
4268
- surface.hover = previous.hover;
4269
- surface.hovering = previous.hovering;
4270
- surface.trail = previous.trail;
4359
+ if (this.clock.paused()) {
4360
+ for (const surface of this.surfaces) {
4361
+ renderSurface(surface, this.clock.now());
4271
4362
  }
4272
- return surface ? [surface] : [];
4273
- });
4274
- updateReactiveLightFields(surfaces);
4275
- captureBackdrops(generation);
4276
- if (surfaces.length > 0) {
4277
- startFrames();
4278
4363
  }
4279
- };
4280
- const scheduleRecapture = () => {
4281
- if (recapture !== void 0) {
4282
- view?.clearTimeout(recapture);
4364
+ this.frame = this.view.requestAnimationFrame(this.draw);
4365
+ }
4366
+ scheduleRecapture = () => {
4367
+ if (this.recapture !== void 0) {
4368
+ this.view?.clearTimeout(this.recapture);
4283
4369
  }
4284
- recapture = view?.setTimeout(() => {
4285
- recapture = void 0;
4286
- captureBackdrops(backdropGeneration);
4370
+ this.recapture = this.view?.setTimeout(() => {
4371
+ this.recapture = void 0;
4372
+ this.captureBackdrops(this.backdropGeneration);
4287
4373
  }, RECAPTURE_DELAY_MS);
4288
4374
  };
4289
- const unwatch = watchSvgChanges(svg, view, scheduleRecapture);
4290
- const track = (event) => {
4291
- for (const surface of surfaces) {
4292
- const box = surface.canvas.getBoundingClientRect();
4293
- const inside = box.width > 0 && box.height > 0 && event.clientX >= box.left && event.clientX <= box.right && event.clientY >= box.top && event.clientY <= box.bottom;
4294
- surface.hovering = inside;
4295
- if (inside) {
4296
- surface.pointer = { x: (event.clientX - box.left) / box.width, y: 1 - (event.clientY - box.top) / box.height };
4297
- const now = clock.now();
4298
- const last = surface.trail[surface.trail.length - 1];
4299
- if (!last || now - last.at >= TRAIL_SPACING) {
4300
- surface.trail.push({ ...surface.pointer, at: now });
4301
- if (surface.trail.length > TRAIL_LENGTH2) {
4302
- surface.trail.shift();
4303
- }
4304
- }
4305
- }
4375
+ track = (event) => {
4376
+ const now = this.clock.now();
4377
+ for (const surface of this.surfaces) {
4378
+ followPointer(surface, event, now);
4306
4379
  }
4307
4380
  };
4308
- const leave = () => {
4309
- for (const surface of surfaces) {
4381
+ leave = () => {
4382
+ for (const surface of this.surfaces) {
4310
4383
  surface.hovering = false;
4311
4384
  }
4312
4385
  };
4313
- svg.addEventListener("pointermove", track);
4314
- svg.addEventListener("pointerleave", leave);
4315
- refresh();
4316
- const destroy = () => {
4317
- backdropGeneration += 1;
4318
- unwatch();
4319
- svg.removeEventListener("pointermove", track);
4320
- svg.removeEventListener("pointerleave", leave);
4321
- if (recapture !== void 0) {
4322
- view?.clearTimeout(recapture);
4323
- }
4324
- stop();
4325
- };
4326
- return {
4327
- capture: () => capturePngs(svg, surfaces, clock.now()),
4328
- setParameters: (ownerId, parameters3) => updateParameters(surfaces, ownerId, parameters3, clock.now()),
4329
- setPaused: clock.setPaused,
4330
- refresh,
4331
- destroy
4332
- };
4386
+ };
4387
+ function mountShaderSurfaces(svg) {
4388
+ return new ShaderSurfaces(svg);
4333
4389
  }
4334
4390
 
4335
4391
  // src/runtime/viewer/source.ts
@@ -4717,5 +4773,5 @@ function createViewer(options) {
4717
4773
  }
4718
4774
 
4719
4775
  export { SHADER_DEFAULTS, connectInteraction, createViewer, registerShaderProgram, shaderProgram };
4720
- //# sourceMappingURL=chunk-C3LVKPWQ.js.map
4721
- //# sourceMappingURL=chunk-C3LVKPWQ.js.map
4776
+ //# sourceMappingURL=chunk-VPNOVRWP.js.map
4777
+ //# sourceMappingURL=chunk-VPNOVRWP.js.map