@ericchen1990/pano-view 3.6.1 → 3.6.2
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.md +1 -1
- package/README.zh-CN.md +1 -1
- package/dist/index.cjs +108 -29
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +108 -29
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -2842,7 +2842,12 @@ var PanoramaViewRuntime = forwardRef(function PanoramaViewRuntime2({ initialView
|
|
|
2842
2842
|
}
|
|
2843
2843
|
}
|
|
2844
2844
|
markDirty();
|
|
2845
|
-
|
|
2845
|
+
const releaseVelocity = applyOptions?.velocity;
|
|
2846
|
+
if (!gyroControlsView && releaseVelocity && Number.isFinite(releaseVelocity.yaw) && Number.isFinite(releaseVelocity.pitch)) {
|
|
2847
|
+
yawVelocityRef.current = releaseVelocity.yaw;
|
|
2848
|
+
pitchVelocityRef.current = releaseVelocity.pitch;
|
|
2849
|
+
lastVelocitySampleAtRef.current = performance.now();
|
|
2850
|
+
} else if (applyOptions?.recordVelocity && !gyroControlsView) {
|
|
2846
2851
|
const now = performance.now();
|
|
2847
2852
|
const previousAt = lastVelocitySampleAtRef.current;
|
|
2848
2853
|
const elapsed = previousAt === null ? 1 / 60 : Math.max((now - previousAt) / 1e3, 1 / 120);
|
|
@@ -3690,6 +3695,26 @@ import { useContext as useContext5, useEffect as useEffect5, useRef as useRef5 }
|
|
|
3690
3695
|
import { Euler as Euler2, MathUtils as MathUtils2, PerspectiveCamera as PerspectiveCamera2, Vector3 } from "three";
|
|
3691
3696
|
var DEFAULT_POINTER_DRAG_SPEED = 0.35;
|
|
3692
3697
|
var POINTER_FOLLOW_TIME_SECONDS = 0.01;
|
|
3698
|
+
var MIN_VELOCITY_SAMPLE_SECONDS = 1 / 120;
|
|
3699
|
+
function pointerReleaseVelocity(samples, releasedAt, solve, maxAgeMs = POINTER_VELOCITY_MAX_AGE_MS) {
|
|
3700
|
+
if (samples.length < 2) return { yaw: 0, pitch: 0 };
|
|
3701
|
+
const newest = samples[samples.length - 1];
|
|
3702
|
+
if (releasedAt < newest.at || releasedAt - newest.at > maxAgeMs) return { yaw: 0, pitch: 0 };
|
|
3703
|
+
let oldest = newest;
|
|
3704
|
+
for (let index = samples.length - 1; index >= 0; index -= 1) {
|
|
3705
|
+
const sample = samples[index];
|
|
3706
|
+
if (releasedAt - sample.at <= maxAgeMs) oldest = sample;
|
|
3707
|
+
else break;
|
|
3708
|
+
}
|
|
3709
|
+
if (oldest === newest) return { yaw: 0, pitch: 0 };
|
|
3710
|
+
const elapsed = Math.max((newest.at - oldest.at) / 1e3, MIN_VELOCITY_SAMPLE_SECONDS);
|
|
3711
|
+
const from = solve(oldest);
|
|
3712
|
+
const to = solve(newest);
|
|
3713
|
+
return {
|
|
3714
|
+
yaw: normalizeViewYaw(to.yaw - from.yaw) / elapsed,
|
|
3715
|
+
pitch: (to.pitch - from.pitch) / elapsed
|
|
3716
|
+
};
|
|
3717
|
+
}
|
|
3693
3718
|
var PointerDragAnchor = class {
|
|
3694
3719
|
constructor(start, origin, rect, projection) {
|
|
3695
3720
|
this.start = start;
|
|
@@ -3747,8 +3772,11 @@ function createPointerDrag(camera, element, runtime, source) {
|
|
|
3747
3772
|
let lastPoint;
|
|
3748
3773
|
let fresh = false;
|
|
3749
3774
|
let lastFrameDelta = 1 / 60;
|
|
3775
|
+
let samples = [];
|
|
3776
|
+
let gestureSpeed = DEFAULT_POINTER_DRAG_SPEED;
|
|
3777
|
+
let gestureInvert = false;
|
|
3750
3778
|
const key = (rect) => `${rect.left},${rect.top},${rect.width},${rect.height},${camera.projectionMatrix.elements.join(",")}`;
|
|
3751
|
-
const
|
|
3779
|
+
const place = (point) => {
|
|
3752
3780
|
const handle = runtime();
|
|
3753
3781
|
displayed = { ...point };
|
|
3754
3782
|
lastPoint = { ...point };
|
|
@@ -3760,69 +3788,113 @@ function createPointerDrag(camera, element, runtime, source) {
|
|
|
3760
3788
|
projectionKey = key(rect);
|
|
3761
3789
|
anchor = new PointerDragAnchor(point, handle.getView(), rect, camera.clone());
|
|
3762
3790
|
};
|
|
3763
|
-
const
|
|
3791
|
+
const remember = (point, at) => {
|
|
3792
|
+
samples.push({ x: point.x, y: point.y, at });
|
|
3793
|
+
const cutoff = at - POINTER_VELOCITY_MAX_AGE_MS;
|
|
3794
|
+
while (samples.length > 2 && samples[0].at < cutoff) samples.shift();
|
|
3795
|
+
};
|
|
3796
|
+
const apply = (point, previous, speed, invert, recordVelocity, releaseVelocity) => {
|
|
3764
3797
|
const handle = runtime();
|
|
3765
3798
|
if (!handle) return;
|
|
3766
3799
|
const rect = element.getBoundingClientRect();
|
|
3767
3800
|
if (anchor && key(rect) !== projectionKey) {
|
|
3768
3801
|
const queued = pending;
|
|
3769
|
-
|
|
3802
|
+
place(displayed ?? previous);
|
|
3770
3803
|
pending = queued;
|
|
3771
3804
|
}
|
|
3805
|
+
const options = {
|
|
3806
|
+
recordVelocity: releaseVelocity ? false : recordVelocity,
|
|
3807
|
+
source,
|
|
3808
|
+
...releaseVelocity ? { velocity: releaseVelocity } : {}
|
|
3809
|
+
};
|
|
3772
3810
|
if (anchor) {
|
|
3773
3811
|
handle.applyViewDelta(anchor.solve(point, speed, invert), {
|
|
3774
|
-
|
|
3775
|
-
|
|
3776
|
-
source
|
|
3812
|
+
...options,
|
|
3813
|
+
pointerOrigin: anchor.origin
|
|
3777
3814
|
});
|
|
3778
3815
|
} else {
|
|
3779
3816
|
handle.applyViewDelta({
|
|
3780
3817
|
yaw: -(point.x - previous.x) * 360 * speed / Math.max(rect.width, 1) * (invert ? -1 : 1),
|
|
3781
3818
|
pitch: (point.y - previous.y) * 180 * speed / Math.max(rect.height, 1) * (invert ? -1 : 1)
|
|
3782
|
-
},
|
|
3819
|
+
}, options);
|
|
3783
3820
|
}
|
|
3784
3821
|
};
|
|
3822
|
+
const valid = () => revision === (runtime()?.getPointerDragState().revision ?? -1) && !runtime()?.isInteractionLocked();
|
|
3823
|
+
const clear = () => {
|
|
3824
|
+
anchor = void 0;
|
|
3825
|
+
revision = -1;
|
|
3826
|
+
pending = void 0;
|
|
3827
|
+
displayed = void 0;
|
|
3828
|
+
samples = [];
|
|
3829
|
+
};
|
|
3785
3830
|
return {
|
|
3786
|
-
start,
|
|
3787
|
-
|
|
3788
|
-
|
|
3789
|
-
|
|
3790
|
-
|
|
3791
|
-
|
|
3792
|
-
displayed = void 0;
|
|
3831
|
+
start(point, at = performance.now()) {
|
|
3832
|
+
gestureSpeed = DEFAULT_POINTER_DRAG_SPEED;
|
|
3833
|
+
gestureInvert = false;
|
|
3834
|
+
samples = [];
|
|
3835
|
+
remember(point, at);
|
|
3836
|
+
place(point);
|
|
3793
3837
|
},
|
|
3838
|
+
valid,
|
|
3839
|
+
clear,
|
|
3794
3840
|
suspend: () => {
|
|
3795
3841
|
anchor = void 0;
|
|
3796
3842
|
pending = void 0;
|
|
3797
3843
|
displayed = void 0;
|
|
3844
|
+
samples = [];
|
|
3798
3845
|
},
|
|
3799
|
-
move(point, previous, speed, invert) {
|
|
3846
|
+
move(point, previous, speed, invert, at = performance.now()) {
|
|
3800
3847
|
fresh = true;
|
|
3848
|
+
gestureSpeed = speed;
|
|
3849
|
+
gestureInvert = invert;
|
|
3850
|
+
remember(point, at);
|
|
3801
3851
|
pending = { point, previous: lastPoint ?? previous, speed, invert };
|
|
3802
3852
|
},
|
|
3803
|
-
flush(deltaSeconds = lastFrameDelta, immediate = false) {
|
|
3804
|
-
lastFrameDelta = deltaSeconds;
|
|
3853
|
+
flush(deltaSeconds = lastFrameDelta, immediate = false, releaseVelocity) {
|
|
3854
|
+
if (deltaSeconds > 0) lastFrameDelta = deltaSeconds;
|
|
3805
3855
|
if (!pending) return;
|
|
3806
3856
|
const sample = pending;
|
|
3807
3857
|
if (!anchor || immediate) {
|
|
3808
3858
|
pending = void 0;
|
|
3809
|
-
apply(sample.point, sample.previous, sample.speed, sample.invert, fresh);
|
|
3859
|
+
apply(sample.point, sample.previous, sample.speed, sample.invert, fresh, releaseVelocity);
|
|
3810
3860
|
fresh = false;
|
|
3811
3861
|
lastPoint = sample.point;
|
|
3812
3862
|
displayed = sample.point;
|
|
3813
3863
|
return;
|
|
3814
3864
|
}
|
|
3865
|
+
const dt = deltaSeconds > 0 ? deltaSeconds : lastFrameDelta;
|
|
3815
3866
|
const previousDisplay = displayed ?? sample.previous;
|
|
3816
3867
|
const dx = sample.point.x - previousDisplay.x;
|
|
3817
3868
|
const dy = sample.point.y - previousDisplay.y;
|
|
3818
3869
|
const distance = Math.hypot(dx, dy);
|
|
3819
|
-
const ratio = distance > 0.01 ? POINTER_FOLLOW_TIME_SECONDS / (POINTER_FOLLOW_TIME_SECONDS +
|
|
3870
|
+
const ratio = distance > 0.01 ? POINTER_FOLLOW_TIME_SECONDS / (POINTER_FOLLOW_TIME_SECONDS + dt) : 0;
|
|
3820
3871
|
const point = { x: sample.point.x - dx * ratio, y: sample.point.y - dy * ratio };
|
|
3821
3872
|
apply(point, sample.previous, sample.speed, sample.invert, fresh);
|
|
3822
3873
|
fresh = false;
|
|
3823
3874
|
lastPoint = sample.point;
|
|
3824
3875
|
displayed = point;
|
|
3825
3876
|
if (ratio === 0) pending = void 0;
|
|
3877
|
+
},
|
|
3878
|
+
release() {
|
|
3879
|
+
const handle = runtime();
|
|
3880
|
+
if (!handle || !valid()) {
|
|
3881
|
+
clear();
|
|
3882
|
+
return;
|
|
3883
|
+
}
|
|
3884
|
+
const newestAt = samples[samples.length - 1]?.at ?? 0;
|
|
3885
|
+
const velocity = pointerReleaseVelocity(samples, Math.max(performance.now(), newestAt), (point) => {
|
|
3886
|
+
if (anchor) return anchor.solve(point, gestureSpeed, gestureInvert);
|
|
3887
|
+
const origin = samples[0] ?? point;
|
|
3888
|
+
const rect = element.getBoundingClientRect();
|
|
3889
|
+
const sign = gestureInvert ? -1 : 1;
|
|
3890
|
+
return {
|
|
3891
|
+
yaw: -(point.x - origin.x) * 360 * gestureSpeed / Math.max(rect.width, 1) * sign,
|
|
3892
|
+
pitch: (point.y - origin.y) * 180 * gestureSpeed / Math.max(rect.height, 1) * sign
|
|
3893
|
+
};
|
|
3894
|
+
});
|
|
3895
|
+
if (pending) this.flush(lastFrameDelta, true, velocity);
|
|
3896
|
+
else handle.applyViewDelta({}, { velocity, source });
|
|
3897
|
+
clear();
|
|
3826
3898
|
}
|
|
3827
3899
|
};
|
|
3828
3900
|
}
|
|
@@ -3838,6 +3910,9 @@ var BUTTON_FLAG = {
|
|
|
3838
3910
|
function resolveSpeed2(value, fallback) {
|
|
3839
3911
|
return Number.isFinite(value) && value >= 0 ? value : fallback;
|
|
3840
3912
|
}
|
|
3913
|
+
function pointerAt(event) {
|
|
3914
|
+
return event.timeStamp > 0 ? event.timeStamp : performance.now();
|
|
3915
|
+
}
|
|
3841
3916
|
function resolveButtons(buttons) {
|
|
3842
3917
|
const list = buttons && buttons.length > 0 ? buttons : ["left"];
|
|
3843
3918
|
return new Set(list.map((button) => BUTTON_FLAG[button]));
|
|
@@ -3924,7 +3999,7 @@ function MouseControls({
|
|
|
3924
3999
|
});
|
|
3925
4000
|
element.setPointerCapture?.(event.pointerId);
|
|
3926
4001
|
syncActive();
|
|
3927
|
-
drag.start({ x: event.clientX, y: event.clientY });
|
|
4002
|
+
drag.start({ x: event.clientX, y: event.clientY }, pointerAt(event));
|
|
3928
4003
|
};
|
|
3929
4004
|
const onPointerMove = (event) => {
|
|
3930
4005
|
if (!isMouseLike(event)) {
|
|
@@ -3945,15 +4020,15 @@ function MouseControls({
|
|
|
3945
4020
|
};
|
|
3946
4021
|
pointersRef.current.set(event.pointerId, next);
|
|
3947
4022
|
const speed = resolveSpeed2(optionsRef.current.rotateSpeed, DEFAULT_ROTATE_SPEED2);
|
|
3948
|
-
drag.move(next, previous, speed, optionsRef.current.invert);
|
|
4023
|
+
drag.move(next, previous, speed, optionsRef.current.invert, pointerAt(event));
|
|
3949
4024
|
};
|
|
3950
4025
|
const releasePointer = (event) => {
|
|
3951
4026
|
if (!pointersRef.current.has(event.pointerId)) {
|
|
3952
4027
|
return;
|
|
3953
4028
|
}
|
|
3954
|
-
if (event.type === "pointerup") drag.
|
|
4029
|
+
if (event.type === "pointerup") drag.release();
|
|
4030
|
+
else drag.clear();
|
|
3955
4031
|
pointersRef.current.delete(event.pointerId);
|
|
3956
|
-
drag.clear();
|
|
3957
4032
|
if (element.hasPointerCapture?.(event.pointerId)) {
|
|
3958
4033
|
element.releasePointerCapture?.(event.pointerId);
|
|
3959
4034
|
}
|
|
@@ -5619,6 +5694,9 @@ function notifyScenesHost(host) {
|
|
|
5619
5694
|
import { useFrame as useFrame6, useThree as useThree7 } from "@react-three/fiber";
|
|
5620
5695
|
import { useContext as useContext13, useEffect as useEffect11, useRef as useRef10 } from "react";
|
|
5621
5696
|
var DEFAULT_ROTATE_SPEED3 = 0.35;
|
|
5697
|
+
function pointerAt2(event) {
|
|
5698
|
+
return event.timeStamp > 0 ? event.timeStamp : performance.now();
|
|
5699
|
+
}
|
|
5622
5700
|
function resolveSpeed3(value, fallback) {
|
|
5623
5701
|
return Number.isFinite(value) && value >= 0 ? value : fallback;
|
|
5624
5702
|
}
|
|
@@ -5687,7 +5765,7 @@ function TouchControls({
|
|
|
5687
5765
|
});
|
|
5688
5766
|
element.setPointerCapture?.(event.pointerId);
|
|
5689
5767
|
syncActive();
|
|
5690
|
-
drag.start({ x: event.clientX, y: event.clientY });
|
|
5768
|
+
drag.start({ x: event.clientX, y: event.clientY }, pointerAt2(event));
|
|
5691
5769
|
if (pointersRef.current.size >= 2) {
|
|
5692
5770
|
drag.suspend();
|
|
5693
5771
|
const [first, second] = Array.from(pointersRef.current.values());
|
|
@@ -5734,15 +5812,16 @@ function TouchControls({
|
|
|
5734
5812
|
return;
|
|
5735
5813
|
}
|
|
5736
5814
|
const speed = resolveSpeed3(optionsRef.current.rotateSpeed, DEFAULT_ROTATE_SPEED3);
|
|
5737
|
-
drag.move(next, previous, speed, optionsRef.current.invert);
|
|
5815
|
+
drag.move(next, previous, speed, optionsRef.current.invert, pointerAt2(event));
|
|
5738
5816
|
};
|
|
5739
5817
|
const releasePointer = (event) => {
|
|
5740
5818
|
if (!pointersRef.current.has(event.pointerId)) {
|
|
5741
5819
|
return;
|
|
5742
5820
|
}
|
|
5743
|
-
|
|
5821
|
+
const pinch = pointersRef.current.size >= 2;
|
|
5822
|
+
if (event.type === "pointerup" && !pinch) drag.release();
|
|
5823
|
+
else drag.clear();
|
|
5744
5824
|
pointersRef.current.delete(event.pointerId);
|
|
5745
|
-
drag.clear();
|
|
5746
5825
|
if (element.hasPointerCapture?.(event.pointerId)) {
|
|
5747
5826
|
element.releasePointerCapture?.(event.pointerId);
|
|
5748
5827
|
}
|
|
@@ -5751,7 +5830,7 @@ function TouchControls({
|
|
|
5751
5830
|
}
|
|
5752
5831
|
syncActive(event.type !== "pointerup");
|
|
5753
5832
|
const remaining = pointersRef.current.values().next().value;
|
|
5754
|
-
if (remaining) drag.start(remaining);
|
|
5833
|
+
if (remaining) drag.start(remaining, pointerAt2(event));
|
|
5755
5834
|
};
|
|
5756
5835
|
element.addEventListener("pointerdown", onPointerDown);
|
|
5757
5836
|
element.addEventListener("pointermove", onPointerMove);
|