@marianmeres/stuic 3.119.0 → 3.120.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.
|
@@ -135,8 +135,24 @@
|
|
|
135
135
|
|
|
136
136
|
$effect(() => () => clearTimeout(_previewSettleTimer));
|
|
137
137
|
|
|
138
|
-
//
|
|
139
|
-
|
|
138
|
+
// ---- Tap vs drag discrimination for area activation ----
|
|
139
|
+
// Areas activate via pointer events (pointerdown/pointerup), not a synthesized
|
|
140
|
+
// `click`. On touch the synthesized click is dropped whenever the gesture involves
|
|
141
|
+
// any movement/scroll — unreliable in general, worst on inner SVG shapes (iOS
|
|
142
|
+
// Safari) — which made small, closely-spaced area taps a no-op on mobile. A tap is
|
|
143
|
+
// a pointerup landing within TAP_SLOP_PX of its pointerdown. (Mirrors Book.svelte.)
|
|
144
|
+
const TAP_SLOP_PX = 10;
|
|
145
|
+
let _tapDownX = 0;
|
|
146
|
+
let _tapDownY = 0;
|
|
147
|
+
|
|
148
|
+
function handleTapDown(e: PointerEvent) {
|
|
149
|
+
_tapDownX = e.clientX;
|
|
150
|
+
_tapDownY = e.clientY;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function isTap(e: PointerEvent): boolean {
|
|
154
|
+
return Math.hypot(e.clientX - _tapDownX, e.clientY - _tapDownY) <= TAP_SLOP_PX;
|
|
155
|
+
}
|
|
140
156
|
|
|
141
157
|
const BUTTON_CLS = "stuic-assets-preview-control pointer-events-auto p-0!";
|
|
142
158
|
|
|
@@ -279,7 +295,6 @@
|
|
|
279
295
|
|
|
280
296
|
// Pan/drag handlers
|
|
281
297
|
function panStart(e: MouseEvent | TouchEvent) {
|
|
282
|
-
_wasDragged = false;
|
|
283
298
|
// Detect two-finger pinch gesture
|
|
284
299
|
if ("touches" in e && e.touches.length === 2) {
|
|
285
300
|
if (noZoom) return;
|
|
@@ -336,11 +351,6 @@
|
|
|
336
351
|
const newPanX = startPanX + (clientX - startMouseX);
|
|
337
352
|
const newPanY = startPanY + (clientY - startMouseY);
|
|
338
353
|
|
|
339
|
-
// Track drag for area click guard
|
|
340
|
-
if (Math.abs(clientX - startMouseX) > 3 || Math.abs(clientY - startMouseY) > 3) {
|
|
341
|
-
_wasDragged = true;
|
|
342
|
-
}
|
|
343
|
-
|
|
344
354
|
if (clampPan) {
|
|
345
355
|
const clamped = getClampedPan(newPanX, newPanY);
|
|
346
356
|
panX = clamped.x;
|
|
@@ -389,10 +399,6 @@
|
|
|
389
399
|
}
|
|
390
400
|
|
|
391
401
|
isPanning = false;
|
|
392
|
-
// Reset _wasDragged after a microtask so onclick handlers can check it first
|
|
393
|
-
requestAnimationFrame(() => {
|
|
394
|
-
_wasDragged = false;
|
|
395
|
-
});
|
|
396
402
|
}
|
|
397
403
|
|
|
398
404
|
async function slideToIndex(targetIdx: number, direction: "next" | "prev") {
|
|
@@ -565,6 +571,7 @@
|
|
|
565
571
|
use:interactable
|
|
566
572
|
bind:this={containerEl}
|
|
567
573
|
class="w-full h-full overflow-hidden flex items-center justify-center relative"
|
|
574
|
+
style:touch-action="none"
|
|
568
575
|
>
|
|
569
576
|
<img
|
|
570
577
|
use:pannable
|
|
@@ -600,7 +607,6 @@
|
|
|
600
607
|
style:transform-origin="center center"
|
|
601
608
|
>
|
|
602
609
|
{#each previewAsset.areas as area, i (`${area.id}-${i}`)}
|
|
603
|
-
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
604
610
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
605
611
|
<rect
|
|
606
612
|
x={area.x}
|
|
@@ -608,8 +614,9 @@
|
|
|
608
614
|
width={area.w}
|
|
609
615
|
height={area.h}
|
|
610
616
|
class="stuic-assets-preview-area"
|
|
611
|
-
|
|
612
|
-
|
|
617
|
+
onpointerdown={handleTapDown}
|
|
618
|
+
onpointerup={(e: PointerEvent) => {
|
|
619
|
+
if (!isTap(e)) return;
|
|
613
620
|
e.stopPropagation();
|
|
614
621
|
onAreaClick({ area, asset: previewAsset });
|
|
615
622
|
}}
|