@ericchen1990/pano-view 3.6.2 → 3.6.4
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/README.zh-CN.md +4 -4
- package/dist/index.cjs +388 -78
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.mjs +409 -96
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -3769,12 +3769,18 @@ var PointerDragAnchor = class {
|
|
|
3769
3769
|
this.projection = projection;
|
|
3770
3770
|
this.local = new import_three2.Vector3();
|
|
3771
3771
|
this.rotation = new import_three2.Euler(0, 0, 0, "YXZ");
|
|
3772
|
-
|
|
3772
|
+
const startRay = this.ray(start).clone();
|
|
3773
|
+
this.baseAzimuth = Math.atan2(startRay.x, -startRay.z);
|
|
3774
|
+
this.baseElevation = Math.atan2(startRay.y, -startRay.z);
|
|
3775
|
+
this.anchor = startRay.clone().applyEuler(this.rotation.set(
|
|
3773
3776
|
import_three2.MathUtils.degToRad(origin.pitch),
|
|
3774
3777
|
import_three2.MathUtils.degToRad(-origin.yaw),
|
|
3775
3778
|
0,
|
|
3776
3779
|
"YXZ"
|
|
3777
3780
|
));
|
|
3781
|
+
const originPitch = import_three2.MathUtils.degToRad(origin.pitch);
|
|
3782
|
+
const roots = this.pitchRoots(startRay, originPitch);
|
|
3783
|
+
this.useSupplementary = Math.abs(roots.supplementary - originPitch) + 1e-6 < Math.abs(roots.principal - originPitch);
|
|
3778
3784
|
}
|
|
3779
3785
|
ray(point) {
|
|
3780
3786
|
return this.local.set(
|
|
@@ -3783,6 +3789,21 @@ var PointerDragAnchor = class {
|
|
|
3783
3789
|
0.5
|
|
3784
3790
|
).applyMatrix4(this.projection.projectionMatrixInverse).normalize();
|
|
3785
3791
|
}
|
|
3792
|
+
/** Pitch roots of the level-camera constraint. The supplementary root is unwrapped toward the press. */
|
|
3793
|
+
pitchRoots(ray, originPitch) {
|
|
3794
|
+
const latitude = Math.asin(import_three2.MathUtils.clamp(
|
|
3795
|
+
this.anchor.y / Math.max(Math.hypot(ray.y, ray.z), 1e-12),
|
|
3796
|
+
-1,
|
|
3797
|
+
1
|
|
3798
|
+
));
|
|
3799
|
+
const offset = Math.atan2(ray.y, -ray.z);
|
|
3800
|
+
const principal = latitude - offset;
|
|
3801
|
+
const turned = Math.PI - latitude - offset;
|
|
3802
|
+
return {
|
|
3803
|
+
principal,
|
|
3804
|
+
supplementary: originPitch + Math.atan2(Math.sin(turned - originPitch), Math.cos(turned - originPitch))
|
|
3805
|
+
};
|
|
3806
|
+
}
|
|
3786
3807
|
solve(point, speed = DEFAULT_POINTER_DRAG_SPEED, invert = false) {
|
|
3787
3808
|
const multiplier = (Number.isFinite(speed) && speed >= 0 ? speed : DEFAULT_POINTER_DRAG_SPEED) / DEFAULT_POINTER_DRAG_SPEED * (invert ? -1 : 1);
|
|
3788
3809
|
if (multiplier === 0) return { yaw: 0, pitch: 0 };
|
|
@@ -3790,22 +3811,27 @@ var PointerDragAnchor = class {
|
|
|
3790
3811
|
x: this.start.x + (point.x - this.start.x) * multiplier,
|
|
3791
3812
|
y: this.start.y + (point.y - this.start.y) * multiplier
|
|
3792
3813
|
});
|
|
3793
|
-
const latitude = Math.asin(import_three2.MathUtils.clamp(this.anchor.y / Math.max(Math.hypot(ray.y, ray.z), 1e-12), -1, 1));
|
|
3794
|
-
const offset = Math.atan2(ray.y, -ray.z);
|
|
3795
3814
|
const originPitch = import_three2.MathUtils.degToRad(this.origin.pitch);
|
|
3796
|
-
const
|
|
3797
|
-
|
|
3798
|
-
|
|
3799
|
-
|
|
3800
|
-
|
|
3801
|
-
|
|
3802
|
-
|
|
3803
|
-
|
|
3804
|
-
|
|
3805
|
-
|
|
3806
|
-
|
|
3807
|
-
|
|
3808
|
-
|
|
3815
|
+
const roots = this.pitchRoots(ray, originPitch);
|
|
3816
|
+
const exactPitch = import_three2.MathUtils.clamp(
|
|
3817
|
+
this.useSupplementary ? roots.supplementary : roots.principal,
|
|
3818
|
+
-Math.PI / 2,
|
|
3819
|
+
Math.PI / 2
|
|
3820
|
+
);
|
|
3821
|
+
const stablePitch = originPitch - (Math.atan2(ray.y, -ray.z) - this.baseElevation);
|
|
3822
|
+
const fromPole = Math.asin(Math.min(1, Math.hypot(this.anchor.x, this.anchor.z)));
|
|
3823
|
+
const pointerLock = import_three2.MathUtils.smoothstep(fromPole, import_three2.MathUtils.degToRad(8), import_three2.MathUtils.degToRad(18));
|
|
3824
|
+
const pitchTurn = Math.atan2(Math.sin(exactPitch - stablePitch), Math.cos(exactPitch - stablePitch));
|
|
3825
|
+
const pitch = import_three2.MathUtils.clamp(
|
|
3826
|
+
pointerLock >= 1 ? exactPitch : stablePitch + pointerLock * pitchTurn,
|
|
3827
|
+
-Math.PI / 2,
|
|
3828
|
+
Math.PI / 2
|
|
3829
|
+
);
|
|
3830
|
+
const pitchedZ = Math.sin(exactPitch) * ray.y + Math.cos(exactPitch) * ray.z;
|
|
3831
|
+
const exactYaw = Math.atan2(this.anchor.x, -this.anchor.z) - Math.atan2(ray.x, -pitchedZ);
|
|
3832
|
+
const stableYaw = import_three2.MathUtils.degToRad(this.origin.yaw) + Math.atan2(ray.x, -ray.z) - this.baseAzimuth;
|
|
3833
|
+
const yawTurn = Math.atan2(Math.sin(exactYaw - stableYaw), Math.cos(exactYaw - stableYaw));
|
|
3834
|
+
const yaw = import_three2.MathUtils.radToDeg(stableYaw + pointerLock * yawTurn);
|
|
3809
3835
|
return { yaw: normalizeViewYaw(yaw - this.origin.yaw), pitch: import_three2.MathUtils.radToDeg(pitch) - this.origin.pitch };
|
|
3810
3836
|
}
|
|
3811
3837
|
};
|
|
@@ -4001,7 +4027,10 @@ function MouseControls({
|
|
|
4001
4027
|
const element = gl.domElement;
|
|
4002
4028
|
const drag = createPointerDrag(camera, element, () => controlsRef.current, "mouse");
|
|
4003
4029
|
const allowedButtons = resolveButtons(buttons);
|
|
4030
|
+
const pending = /* @__PURE__ */ new Set();
|
|
4031
|
+
let disposed = false;
|
|
4004
4032
|
const clearPointers = () => {
|
|
4033
|
+
pending.clear();
|
|
4005
4034
|
for (const pointerId of pointersRef.current.keys()) {
|
|
4006
4035
|
if (element.hasPointerCapture?.(pointerId)) {
|
|
4007
4036
|
element.releasePointerCapture?.(pointerId);
|
|
@@ -4027,6 +4056,25 @@ function MouseControls({
|
|
|
4027
4056
|
{ cancelled }
|
|
4028
4057
|
);
|
|
4029
4058
|
};
|
|
4059
|
+
const beginPointer = (event) => {
|
|
4060
|
+
if (disposed || controlsRef.current?.isInteractionLocked()) {
|
|
4061
|
+
return;
|
|
4062
|
+
}
|
|
4063
|
+
if (pointersRef.current.has(event.pointerId)) {
|
|
4064
|
+
return;
|
|
4065
|
+
}
|
|
4066
|
+
pointersRef.current.set(event.pointerId, {
|
|
4067
|
+
x: event.clientX,
|
|
4068
|
+
y: event.clientY,
|
|
4069
|
+
at: performance.now()
|
|
4070
|
+
});
|
|
4071
|
+
try {
|
|
4072
|
+
element.setPointerCapture?.(event.pointerId);
|
|
4073
|
+
} catch {
|
|
4074
|
+
}
|
|
4075
|
+
syncActive();
|
|
4076
|
+
drag.start({ x: event.clientX, y: event.clientY }, pointerAt(event));
|
|
4077
|
+
};
|
|
4030
4078
|
const onPointerDown = (event) => {
|
|
4031
4079
|
if (!isMouseLike(event)) {
|
|
4032
4080
|
return;
|
|
@@ -4038,14 +4086,14 @@ function MouseControls({
|
|
|
4038
4086
|
return;
|
|
4039
4087
|
}
|
|
4040
4088
|
event.preventDefault();
|
|
4041
|
-
|
|
4042
|
-
|
|
4043
|
-
|
|
4044
|
-
|
|
4089
|
+
const pointerId = event.pointerId;
|
|
4090
|
+
pending.add(pointerId);
|
|
4091
|
+
queueMicrotask(() => {
|
|
4092
|
+
if (!pending.delete(pointerId)) {
|
|
4093
|
+
return;
|
|
4094
|
+
}
|
|
4095
|
+
beginPointer(event);
|
|
4045
4096
|
});
|
|
4046
|
-
element.setPointerCapture?.(event.pointerId);
|
|
4047
|
-
syncActive();
|
|
4048
|
-
drag.start({ x: event.clientX, y: event.clientY }, pointerAt(event));
|
|
4049
4097
|
};
|
|
4050
4098
|
const onPointerMove = (event) => {
|
|
4051
4099
|
if (!isMouseLike(event)) {
|
|
@@ -4069,6 +4117,7 @@ function MouseControls({
|
|
|
4069
4117
|
drag.move(next, previous, speed, optionsRef.current.invert, pointerAt(event));
|
|
4070
4118
|
};
|
|
4071
4119
|
const releasePointer = (event) => {
|
|
4120
|
+
pending.delete(event.pointerId);
|
|
4072
4121
|
if (!pointersRef.current.has(event.pointerId)) {
|
|
4073
4122
|
return;
|
|
4074
4123
|
}
|
|
@@ -4110,6 +4159,7 @@ function MouseControls({
|
|
|
4110
4159
|
element.addEventListener("lostpointercapture", releasePointer);
|
|
4111
4160
|
element.addEventListener("wheel", onWheel, { passive: false });
|
|
4112
4161
|
return () => {
|
|
4162
|
+
disposed = true;
|
|
4113
4163
|
validateDragRef.current = void 0;
|
|
4114
4164
|
element.removeEventListener("pointerdown", onPointerDown);
|
|
4115
4165
|
element.removeEventListener("pointermove", onPointerMove);
|
|
@@ -5604,6 +5654,12 @@ function vector3ToPanoPosition(vector) {
|
|
|
5604
5654
|
)
|
|
5605
5655
|
});
|
|
5606
5656
|
}
|
|
5657
|
+
function translateHotspotPosition(origin, from, to) {
|
|
5658
|
+
return normalizePanoPosition({
|
|
5659
|
+
yaw: origin.yaw + normalizePanoYaw(to.yaw - from.yaw),
|
|
5660
|
+
pitch: origin.pitch + (to.pitch - from.pitch)
|
|
5661
|
+
});
|
|
5662
|
+
}
|
|
5607
5663
|
|
|
5608
5664
|
// src/panorama-radius.ts
|
|
5609
5665
|
var DEFAULT_PANORAMA_RADIUS = 1e3;
|
|
@@ -5747,7 +5803,10 @@ function TouchControls({
|
|
|
5747
5803
|
(0, import_react18.useEffect)(() => {
|
|
5748
5804
|
const element = gl.domElement;
|
|
5749
5805
|
const drag = createPointerDrag(camera, element, () => controlsRef.current, "touch");
|
|
5806
|
+
const pending = /* @__PURE__ */ new Set();
|
|
5807
|
+
let disposed = false;
|
|
5750
5808
|
const clearPointers = () => {
|
|
5809
|
+
pending.clear();
|
|
5751
5810
|
for (const pointerId of pointersRef.current.keys()) {
|
|
5752
5811
|
if (element.hasPointerCapture?.(pointerId)) {
|
|
5753
5812
|
element.releasePointerCapture?.(pointerId);
|
|
@@ -5773,20 +5832,22 @@ function TouchControls({
|
|
|
5773
5832
|
{ cancelled }
|
|
5774
5833
|
);
|
|
5775
5834
|
};
|
|
5776
|
-
const
|
|
5777
|
-
if (
|
|
5835
|
+
const beginPointer = (event) => {
|
|
5836
|
+
if (disposed || controlsRef.current?.isInteractionLocked()) {
|
|
5778
5837
|
return;
|
|
5779
5838
|
}
|
|
5780
|
-
if (
|
|
5839
|
+
if (pointersRef.current.has(event.pointerId)) {
|
|
5781
5840
|
return;
|
|
5782
5841
|
}
|
|
5783
|
-
event.preventDefault();
|
|
5784
5842
|
pointersRef.current.set(event.pointerId, {
|
|
5785
5843
|
x: event.clientX,
|
|
5786
5844
|
y: event.clientY,
|
|
5787
5845
|
at: performance.now()
|
|
5788
5846
|
});
|
|
5789
|
-
|
|
5847
|
+
try {
|
|
5848
|
+
element.setPointerCapture?.(event.pointerId);
|
|
5849
|
+
} catch {
|
|
5850
|
+
}
|
|
5790
5851
|
syncActive();
|
|
5791
5852
|
drag.start({ x: event.clientX, y: event.clientY }, pointerAt2(event));
|
|
5792
5853
|
if (pointersRef.current.size >= 2) {
|
|
@@ -5795,6 +5856,23 @@ function TouchControls({
|
|
|
5795
5856
|
pinchDistanceRef.current = pointerDistance(first, second);
|
|
5796
5857
|
}
|
|
5797
5858
|
};
|
|
5859
|
+
const onPointerDown = (event) => {
|
|
5860
|
+
if (event.pointerType !== "touch") {
|
|
5861
|
+
return;
|
|
5862
|
+
}
|
|
5863
|
+
if (controlsRef.current?.isInteractionLocked()) {
|
|
5864
|
+
return;
|
|
5865
|
+
}
|
|
5866
|
+
event.preventDefault();
|
|
5867
|
+
const pointerId = event.pointerId;
|
|
5868
|
+
pending.add(pointerId);
|
|
5869
|
+
queueMicrotask(() => {
|
|
5870
|
+
if (!pending.delete(pointerId)) {
|
|
5871
|
+
return;
|
|
5872
|
+
}
|
|
5873
|
+
beginPointer(event);
|
|
5874
|
+
});
|
|
5875
|
+
};
|
|
5798
5876
|
const onPointerMove = (event) => {
|
|
5799
5877
|
if (event.pointerType !== "touch") {
|
|
5800
5878
|
return;
|
|
@@ -5838,6 +5916,7 @@ function TouchControls({
|
|
|
5838
5916
|
drag.move(next, previous, speed, optionsRef.current.invert, pointerAt2(event));
|
|
5839
5917
|
};
|
|
5840
5918
|
const releasePointer = (event) => {
|
|
5919
|
+
pending.delete(event.pointerId);
|
|
5841
5920
|
if (!pointersRef.current.has(event.pointerId)) {
|
|
5842
5921
|
return;
|
|
5843
5922
|
}
|
|
@@ -5861,6 +5940,7 @@ function TouchControls({
|
|
|
5861
5940
|
element.addEventListener("pointercancel", releasePointer);
|
|
5862
5941
|
element.addEventListener("lostpointercapture", releasePointer);
|
|
5863
5942
|
return () => {
|
|
5943
|
+
disposed = true;
|
|
5864
5944
|
validateDragRef.current = void 0;
|
|
5865
5945
|
element.removeEventListener("pointerdown", onPointerDown);
|
|
5866
5946
|
element.removeEventListener("pointermove", onPointerMove);
|
|
@@ -11410,6 +11490,93 @@ var import_fiber21 = require("@react-three/fiber");
|
|
|
11410
11490
|
var import_react42 = require("react");
|
|
11411
11491
|
var import_three24 = require("three");
|
|
11412
11492
|
|
|
11493
|
+
// src/hotspot/drag-session.ts
|
|
11494
|
+
var CLICK_SUPPRESS_MS = 1e3;
|
|
11495
|
+
function trackPointerDrag(source, element, pointerId, onMove, onEnd) {
|
|
11496
|
+
let stopped = false;
|
|
11497
|
+
const releaseCapture = () => {
|
|
11498
|
+
if (!element.hasPointerCapture?.(pointerId)) {
|
|
11499
|
+
return;
|
|
11500
|
+
}
|
|
11501
|
+
try {
|
|
11502
|
+
element.releasePointerCapture?.(pointerId);
|
|
11503
|
+
} catch {
|
|
11504
|
+
}
|
|
11505
|
+
};
|
|
11506
|
+
const stop = () => {
|
|
11507
|
+
if (stopped) {
|
|
11508
|
+
return;
|
|
11509
|
+
}
|
|
11510
|
+
stopped = true;
|
|
11511
|
+
source.removeEventListener("pointermove", onPointerMove, true);
|
|
11512
|
+
source.removeEventListener("pointerup", onPointerUp, true);
|
|
11513
|
+
source.removeEventListener("pointercancel", onPointerCancel, true);
|
|
11514
|
+
element.removeEventListener("lostpointercapture", onLostCapture);
|
|
11515
|
+
releaseCapture();
|
|
11516
|
+
};
|
|
11517
|
+
const finish = (event) => {
|
|
11518
|
+
if (stopped || event.pointerId !== pointerId) {
|
|
11519
|
+
return;
|
|
11520
|
+
}
|
|
11521
|
+
stop();
|
|
11522
|
+
onEnd(event);
|
|
11523
|
+
};
|
|
11524
|
+
const onPointerMove = (event) => {
|
|
11525
|
+
if (stopped || event.pointerId !== pointerId) {
|
|
11526
|
+
return;
|
|
11527
|
+
}
|
|
11528
|
+
try {
|
|
11529
|
+
event.preventDefault?.();
|
|
11530
|
+
} catch {
|
|
11531
|
+
}
|
|
11532
|
+
onMove(event);
|
|
11533
|
+
};
|
|
11534
|
+
const onPointerUp = (event) => {
|
|
11535
|
+
finish(event);
|
|
11536
|
+
};
|
|
11537
|
+
const onPointerCancel = (event) => {
|
|
11538
|
+
finish(event);
|
|
11539
|
+
};
|
|
11540
|
+
const onLostCapture = (event) => {
|
|
11541
|
+
if ((event.buttons ?? 0) > 0) {
|
|
11542
|
+
return;
|
|
11543
|
+
}
|
|
11544
|
+
finish(event);
|
|
11545
|
+
};
|
|
11546
|
+
try {
|
|
11547
|
+
element.setPointerCapture?.(pointerId);
|
|
11548
|
+
} catch {
|
|
11549
|
+
}
|
|
11550
|
+
source.addEventListener("pointermove", onPointerMove, true);
|
|
11551
|
+
source.addEventListener("pointerup", onPointerUp, true);
|
|
11552
|
+
source.addEventListener("pointercancel", onPointerCancel, true);
|
|
11553
|
+
element.addEventListener("lostpointercapture", onLostCapture);
|
|
11554
|
+
return stop;
|
|
11555
|
+
}
|
|
11556
|
+
function suppressFollowingClick(target) {
|
|
11557
|
+
let cleaned = false;
|
|
11558
|
+
const cleanup = () => {
|
|
11559
|
+
if (cleaned) {
|
|
11560
|
+
return;
|
|
11561
|
+
}
|
|
11562
|
+
cleaned = true;
|
|
11563
|
+
target.removeEventListener("click", swallowClick, true);
|
|
11564
|
+
target.removeEventListener("pointerdown", cancel, true);
|
|
11565
|
+
};
|
|
11566
|
+
const swallowClick = (event) => {
|
|
11567
|
+
event.preventDefault();
|
|
11568
|
+
event.stopPropagation();
|
|
11569
|
+
event.stopImmediatePropagation();
|
|
11570
|
+
cleanup();
|
|
11571
|
+
};
|
|
11572
|
+
const cancel = () => {
|
|
11573
|
+
cleanup();
|
|
11574
|
+
};
|
|
11575
|
+
target.addEventListener("click", swallowClick, true);
|
|
11576
|
+
target.addEventListener("pointerdown", cancel, true);
|
|
11577
|
+
setTimeout(cleanup, CLICK_SUPPRESS_MS);
|
|
11578
|
+
}
|
|
11579
|
+
|
|
11413
11580
|
// src/hotspot/hotspot-tooltip.tsx
|
|
11414
11581
|
var import_react40 = require("react");
|
|
11415
11582
|
|
|
@@ -11669,6 +11836,21 @@ function fixedScaleFactor(cameraFov, referenceFov) {
|
|
|
11669
11836
|
const safeReferenceFov = import_three22.MathUtils.clamp(referenceFov, 1, 179);
|
|
11670
11837
|
return Math.tan(import_three22.MathUtils.degToRad(cameraFov) / 2) / Math.tan(import_three22.MathUtils.degToRad(safeReferenceFov) / 2);
|
|
11671
11838
|
}
|
|
11839
|
+
function selectionFrameScale(worldScaleX, worldScaleY, cameraSpaceDepth, fovDegrees, viewportHeight, outsetPixels) {
|
|
11840
|
+
const pixels = Number.isFinite(outsetPixels) && outsetPixels > 0 ? outsetPixels : 0;
|
|
11841
|
+
const depth = Number.isFinite(cameraSpaceDepth) ? Math.max(cameraSpaceDepth, 1e-4) : 1e-4;
|
|
11842
|
+
const height = Number.isFinite(viewportHeight) ? Math.max(viewportHeight, 1) : 1;
|
|
11843
|
+
const fov = Number.isFinite(fovDegrees) ? import_three22.MathUtils.clamp(fovDegrees, 1, 179) : 75;
|
|
11844
|
+
const pixelsPerWorldUnit = height / (2 * Math.tan(import_three22.MathUtils.degToRad(fov) * 0.5) * depth);
|
|
11845
|
+
const axis = (worldScale) => {
|
|
11846
|
+
const pixelsPerLocalUnit = pixelsPerWorldUnit * Math.abs(worldScale);
|
|
11847
|
+
if (pixelsPerLocalUnit < 1e-4) {
|
|
11848
|
+
return 1;
|
|
11849
|
+
}
|
|
11850
|
+
return 1 + 2 * pixels / pixelsPerLocalUnit;
|
|
11851
|
+
};
|
|
11852
|
+
return [axis(worldScaleX), axis(worldScaleY)];
|
|
11853
|
+
}
|
|
11672
11854
|
|
|
11673
11855
|
// src/hotspot/hotspot-stroke-line.tsx
|
|
11674
11856
|
var import_drei = require("@react-three/drei");
|
|
@@ -11751,6 +11933,11 @@ var DEFAULT_REFERENCE_FOV = 75;
|
|
|
11751
11933
|
var MIN_ANGULAR_SIZE = 0.01;
|
|
11752
11934
|
var MAX_ANGULAR_SIZE = 179;
|
|
11753
11935
|
var DRAG_EPSILON_DEGREES = 1e-3;
|
|
11936
|
+
var SELECTION_BORDER_WIDTH = 3;
|
|
11937
|
+
var SELECTION_BORDER_GAP = 3;
|
|
11938
|
+
var SELECTION_BORDER_OUTSET = SELECTION_BORDER_GAP + SELECTION_BORDER_WIDTH / 2;
|
|
11939
|
+
var SELECTION_CAMERA_POSITION = new import_three24.Vector3();
|
|
11940
|
+
var SELECTION_WORLD_SCALE = new import_three24.Vector3();
|
|
11754
11941
|
var SELECTION_BORDER_POINTS = [
|
|
11755
11942
|
[-0.5, -0.5, 1e-3],
|
|
11756
11943
|
[0.5, -0.5, 1e-3],
|
|
@@ -11838,6 +12025,34 @@ function angularDistance(a, b) {
|
|
|
11838
12025
|
const bVector = panoPositionToVector3(b);
|
|
11839
12026
|
return import_three24.MathUtils.radToDeg(aVector.angleTo(bVector));
|
|
11840
12027
|
}
|
|
12028
|
+
var DRAG_POINTER = new import_three24.Vector2();
|
|
12029
|
+
var DRAG_RAYCASTER = new import_three24.Raycaster();
|
|
12030
|
+
function aimDragRaycaster(event, element, camera) {
|
|
12031
|
+
const rect = element.getBoundingClientRect();
|
|
12032
|
+
if (!(rect.width > 0) || !(rect.height > 0)) {
|
|
12033
|
+
return false;
|
|
12034
|
+
}
|
|
12035
|
+
DRAG_POINTER.set(
|
|
12036
|
+
(event.clientX - rect.left) / rect.width * 2 - 1,
|
|
12037
|
+
-((event.clientY - rect.top) / rect.height) * 2 + 1
|
|
12038
|
+
);
|
|
12039
|
+
camera.updateMatrixWorld();
|
|
12040
|
+
DRAG_RAYCASTER.setFromCamera(DRAG_POINTER, camera);
|
|
12041
|
+
return true;
|
|
12042
|
+
}
|
|
12043
|
+
function pointerToPanoPosition(event, element, camera) {
|
|
12044
|
+
if (!aimDragRaycaster(event, element, camera)) {
|
|
12045
|
+
return null;
|
|
12046
|
+
}
|
|
12047
|
+
return vector3ToPanoPosition(DRAG_RAYCASTER.ray.direction);
|
|
12048
|
+
}
|
|
12049
|
+
function pointerHitsHotspot(event, element, camera, group) {
|
|
12050
|
+
if (!group || !aimDragRaycaster(event, element, camera)) {
|
|
12051
|
+
return false;
|
|
12052
|
+
}
|
|
12053
|
+
group.updateMatrixWorld(true);
|
|
12054
|
+
return DRAG_RAYCASTER.intersectObject(group, true).length > 0;
|
|
12055
|
+
}
|
|
11841
12056
|
function isTooltipOpen(trigger, hovered, focused, pinned) {
|
|
11842
12057
|
switch (trigger) {
|
|
11843
12058
|
case "always":
|
|
@@ -12033,6 +12248,24 @@ function updateTooltipAnchor(anchor, group, placement, useAngularScale, camera,
|
|
|
12033
12248
|
}
|
|
12034
12249
|
setTooltipAnchorOnLocalBox(anchor, placement, -0.5, 0.5, -0.5, 0.5);
|
|
12035
12250
|
}
|
|
12251
|
+
function placeSelectionFrame(frame, group, camera, viewportHeight) {
|
|
12252
|
+
if (!frame) {
|
|
12253
|
+
return;
|
|
12254
|
+
}
|
|
12255
|
+
group.getWorldScale(SELECTION_WORLD_SCALE);
|
|
12256
|
+
SELECTION_CAMERA_POSITION.setFromMatrixPosition(group.matrixWorld).applyMatrix4(
|
|
12257
|
+
camera.matrixWorldInverse
|
|
12258
|
+
);
|
|
12259
|
+
const [scaleX, scaleY] = selectionFrameScale(
|
|
12260
|
+
SELECTION_WORLD_SCALE.x,
|
|
12261
|
+
SELECTION_WORLD_SCALE.y,
|
|
12262
|
+
-SELECTION_CAMERA_POSITION.z,
|
|
12263
|
+
camera instanceof import_three24.PerspectiveCamera ? camera.fov : DEFAULT_REFERENCE_FOV,
|
|
12264
|
+
viewportHeight,
|
|
12265
|
+
SELECTION_BORDER_OUTSET
|
|
12266
|
+
);
|
|
12267
|
+
frame.scale.set(scaleX, scaleY, 1);
|
|
12268
|
+
}
|
|
12036
12269
|
function HotspotAnchor({
|
|
12037
12270
|
id,
|
|
12038
12271
|
position,
|
|
@@ -12072,10 +12305,13 @@ function HotspotAnchor({
|
|
|
12072
12305
|
const hotspotTargetRegistry = (0, import_react42.useContext)(HotspotTargetRegistryContext);
|
|
12073
12306
|
const eventBus = (0, import_react42.useContext)(PanoEventBusContext);
|
|
12074
12307
|
const cursorApi = usePanoCursor();
|
|
12075
|
-
const { camera, size } = (0, import_fiber21.useThree)();
|
|
12308
|
+
const { camera, gl, size } = (0, import_fiber21.useThree)();
|
|
12076
12309
|
const groupRef = (0, import_react42.useRef)(null);
|
|
12310
|
+
const selectionFrameRef = (0, import_react42.useRef)(null);
|
|
12077
12311
|
const tooltipAnchorRef = (0, import_react42.useRef)(null);
|
|
12078
12312
|
const dragStateRef = (0, import_react42.useRef)(null);
|
|
12313
|
+
const updateDragRef = (0, import_react42.useRef)(() => void 0);
|
|
12314
|
+
const endDragRef = (0, import_react42.useRef)(() => void 0);
|
|
12079
12315
|
const suppressNextClickRef = (0, import_react42.useRef)(false);
|
|
12080
12316
|
const [hovered, setHovered] = (0, import_react42.useState)(false);
|
|
12081
12317
|
const [dragging, setDragging] = (0, import_react42.useState)(false);
|
|
@@ -12145,7 +12381,9 @@ function HotspotAnchor({
|
|
|
12145
12381
|
const cursorClaimId = hotspotCursorClaimId(id);
|
|
12146
12382
|
(0, import_react42.useEffect)(
|
|
12147
12383
|
() => () => {
|
|
12148
|
-
dragStateRef.current
|
|
12384
|
+
const dragState = dragStateRef.current;
|
|
12385
|
+
dragState?.stopTracking();
|
|
12386
|
+
dragState?.releaseInteractionLock();
|
|
12149
12387
|
dragStateRef.current = null;
|
|
12150
12388
|
},
|
|
12151
12389
|
[]
|
|
@@ -12202,6 +12440,7 @@ function HotspotAnchor({
|
|
|
12202
12440
|
if (!dragState) {
|
|
12203
12441
|
return;
|
|
12204
12442
|
}
|
|
12443
|
+
dragState.stopTracking();
|
|
12205
12444
|
dragState.releaseInteractionLock();
|
|
12206
12445
|
dragStateRef.current = null;
|
|
12207
12446
|
setDragging(false);
|
|
@@ -12224,6 +12463,7 @@ function HotspotAnchor({
|
|
|
12224
12463
|
worldHeight,
|
|
12225
12464
|
resolvedDistance
|
|
12226
12465
|
);
|
|
12466
|
+
placeSelectionFrame(selectionFrameRef.current, group, camera, size.height);
|
|
12227
12467
|
if (tooltipOpen && tooltipAnchorRef.current) {
|
|
12228
12468
|
updateTooltipAnchor(
|
|
12229
12469
|
tooltipAnchorRef.current,
|
|
@@ -12242,6 +12482,7 @@ function HotspotAnchor({
|
|
|
12242
12482
|
rotation,
|
|
12243
12483
|
scaleMode,
|
|
12244
12484
|
size,
|
|
12485
|
+
selected,
|
|
12245
12486
|
surfaceQuaternion3,
|
|
12246
12487
|
tooltipOpen,
|
|
12247
12488
|
tooltipPlacement,
|
|
@@ -12267,6 +12508,12 @@ function HotspotAnchor({
|
|
|
12267
12508
|
worldHeight,
|
|
12268
12509
|
resolvedDistance
|
|
12269
12510
|
);
|
|
12511
|
+
placeSelectionFrame(
|
|
12512
|
+
selectionFrameRef.current,
|
|
12513
|
+
group,
|
|
12514
|
+
state.camera,
|
|
12515
|
+
state.size.height
|
|
12516
|
+
);
|
|
12270
12517
|
if (tooltipOpen && tooltipAnchorRef.current) {
|
|
12271
12518
|
updateTooltipAnchor(
|
|
12272
12519
|
tooltipAnchorRef.current,
|
|
@@ -12282,31 +12529,78 @@ function HotspotAnchor({
|
|
|
12282
12529
|
event.stopPropagation();
|
|
12283
12530
|
event.nativeEvent.stopImmediatePropagation?.();
|
|
12284
12531
|
};
|
|
12285
|
-
const
|
|
12532
|
+
const dragPosition = (dragState, event) => {
|
|
12533
|
+
const pointerPosition = pointerToPanoPosition(event, gl.domElement, camera);
|
|
12534
|
+
if (!pointerPosition) {
|
|
12535
|
+
return dragState.lastPosition;
|
|
12536
|
+
}
|
|
12537
|
+
return translateHotspotPosition(
|
|
12538
|
+
dragState.startPosition,
|
|
12539
|
+
dragState.pointerOrigin,
|
|
12540
|
+
pointerPosition
|
|
12541
|
+
);
|
|
12542
|
+
};
|
|
12543
|
+
updateDragRef.current = (nativeEvent) => {
|
|
12286
12544
|
const dragState = dragStateRef.current;
|
|
12287
|
-
if (!dragState || dragState.pointerId !==
|
|
12545
|
+
if (!dragState || dragState.pointerId !== nativeEvent.pointerId) {
|
|
12288
12546
|
return;
|
|
12289
12547
|
}
|
|
12290
|
-
|
|
12291
|
-
|
|
12292
|
-
|
|
12293
|
-
|
|
12294
|
-
|
|
12295
|
-
|
|
12296
|
-
|
|
12297
|
-
|
|
12298
|
-
|
|
12299
|
-
|
|
12300
|
-
|
|
12301
|
-
|
|
12548
|
+
const nextPosition = dragPosition(dragState, nativeEvent);
|
|
12549
|
+
dragState.lastPosition = nextPosition;
|
|
12550
|
+
dragState.moved || (dragState.moved = angularDistance(dragState.startPosition, nextPosition) > DRAG_EPSILON_DEGREES);
|
|
12551
|
+
onPositionChange?.({
|
|
12552
|
+
id,
|
|
12553
|
+
position: nextPosition,
|
|
12554
|
+
source: "pointer",
|
|
12555
|
+
nativeEvent,
|
|
12556
|
+
startPosition: dragState.startPosition
|
|
12557
|
+
});
|
|
12558
|
+
};
|
|
12559
|
+
endDragRef.current = (nativeEvent, emitDragEnd) => {
|
|
12560
|
+
const dragState = dragStateRef.current;
|
|
12561
|
+
if (!dragState || dragState.pointerId !== nativeEvent.pointerId) {
|
|
12562
|
+
return;
|
|
12302
12563
|
}
|
|
12303
|
-
|
|
12564
|
+
const nextPosition = dragPosition(dragState, nativeEvent);
|
|
12565
|
+
dragState.lastPosition = nextPosition;
|
|
12566
|
+
dragState.moved || (dragState.moved = angularDistance(dragState.startPosition, nextPosition) > DRAG_EPSILON_DEGREES);
|
|
12567
|
+
const moved = dragState.moved;
|
|
12568
|
+
const startPosition = dragState.startPosition;
|
|
12569
|
+
dragState.stopTracking();
|
|
12304
12570
|
dragState.releaseInteractionLock();
|
|
12305
12571
|
dragStateRef.current = null;
|
|
12572
|
+
suppressNextClickRef.current = moved;
|
|
12306
12573
|
setDragging(false);
|
|
12307
|
-
if (emitDragEnd) {
|
|
12308
|
-
|
|
12574
|
+
if (!emitDragEnd) {
|
|
12575
|
+
return;
|
|
12576
|
+
}
|
|
12577
|
+
const overHotspot = pointerHitsHotspot(
|
|
12578
|
+
nativeEvent,
|
|
12579
|
+
gl.domElement,
|
|
12580
|
+
camera,
|
|
12581
|
+
groupRef.current
|
|
12582
|
+
);
|
|
12583
|
+
eventHovered.current = overHotspot;
|
|
12584
|
+
setHovered(overHotspot);
|
|
12585
|
+
if (moved && typeof window !== "undefined") {
|
|
12586
|
+
suppressFollowingClick(window);
|
|
12309
12587
|
}
|
|
12588
|
+
if (moved) {
|
|
12589
|
+
onPositionChange?.({
|
|
12590
|
+
id,
|
|
12591
|
+
position: nextPosition,
|
|
12592
|
+
source: "pointer",
|
|
12593
|
+
nativeEvent,
|
|
12594
|
+
startPosition
|
|
12595
|
+
});
|
|
12596
|
+
}
|
|
12597
|
+
onDragEnd?.({
|
|
12598
|
+
id,
|
|
12599
|
+
position: nextPosition,
|
|
12600
|
+
source: "pointer",
|
|
12601
|
+
nativeEvent,
|
|
12602
|
+
startPosition
|
|
12603
|
+
});
|
|
12310
12604
|
};
|
|
12311
12605
|
return /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
|
|
12312
12606
|
"group",
|
|
@@ -12326,23 +12620,42 @@ function HotspotAnchor({
|
|
|
12326
12620
|
}
|
|
12327
12621
|
suppressNextClickRef.current = false;
|
|
12328
12622
|
} : void 0,
|
|
12329
|
-
onLostPointerCapture: acceptsPointer ? (event) =>
|
|
12330
|
-
|
|
12623
|
+
onLostPointerCapture: acceptsPointer ? (event) => {
|
|
12624
|
+
endDragRef.current(event.nativeEvent, true);
|
|
12625
|
+
} : void 0,
|
|
12626
|
+
onPointerCancel: acceptsPointer ? (event) => {
|
|
12627
|
+
endDragRef.current(event.nativeEvent, true);
|
|
12628
|
+
} : void 0,
|
|
12331
12629
|
onPointerDown: acceptsPointer ? (event) => {
|
|
12332
|
-
|
|
12630
|
+
const native = event.nativeEvent;
|
|
12333
12631
|
if (!draggable || dragStateRef.current) {
|
|
12632
|
+
stopPointerEvent(event);
|
|
12334
12633
|
return;
|
|
12335
12634
|
}
|
|
12635
|
+
const pointerId = native.pointerId;
|
|
12636
|
+
stopPointerEvent(event);
|
|
12336
12637
|
const releaseInteractionLock = controlsRef?.current?.acquireInteractionLock() ?? (() => void 0);
|
|
12337
|
-
const
|
|
12338
|
-
target.setPointerCapture?.(event.pointerId);
|
|
12638
|
+
const pointerOrigin = pointerToPanoPosition(native, gl.domElement, camera) ?? vector3ToPanoPosition(event.ray.direction);
|
|
12339
12639
|
const startPosition = { ...normalizedPosition };
|
|
12640
|
+
const tracksOutsideMesh = typeof window !== "undefined";
|
|
12641
|
+
const stopTracking = tracksOutsideMesh ? trackPointerDrag(
|
|
12642
|
+
window,
|
|
12643
|
+
gl.domElement,
|
|
12644
|
+
pointerId,
|
|
12645
|
+
(pointerEvent) => updateDragRef.current(pointerEvent),
|
|
12646
|
+
(pointerEvent) => endDragRef.current(pointerEvent, true)
|
|
12647
|
+
) : () => void 0;
|
|
12340
12648
|
dragStateRef.current = {
|
|
12341
|
-
pointerId
|
|
12649
|
+
pointerId,
|
|
12342
12650
|
startPosition,
|
|
12651
|
+
pointerOrigin,
|
|
12652
|
+
lastPosition: startPosition,
|
|
12343
12653
|
releaseInteractionLock,
|
|
12344
|
-
moved: false
|
|
12654
|
+
moved: false,
|
|
12655
|
+
tracksOutsideMesh,
|
|
12656
|
+
stopTracking
|
|
12345
12657
|
};
|
|
12658
|
+
eventHovered.current = false;
|
|
12346
12659
|
setHovered(false);
|
|
12347
12660
|
setDragging(true);
|
|
12348
12661
|
onDragStart?.({
|
|
@@ -12353,17 +12666,13 @@ function HotspotAnchor({
|
|
|
12353
12666
|
} : void 0,
|
|
12354
12667
|
onPointerMove: acceptsPointer ? (event) => {
|
|
12355
12668
|
const dragState = dragStateRef.current;
|
|
12356
|
-
if (!dragState || dragState.pointerId !== event.pointerId) {
|
|
12669
|
+
if (!dragState || dragState.pointerId !== event.nativeEvent.pointerId) {
|
|
12357
12670
|
return;
|
|
12358
12671
|
}
|
|
12359
12672
|
stopPointerEvent(event);
|
|
12360
|
-
|
|
12361
|
-
|
|
12362
|
-
|
|
12363
|
-
...makeInteractionEvent(id, nextPosition, event),
|
|
12364
|
-
source: "pointer",
|
|
12365
|
-
startPosition: dragState.startPosition
|
|
12366
|
-
});
|
|
12673
|
+
if (!dragState.tracksOutsideMesh) {
|
|
12674
|
+
updateDragRef.current(event.nativeEvent);
|
|
12675
|
+
}
|
|
12367
12676
|
} : void 0,
|
|
12368
12677
|
onPointerOut: acceptsPointer ? (event) => {
|
|
12369
12678
|
if (!dragStateRef.current) {
|
|
@@ -12392,7 +12701,10 @@ function HotspotAnchor({
|
|
|
12392
12701
|
);
|
|
12393
12702
|
}
|
|
12394
12703
|
} : void 0,
|
|
12395
|
-
onPointerUp: acceptsPointer ? (event) =>
|
|
12704
|
+
onPointerUp: acceptsPointer ? (event) => {
|
|
12705
|
+
stopPointerEvent(event);
|
|
12706
|
+
endDragRef.current(event.nativeEvent, true);
|
|
12707
|
+
} : void 0,
|
|
12396
12708
|
children: [
|
|
12397
12709
|
focused ? focusContent ?? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
12398
12710
|
"lineSegments",
|
|
@@ -12405,16 +12717,16 @@ function HotspotAnchor({
|
|
|
12405
12717
|
}
|
|
12406
12718
|
) : null,
|
|
12407
12719
|
children,
|
|
12408
|
-
selected && useAngularScale ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
12720
|
+
selected && useAngularScale ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("group", { ref: selectionFrameRef, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
12409
12721
|
HotspotStrokeLine,
|
|
12410
12722
|
{
|
|
12411
12723
|
points: SELECTION_BORDER_POINTS,
|
|
12412
12724
|
color: "#ffb300",
|
|
12413
|
-
lineWidth:
|
|
12725
|
+
lineWidth: SELECTION_BORDER_WIDTH,
|
|
12414
12726
|
opacity: 1,
|
|
12415
12727
|
renderOrder: renderOrder + 1
|
|
12416
12728
|
}
|
|
12417
|
-
) : null,
|
|
12729
|
+
) }) : null,
|
|
12418
12730
|
tooltipOpen && tooltipContent ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("group", { ref: tooltipAnchorRef, children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
|
|
12419
12731
|
HotspotTooltip,
|
|
12420
12732
|
{
|
|
@@ -13917,11 +14229,15 @@ function createTextTexture(text, width, height, style, rasterLong) {
|
|
|
13917
14229
|
if (!context) {
|
|
13918
14230
|
throw new Error("Canvas 2D is unavailable for this text hotspot.");
|
|
13919
14231
|
}
|
|
13920
|
-
|
|
13921
|
-
|
|
13922
|
-
|
|
13923
|
-
|
|
13924
|
-
|
|
14232
|
+
context.setTransform(
|
|
14233
|
+
canvasWidth / layout.canvasWidth,
|
|
14234
|
+
0,
|
|
14235
|
+
0,
|
|
14236
|
+
canvasHeight / layout.canvasHeight,
|
|
14237
|
+
0,
|
|
14238
|
+
0
|
|
14239
|
+
);
|
|
14240
|
+
drawTextHotspot(context, layout.canvasWidth, layout.canvasHeight, text, style);
|
|
13925
14241
|
const texture = new import_three32.CanvasTexture(canvas);
|
|
13926
14242
|
texture.colorSpace = import_three32.SRGBColorSpace;
|
|
13927
14243
|
texture.wrapS = import_three32.ClampToEdgeWrapping;
|
|
@@ -13981,13 +14297,7 @@ function useTextTexture(text, width, height, style, scale, scaleMode, referenceF
|
|
|
13981
14297
|
let nextTexture = null;
|
|
13982
14298
|
const run = async () => {
|
|
13983
14299
|
try {
|
|
13984
|
-
const
|
|
13985
|
-
const layoutLong = Math.max(layout.canvasWidth, layout.canvasHeight);
|
|
13986
|
-
const drawScale = rasterLong / layoutLong;
|
|
13987
|
-
const { font } = resolveTextFont({
|
|
13988
|
-
...style,
|
|
13989
|
-
fontSize: resolvePositive(style.fontSize, DEFAULT_FONT_SIZE) * drawScale
|
|
13990
|
-
});
|
|
14300
|
+
const { font } = resolveTextFont(style);
|
|
13991
14301
|
try {
|
|
13992
14302
|
await document.fonts?.load(font);
|
|
13993
14303
|
} catch {
|