@project-skymap/library 0.7.0 → 0.7.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/index.cjs +83 -16
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +83 -16
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -849,7 +849,8 @@ function createEngine({
|
|
|
849
849
|
onSelect,
|
|
850
850
|
onHover,
|
|
851
851
|
onArrangementChange,
|
|
852
|
-
onFovChange
|
|
852
|
+
onFovChange,
|
|
853
|
+
onLongPress
|
|
853
854
|
}) {
|
|
854
855
|
let hoveredBookId = null;
|
|
855
856
|
let focusedBookId = null;
|
|
@@ -919,13 +920,20 @@ function createEngine({
|
|
|
919
920
|
pinchStartDistance: 0,
|
|
920
921
|
pinchStartFov: ENGINE_CONFIG.defaultFov,
|
|
921
922
|
pinchCenterX: 0,
|
|
922
|
-
pinchCenterY: 0
|
|
923
|
+
pinchCenterY: 0,
|
|
924
|
+
// Double-tap detection
|
|
925
|
+
lastTapTime: 0,
|
|
926
|
+
lastTapX: 0,
|
|
927
|
+
lastTapY: 0,
|
|
928
|
+
// Long-press detection
|
|
929
|
+
longPressTimer: null,
|
|
930
|
+
longPressTriggered: false
|
|
923
931
|
};
|
|
924
932
|
const mouseNDC = new THREE5__namespace.Vector2();
|
|
925
933
|
let isMouseInWindow = false;
|
|
926
934
|
let isTouchDevice = false;
|
|
927
935
|
let edgeHoverStart = 0;
|
|
928
|
-
let handlers = { onSelect, onHover, onArrangementChange, onFovChange };
|
|
936
|
+
let handlers = { onSelect, onHover, onArrangementChange, onFovChange, onLongPress };
|
|
929
937
|
let currentConfig;
|
|
930
938
|
const constellationLayer = new ConstellationArtworkLayer(scene);
|
|
931
939
|
function mix(a, b, t) {
|
|
@@ -2418,6 +2426,11 @@ function createEngine({
|
|
|
2418
2426
|
function onTouchStart(e) {
|
|
2419
2427
|
e.preventDefault();
|
|
2420
2428
|
isTouchDevice = true;
|
|
2429
|
+
if (state.longPressTimer) {
|
|
2430
|
+
clearTimeout(state.longPressTimer);
|
|
2431
|
+
state.longPressTimer = null;
|
|
2432
|
+
}
|
|
2433
|
+
state.longPressTriggered = false;
|
|
2421
2434
|
const touches = e.touches;
|
|
2422
2435
|
state.touchCount = touches.length;
|
|
2423
2436
|
if (touches.length === 1) {
|
|
@@ -2433,6 +2446,22 @@ function createEngine({
|
|
|
2433
2446
|
state.isDragging = true;
|
|
2434
2447
|
state.velocityX = 0;
|
|
2435
2448
|
state.velocityY = 0;
|
|
2449
|
+
state.longPressTimer = setTimeout(() => {
|
|
2450
|
+
if (!state.touchMoved && state.touchCount === 1) {
|
|
2451
|
+
state.longPressTriggered = true;
|
|
2452
|
+
const rect = renderer.domElement.getBoundingClientRect();
|
|
2453
|
+
const mX = state.touchStartX - rect.left;
|
|
2454
|
+
const mY = state.touchStartY - rect.top;
|
|
2455
|
+
mouseNDC.x = mX / rect.width * 2 - 1;
|
|
2456
|
+
mouseNDC.y = -(mY / rect.height) * 2 + 1;
|
|
2457
|
+
const syntheticEvent = {
|
|
2458
|
+
clientX: state.touchStartX,
|
|
2459
|
+
clientY: state.touchStartY
|
|
2460
|
+
};
|
|
2461
|
+
const hit = pick(syntheticEvent);
|
|
2462
|
+
handlers.onLongPress?.(hit?.node ?? null, state.touchStartX, state.touchStartY);
|
|
2463
|
+
}
|
|
2464
|
+
}, ENGINE_CONFIG.longPressDelay);
|
|
2436
2465
|
} else if (touches.length === 2) {
|
|
2437
2466
|
const t0 = touches[0];
|
|
2438
2467
|
const t1 = touches[1];
|
|
@@ -2459,6 +2488,10 @@ function createEngine({
|
|
|
2459
2488
|
const totalDy = touch.clientY - state.touchStartY;
|
|
2460
2489
|
if (Math.sqrt(totalDx * totalDx + totalDy * totalDy) > ENGINE_CONFIG.tapMaxDistance) {
|
|
2461
2490
|
state.touchMoved = true;
|
|
2491
|
+
if (state.longPressTimer) {
|
|
2492
|
+
clearTimeout(state.longPressTimer);
|
|
2493
|
+
state.longPressTimer = null;
|
|
2494
|
+
}
|
|
2462
2495
|
}
|
|
2463
2496
|
const speedScale = state.fov / ENGINE_CONFIG.defaultFov;
|
|
2464
2497
|
const rotLock = Math.max(0, Math.min(1, (state.fov - 100) / (ENGINE_CONFIG.maxFov - 100)));
|
|
@@ -2493,11 +2526,21 @@ function createEngine({
|
|
|
2493
2526
|
}
|
|
2494
2527
|
function onTouchEnd(e) {
|
|
2495
2528
|
e.preventDefault();
|
|
2529
|
+
if (state.longPressTimer) {
|
|
2530
|
+
clearTimeout(state.longPressTimer);
|
|
2531
|
+
state.longPressTimer = null;
|
|
2532
|
+
}
|
|
2496
2533
|
const remainingTouches = e.touches.length;
|
|
2497
2534
|
if (remainingTouches === 0) {
|
|
2498
|
-
const
|
|
2499
|
-
const
|
|
2535
|
+
const now = performance.now();
|
|
2536
|
+
const duration = now - state.touchStartTime;
|
|
2537
|
+
const wasTap = !state.touchMoved && duration < ENGINE_CONFIG.tapMaxDuration && !state.longPressTriggered;
|
|
2500
2538
|
if (wasTap) {
|
|
2539
|
+
const timeSinceLastTap = now - state.lastTapTime;
|
|
2540
|
+
const distFromLastTap = Math.sqrt(
|
|
2541
|
+
Math.pow(state.touchStartX - state.lastTapX, 2) + Math.pow(state.touchStartY - state.lastTapY, 2)
|
|
2542
|
+
);
|
|
2543
|
+
const isDoubleTap = timeSinceLastTap < ENGINE_CONFIG.doubleTapMaxDelay && distFromLastTap < ENGINE_CONFIG.doubleTapMaxDistance;
|
|
2501
2544
|
const rect = renderer.domElement.getBoundingClientRect();
|
|
2502
2545
|
const mX = state.touchStartX - rect.left;
|
|
2503
2546
|
const mY = state.touchStartY - rect.top;
|
|
@@ -2508,13 +2551,26 @@ function createEngine({
|
|
|
2508
2551
|
clientY: state.touchStartY
|
|
2509
2552
|
};
|
|
2510
2553
|
const hit = pick(syntheticEvent);
|
|
2511
|
-
if (
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2554
|
+
if (isDoubleTap) {
|
|
2555
|
+
if (hit) {
|
|
2556
|
+
flyTo(hit.node.id, ENGINE_CONFIG.minFov);
|
|
2557
|
+
handlers.onSelect?.(hit.node);
|
|
2558
|
+
}
|
|
2559
|
+
state.lastTapTime = 0;
|
|
2560
|
+
state.lastTapX = 0;
|
|
2561
|
+
state.lastTapY = 0;
|
|
2516
2562
|
} else {
|
|
2517
|
-
|
|
2563
|
+
if (hit) {
|
|
2564
|
+
handlers.onSelect?.(hit.node);
|
|
2565
|
+
constellationLayer.setFocused(hit.node.id);
|
|
2566
|
+
if (hit.node.level === 2) setFocusedBook(hit.node.id);
|
|
2567
|
+
else if (hit.node.level === 3 && hit.node.parent) setFocusedBook(hit.node.parent);
|
|
2568
|
+
} else {
|
|
2569
|
+
setFocusedBook(null);
|
|
2570
|
+
}
|
|
2571
|
+
state.lastTapTime = now;
|
|
2572
|
+
state.lastTapX = state.touchStartX;
|
|
2573
|
+
state.lastTapY = state.touchStartY;
|
|
2518
2574
|
}
|
|
2519
2575
|
}
|
|
2520
2576
|
state.isDragging = false;
|
|
@@ -2533,6 +2589,10 @@ function createEngine({
|
|
|
2533
2589
|
}
|
|
2534
2590
|
function onTouchCancel(e) {
|
|
2535
2591
|
e.preventDefault();
|
|
2592
|
+
if (state.longPressTimer) {
|
|
2593
|
+
clearTimeout(state.longPressTimer);
|
|
2594
|
+
state.longPressTimer = null;
|
|
2595
|
+
}
|
|
2536
2596
|
state.isDragging = false;
|
|
2537
2597
|
state.dragMode = "none";
|
|
2538
2598
|
state.touchCount = 0;
|
|
@@ -2918,8 +2978,14 @@ var init_createEngine = __esm({
|
|
|
2918
2978
|
// Snappier than mouse (0.92)
|
|
2919
2979
|
tapMaxDuration: 300,
|
|
2920
2980
|
// ms
|
|
2921
|
-
tapMaxDistance: 10
|
|
2981
|
+
tapMaxDistance: 10,
|
|
2922
2982
|
// px
|
|
2983
|
+
doubleTapMaxDelay: 300,
|
|
2984
|
+
// ms between taps
|
|
2985
|
+
doubleTapMaxDistance: 30,
|
|
2986
|
+
// px between tap locations
|
|
2987
|
+
longPressDelay: 500
|
|
2988
|
+
// ms to trigger long-press
|
|
2923
2989
|
};
|
|
2924
2990
|
ORDER_REVEAL_CONFIG = {
|
|
2925
2991
|
globalDim: 0.85,
|
|
@@ -2930,7 +2996,7 @@ var init_createEngine = __esm({
|
|
|
2930
2996
|
}
|
|
2931
2997
|
});
|
|
2932
2998
|
var StarMap = react.forwardRef(
|
|
2933
|
-
({ config, className, onSelect, onHover, onArrangementChange, onFovChange }, ref) => {
|
|
2999
|
+
({ config, className, onSelect, onHover, onArrangementChange, onFovChange, onLongPress }, ref) => {
|
|
2934
3000
|
const containerRef = react.useRef(null);
|
|
2935
3001
|
const engineRef = react.useRef(null);
|
|
2936
3002
|
react.useImperativeHandle(ref, () => ({
|
|
@@ -2953,7 +3019,8 @@ var StarMap = react.forwardRef(
|
|
|
2953
3019
|
onSelect,
|
|
2954
3020
|
onHover,
|
|
2955
3021
|
onArrangementChange,
|
|
2956
|
-
onFovChange
|
|
3022
|
+
onFovChange,
|
|
3023
|
+
onLongPress
|
|
2957
3024
|
});
|
|
2958
3025
|
engineRef.current.setConfig(config);
|
|
2959
3026
|
engineRef.current.start();
|
|
@@ -2969,8 +3036,8 @@ var StarMap = react.forwardRef(
|
|
|
2969
3036
|
engineRef.current?.setConfig?.(config);
|
|
2970
3037
|
}, [config]);
|
|
2971
3038
|
react.useEffect(() => {
|
|
2972
|
-
engineRef.current?.setHandlers?.({ onSelect, onHover, onArrangementChange, onFovChange });
|
|
2973
|
-
}, [onSelect, onHover, onArrangementChange, onFovChange]);
|
|
3039
|
+
engineRef.current?.setHandlers?.({ onSelect, onHover, onArrangementChange, onFovChange, onLongPress });
|
|
3040
|
+
}, [onSelect, onHover, onArrangementChange, onFovChange, onLongPress]);
|
|
2974
3041
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { ref: containerRef, className, style: { width: "100%", height: "100%" } });
|
|
2975
3042
|
}
|
|
2976
3043
|
);
|