lido-player 0.0.2-beta-19-dev → 0.0.2-beta-21-dev
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/cjs/{decode-Bny56MQ9.js → decode-Buln7Iaf.js} +1 -1
- package/dist/cjs/{index-BY9fvbr8.js → index-Bb_TFgTA.js} +1 -1
- package/dist/cjs/{index-DjsCseV8.js → index-DBCFoh1I.js} +19 -66
- package/dist/cjs/index.cjs.js +2 -2
- package/dist/cjs/lido-avatar_22.cjs.entry.js +110 -21
- package/dist/cjs/lido-player.cjs.js +2 -2
- package/dist/cjs/loader.cjs.js +1 -1
- package/dist/collection/collection-manifest.json +1 -1
- package/dist/collection/components/trace/lido-trace.js +107 -18
- package/dist/components/index.js +1 -1
- package/dist/components/lido-home.js +1 -1
- package/dist/components/lido-root.js +1 -1
- package/dist/components/lido-trace.js +1 -1
- package/dist/components/p-BAfFgI9q.js +1 -0
- package/dist/components/{p-CWwymnbk.js → p-wF7SBGpr.js} +2 -2
- package/dist/esm/{decode-Buyq-Iy5.js → decode-B_VrYFdJ.js} +1 -1
- package/dist/esm/{index-CQXciux9.js → index-B-VyHxJa.js} +1 -1
- package/dist/esm/{index-DQZfuGjI.js → index-mMpK8062.js} +19 -66
- package/dist/esm/index.js +2 -2
- package/dist/esm/lido-avatar_22.entry.js +110 -21
- package/dist/esm/lido-player.js +3 -3
- package/dist/esm/loader.js +2 -2
- package/dist/lido-player/index.esm.js +1 -1
- package/dist/lido-player/lido-player.esm.js +1 -1
- package/dist/lido-player/{p-37736e11.entry.js → p-744dee1c.entry.js} +2 -2
- package/dist/lido-player/{p-3Ry570XH.js → p-BK926Rl3.js} +1 -1
- package/dist/lido-player/{p-CFtq4Thh.js → p-Cw84dpIR.js} +1 -1
- package/dist/lido-player/p-mMpK8062.js +2 -0
- package/dist/types/components/trace/lido-trace.d.ts +9 -1
- package/dist/types/stencil-public-runtime.d.ts +55 -73
- package/loader/index.d.ts +1 -1
- package/package.json +3 -3
- package/dist/components/p-DYFVwyRr.js +0 -1
- package/dist/lido-player/p-DQZfuGjI.js +0 -3
|
@@ -111,6 +111,7 @@ export class LidoTrace {
|
|
|
111
111
|
this.fileIndex = -1;
|
|
112
112
|
this.isDragging = false;
|
|
113
113
|
this.activePointerId = null;
|
|
114
|
+
this.activeTraceState = null;
|
|
114
115
|
// Counter for throttling free trace updates
|
|
115
116
|
// This is only an internal counter. Keeping it out of @State prevents a
|
|
116
117
|
// Stencil component re-render while the user is dragging.
|
|
@@ -125,6 +126,7 @@ export class LidoTrace {
|
|
|
125
126
|
// Handle the pointermove event with optimizations
|
|
126
127
|
// Update the path trace as the red circle moves
|
|
127
128
|
async initializeSVG() {
|
|
129
|
+
this.cleanupTraceState(this.activeTraceState);
|
|
128
130
|
let state = {
|
|
129
131
|
fileIndex: -1,
|
|
130
132
|
currentPathIndex: 0,
|
|
@@ -147,7 +149,10 @@ export class LidoTrace {
|
|
|
147
149
|
dragOffset: null,
|
|
148
150
|
isCompletingPath: false,
|
|
149
151
|
touchProximityThreshold: null,
|
|
152
|
+
pointerTransform: null,
|
|
153
|
+
pointerRect: null,
|
|
150
154
|
};
|
|
155
|
+
this.activeTraceState = state;
|
|
151
156
|
const url = this.svgUrls[this.currentSvgIndex];
|
|
152
157
|
if (!url || url.trim() === '') {
|
|
153
158
|
console.error('No SVG URL provided or index out of bounds.');
|
|
@@ -174,6 +179,27 @@ export class LidoTrace {
|
|
|
174
179
|
disconnectedCallback() {
|
|
175
180
|
window.removeEventListener('resize', this.handleWindowResize);
|
|
176
181
|
window.removeEventListener('load', this.handleWindowLoad);
|
|
182
|
+
this.cleanupTraceState(this.activeTraceState);
|
|
183
|
+
this.activeTraceState = null;
|
|
184
|
+
}
|
|
185
|
+
/** Release listeners, pending frames, timers, and cached SVG geometry. */
|
|
186
|
+
cleanupTraceState(state) {
|
|
187
|
+
var _a;
|
|
188
|
+
if (!state)
|
|
189
|
+
return;
|
|
190
|
+
(_a = state.cleanup) === null || _a === void 0 ? void 0 : _a.call(state);
|
|
191
|
+
if (state.rafId)
|
|
192
|
+
cancelAnimationFrame(state.rafId);
|
|
193
|
+
state.rafId = null;
|
|
194
|
+
state.pointerMoveEvent = null;
|
|
195
|
+
state.pathSamples = [];
|
|
196
|
+
state.paths = [];
|
|
197
|
+
state.svg = null;
|
|
198
|
+
if (this.idleTimer !== null) {
|
|
199
|
+
clearTimeout(this.idleTimer);
|
|
200
|
+
this.idleTimer = null;
|
|
201
|
+
}
|
|
202
|
+
this.hideFingerHint();
|
|
177
203
|
}
|
|
178
204
|
/** ───────────────────────────────────────────────────────────
|
|
179
205
|
* Idle‑timer helpers
|
|
@@ -372,6 +398,18 @@ export class LidoTrace {
|
|
|
372
398
|
path._lidoTraceStart = path.getPointAtLength(0);
|
|
373
399
|
path._lidoTraceEnd = path.getPointAtLength(pathLength);
|
|
374
400
|
path._lidoTraceIsClosed = this.getDistanceSquared(path._lidoTraceStart, path._lidoTraceEnd) < 200;
|
|
401
|
+
// Index the path once. Repeated getPointAtLength calls are expensive on
|
|
402
|
+
// low-end SVG implementations and used to dominate every pointer frame.
|
|
403
|
+
const sampleCount = 192;
|
|
404
|
+
const sampleStep = pathLength / sampleCount || 1;
|
|
405
|
+
const samples = [];
|
|
406
|
+
for (let sampleIndex = 0; sampleIndex <= sampleCount; sampleIndex++) {
|
|
407
|
+
const length = Math.min(pathLength, sampleIndex * sampleStep);
|
|
408
|
+
const point = path.getPointAtLength(length);
|
|
409
|
+
samples.push({ x: point.x, y: point.y, length });
|
|
410
|
+
}
|
|
411
|
+
path._lidoTraceSamples = samples;
|
|
412
|
+
path._lidoTraceSampleStep = sampleStep;
|
|
375
413
|
// /** give every path an id so <mpath> can follow it */
|
|
376
414
|
path.setAttribute('id', 'lido-path-' + index); // ← NEW
|
|
377
415
|
// Create green path for tracing effect
|
|
@@ -406,7 +444,7 @@ export class LidoTrace {
|
|
|
406
444
|
state.flowMarkers = this.createFlowMarkersForPath(path);
|
|
407
445
|
}
|
|
408
446
|
});
|
|
409
|
-
state.totalPathLength = state.paths[state.currentPathIndex].
|
|
447
|
+
state.totalPathLength = state.paths[state.currentPathIndex]._lidoTraceLength;
|
|
410
448
|
}
|
|
411
449
|
// Set up the draggable circle at the start of the first path
|
|
412
450
|
setupDraggableCircle(state) {
|
|
@@ -431,10 +469,14 @@ export class LidoTrace {
|
|
|
431
469
|
return;
|
|
432
470
|
state.svg.style.touchAction = 'none';
|
|
433
471
|
state.circle.style.touchAction = 'none';
|
|
434
|
-
//
|
|
435
|
-
|
|
472
|
+
// Keep named handlers so the detached SVG can be fully released when the
|
|
473
|
+
// next trace starts. Anonymous handlers here previously retained every
|
|
474
|
+
// completed trace for the lifetime of the page.
|
|
475
|
+
const onPointerDown = (evt) => {
|
|
436
476
|
evt.preventDefault(); // Prevent default actions like text selection
|
|
437
|
-
|
|
477
|
+
state.pointerRect = state.svg.getBoundingClientRect();
|
|
478
|
+
state.pointerTransform = this.getSvgViewBoxTransform(state.svg, state.pointerRect);
|
|
479
|
+
const pointerPos = this.getPointerPosition(evt, state.svg, state.pointerTransform, state.pointerRect);
|
|
438
480
|
const circlePos = {
|
|
439
481
|
x: parseFloat(state.circle.getAttribute('cx')),
|
|
440
482
|
y: parseFloat(state.circle.getAttribute('cy')),
|
|
@@ -459,9 +501,9 @@ export class LidoTrace {
|
|
|
459
501
|
}
|
|
460
502
|
this.hideFingerHint(); // ← NEW
|
|
461
503
|
this.resetIdleTimer(state); // ← NEW
|
|
462
|
-
}
|
|
504
|
+
};
|
|
463
505
|
// Handle pointermove on the SVG to update the circle position
|
|
464
|
-
|
|
506
|
+
const onPointerMove = (evt) => {
|
|
465
507
|
if (!state.isDragging || evt.pointerId !== state.activePointerId)
|
|
466
508
|
return;
|
|
467
509
|
evt.preventDefault();
|
|
@@ -472,7 +514,7 @@ export class LidoTrace {
|
|
|
472
514
|
state.rafId = null;
|
|
473
515
|
});
|
|
474
516
|
}
|
|
475
|
-
}
|
|
517
|
+
};
|
|
476
518
|
// Handle pointerup and pointercancel on the SVG to stop dragging
|
|
477
519
|
const endDrag = (evt) => {
|
|
478
520
|
if (evt.pointerId === state.activePointerId) {
|
|
@@ -484,12 +526,25 @@ export class LidoTrace {
|
|
|
484
526
|
this.resetIdleTimer(state); // ← NEW
|
|
485
527
|
}
|
|
486
528
|
};
|
|
487
|
-
(
|
|
488
|
-
(
|
|
529
|
+
(_a = state.svg) === null || _a === void 0 ? void 0 : _a.addEventListener('pointerup', endDrag);
|
|
530
|
+
(_b = state.svg) === null || _b === void 0 ? void 0 : _b.addEventListener('pointercancel', endDrag);
|
|
489
531
|
// Optional: Prevent context menu on long press
|
|
490
|
-
|
|
532
|
+
const onContextMenu = (evt) => {
|
|
491
533
|
evt.preventDefault();
|
|
492
|
-
}
|
|
534
|
+
};
|
|
535
|
+
state.circle.addEventListener('pointerdown', onPointerDown, { passive: false });
|
|
536
|
+
(_c = state.svg) === null || _c === void 0 ? void 0 : _c.addEventListener('pointermove', onPointerMove);
|
|
537
|
+
(_d = state.svg) === null || _d === void 0 ? void 0 : _d.addEventListener('contextmenu', onContextMenu);
|
|
538
|
+
state.cleanup = () => {
|
|
539
|
+
var _a, _b, _c, _d, _e;
|
|
540
|
+
(_a = state.circle) === null || _a === void 0 ? void 0 : _a.removeEventListener('pointerdown', onPointerDown);
|
|
541
|
+
(_b = state.svg) === null || _b === void 0 ? void 0 : _b.removeEventListener('pointermove', onPointerMove);
|
|
542
|
+
(_c = state.svg) === null || _c === void 0 ? void 0 : _c.removeEventListener('pointerup', endDrag);
|
|
543
|
+
(_d = state.svg) === null || _d === void 0 ? void 0 : _d.removeEventListener('pointercancel', endDrag);
|
|
544
|
+
(_e = state.svg) === null || _e === void 0 ? void 0 : _e.removeEventListener('contextmenu', onContextMenu);
|
|
545
|
+
state.isDragging = false;
|
|
546
|
+
state.activePointerId = null;
|
|
547
|
+
};
|
|
493
548
|
}
|
|
494
549
|
// Modified handlePointerMove function
|
|
495
550
|
async handlePointerMove(state) {
|
|
@@ -502,7 +557,7 @@ export class LidoTrace {
|
|
|
502
557
|
return;
|
|
503
558
|
this.hideFingerHint(); // user is active, remove hint
|
|
504
559
|
const evt = state.pointerMoveEvent;
|
|
505
|
-
const rawPointerPos = this.getPointerPosition(evt, state.svg);
|
|
560
|
+
const rawPointerPos = this.getPointerPosition(evt, state.svg, state.pointerTransform, state.pointerRect);
|
|
506
561
|
const pointerPos = state.dragOffset
|
|
507
562
|
? {
|
|
508
563
|
x: rawPointerPos.x - state.dragOffset.x,
|
|
@@ -766,9 +821,9 @@ export class LidoTrace {
|
|
|
766
821
|
triggerNextContainer();
|
|
767
822
|
}
|
|
768
823
|
// Get the pointer position relative to the SVG
|
|
769
|
-
getPointerPosition(evt, svg) {
|
|
824
|
+
getPointerPosition(evt, svg, cachedTransform, cachedRect) {
|
|
770
825
|
var _a;
|
|
771
|
-
const viewBoxPoint = this.getPointerPositionFromViewBox(evt, svg);
|
|
826
|
+
const viewBoxPoint = this.getPointerPositionFromViewBox(evt, svg, cachedTransform, cachedRect);
|
|
772
827
|
if (viewBoxPoint)
|
|
773
828
|
return viewBoxPoint;
|
|
774
829
|
const svgPoint = svg.createSVGPoint();
|
|
@@ -777,13 +832,13 @@ export class LidoTrace {
|
|
|
777
832
|
const ctm = (_a = svg.getScreenCTM()) === null || _a === void 0 ? void 0 : _a.inverse();
|
|
778
833
|
return ctm ? svgPoint.matrixTransform(ctm) : { x: evt.clientX, y: evt.clientY };
|
|
779
834
|
}
|
|
780
|
-
getPointerPositionFromViewBox(evt, svg) {
|
|
781
|
-
const rect = svg.getBoundingClientRect();
|
|
835
|
+
getPointerPositionFromViewBox(evt, svg, cachedTransform, cachedRect) {
|
|
836
|
+
const rect = cachedRect || svg.getBoundingClientRect();
|
|
782
837
|
const viewBox = svg.viewBox.baseVal;
|
|
783
838
|
if (!rect.width || !rect.height || !viewBox.width || !viewBox.height) {
|
|
784
839
|
return null;
|
|
785
840
|
}
|
|
786
|
-
const { offsetX, offsetY, scaleX, scaleY } = this.getSvgViewBoxTransform(svg, rect);
|
|
841
|
+
const { offsetX, offsetY, scaleX, scaleY } = cachedTransform || this.getSvgViewBoxTransform(svg, rect);
|
|
787
842
|
return {
|
|
788
843
|
x: viewBox.x + (evt.clientX - rect.left - offsetX) / scaleX,
|
|
789
844
|
y: viewBox.y + (evt.clientY - rect.top - offsetY) / scaleY,
|
|
@@ -843,6 +898,40 @@ export class LidoTrace {
|
|
|
843
898
|
getClosestPointOnPath(pathNode, point, lastLength) {
|
|
844
899
|
var _a;
|
|
845
900
|
const pathLength = (_a = pathNode._lidoTraceLength) !== null && _a !== void 0 ? _a : pathNode.getTotalLength();
|
|
901
|
+
const samples = pathNode._lidoTraceSamples;
|
|
902
|
+
const sampleStep = pathNode._lidoTraceSampleStep;
|
|
903
|
+
if ((samples === null || samples === void 0 ? void 0 : samples.length) && sampleStep) {
|
|
904
|
+
const searchWindow = lastLength === undefined ? pathLength : 150;
|
|
905
|
+
const searchStart = lastLength === undefined ? 0 : Math.max(0, lastLength - searchWindow);
|
|
906
|
+
const searchEnd = lastLength === undefined ? pathLength : Math.min(pathLength, lastLength + searchWindow);
|
|
907
|
+
let nearest = samples[Math.max(0, Math.min(samples.length - 1, Math.round((lastLength || 0) / sampleStep)))];
|
|
908
|
+
let nearestDistance = Infinity;
|
|
909
|
+
for (const sample of samples) {
|
|
910
|
+
if (sample.length < searchStart || sample.length > searchEnd)
|
|
911
|
+
continue;
|
|
912
|
+
const distance = this.getDistanceSquared(point, sample);
|
|
913
|
+
if (distance < nearestDistance) {
|
|
914
|
+
nearestDistance = distance;
|
|
915
|
+
nearest = sample;
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
// Refine only around the cached winner. This keeps the path accurate
|
|
919
|
+
// while reducing hot-path geometry calls from roughly 50 to a handful.
|
|
920
|
+
const refinementStep = 6;
|
|
921
|
+
const refineStart = Math.max(searchStart, nearest.length - sampleStep);
|
|
922
|
+
const refineEnd = Math.min(searchEnd, nearest.length + sampleStep);
|
|
923
|
+
let closestPoint = Object.assign({}, nearest);
|
|
924
|
+
let minDistanceSquared = nearestDistance;
|
|
925
|
+
for (let length = refineStart; length <= refineEnd; length += refinementStep) {
|
|
926
|
+
const candidate = pathNode.getPointAtLength(length);
|
|
927
|
+
const distance = this.getDistanceSquared(point, candidate);
|
|
928
|
+
if (distance < minDistanceSquared) {
|
|
929
|
+
minDistanceSquared = distance;
|
|
930
|
+
closestPoint = { x: candidate.x, y: candidate.y, length };
|
|
931
|
+
}
|
|
932
|
+
}
|
|
933
|
+
return closestPoint;
|
|
934
|
+
}
|
|
846
935
|
let closestPoint = { x: 0, y: 0, length: 0 };
|
|
847
936
|
let minDistanceSquared = Infinity;
|
|
848
937
|
const coarseStep = 40;
|
|
@@ -1035,7 +1124,7 @@ export class LidoTrace {
|
|
|
1035
1124
|
};
|
|
1036
1125
|
}
|
|
1037
1126
|
render() {
|
|
1038
|
-
return (h(Host, { key: '
|
|
1127
|
+
return (h(Host, { key: 'f4c270d9319e1115d966a6d9b697a4413ca87885', class: "lido-trace", id: this.id, audio: this.audio, onCorrect: this.onCorrect, onInCorrect: this.onInCorrect, style: this.style, "aria-label": this.ariaLabel, "aria-hidden": this.ariaHidden, tabindex: this.tabIndex, "disable-speak": this.disableSpeak }, h("div", { key: 'efbbaf5c796c9cfe8516fe5d47265e3a01b28a25', style: this.style, id: "lido-svgContainer" })));
|
|
1039
1128
|
}
|
|
1040
1129
|
static get is() { return "lido-trace"; }
|
|
1041
1130
|
static get originalStyleUrls() {
|