@displayxr/inline3d 1.2.0 → 1.2.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/CHANGELOG.md +19 -0
- package/js/inline3d-viewer.js +50 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,25 @@ entry points (`.`, `./three`) are frozen for 1.x, while the **scene subpaths** (
|
|
|
5
5
|
`./splat`, `./model`) are a preview tier whose options may change in any release. Entries below say
|
|
6
6
|
which tier they touch, because that is what tells you whether an upgrade can move your pixels.
|
|
7
7
|
|
|
8
|
+
## 1.2.1 — 2026-08-25
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- **`./viewer` wheel zoom is proportional and eased.** It scaled by the delta's SIGN only — a flat
|
|
13
|
+
8% step per wheel event — which is about right for one mouse notch and badly wrong for a
|
|
14
|
+
trackpad, where a single two-finger flick emits dozens of small events. Measured: a 20-event
|
|
15
|
+
flick reached **5.3x** and a longer swipe hit the 6x clamp, on gestures the user reads as gentle.
|
|
16
|
+
|
|
17
|
+
The handler now scales by magnitude, normalises `deltaMode` (Chrome reports pixels; Firefox
|
|
18
|
+
reports LINES for a mouse wheel, so identical hardware was ~2x more sensitive in one browser),
|
|
19
|
+
clamps per event against OS pointer-acceleration spikes, and applies the zoom as `exp()` so equal
|
|
20
|
+
deltas give equal ratios in both directions — `1 + d` and `1 - d` are not inverses, and the
|
|
21
|
+
asymmetry was felt as zooming out being weaker than zooming in. Zoom then eases toward its target
|
|
22
|
+
on the same damping curve yaw and pitch already used, so a notch glides instead of stepping.
|
|
23
|
+
|
|
24
|
+
Same gestures after: trackpad flick **1.13x**, mouse 3 notches **1.35x**, and Chrome and Firefox
|
|
25
|
+
now agree per notch. *(preview tier — no API change)*
|
|
26
|
+
|
|
8
27
|
## 1.2.0 — 2026-08-20
|
|
9
28
|
|
|
10
29
|
### Added
|
package/js/inline3d-viewer.js
CHANGED
|
@@ -219,6 +219,7 @@ export class SceneViewer {
|
|
|
219
219
|
|
|
220
220
|
this._fitScale = 1;
|
|
221
221
|
this._zoom = 1;
|
|
222
|
+
this._targetZoom = 1;
|
|
222
223
|
this._yaw = 0;
|
|
223
224
|
this._pitch = 0;
|
|
224
225
|
this._targetYaw = 0;
|
|
@@ -346,7 +347,7 @@ export class SceneViewer {
|
|
|
346
347
|
if (pitch !== undefined) {
|
|
347
348
|
this._targetPitch = this._pitch = clamp(pitch, this.pitchLimit[0], this.pitchLimit[1]);
|
|
348
349
|
}
|
|
349
|
-
if (zoom !== undefined) this._zoom = clamp(zoom,
|
|
350
|
+
if (zoom !== undefined) this._targetZoom = this._zoom = clamp(zoom, ZOOM_MIN, ZOOM_MAX);
|
|
350
351
|
this._applyTransform();
|
|
351
352
|
}
|
|
352
353
|
|
|
@@ -682,6 +683,14 @@ export class SceneViewer {
|
|
|
682
683
|
const k = dt > 0 ? 1 - Math.pow(0.001, dt) : 1;
|
|
683
684
|
this._yaw += (this._targetYaw - this._yaw) * k;
|
|
684
685
|
this._pitch += (this._targetPitch - this._pitch) * k;
|
|
686
|
+
// Zoom eases on the same curve. Multiplicatively, because zoom is a ratio: approaching 2x
|
|
687
|
+
// linearly spends most of its time near the start and then lurches, while a ratio approach
|
|
688
|
+
// covers equal PERCEPTUAL steps per frame.
|
|
689
|
+
if (Math.abs(this._targetZoom - this._zoom) > 1e-4) {
|
|
690
|
+
this._zoom *= Math.pow(this._targetZoom / this._zoom, k);
|
|
691
|
+
} else {
|
|
692
|
+
this._zoom = this._targetZoom;
|
|
693
|
+
}
|
|
685
694
|
this._applyTransform();
|
|
686
695
|
}
|
|
687
696
|
|
|
@@ -725,9 +734,29 @@ export class SceneViewer {
|
|
|
725
734
|
};
|
|
726
735
|
this._onWheel = (ev) => {
|
|
727
736
|
ev.preventDefault();
|
|
728
|
-
|
|
737
|
+
// Scale by the delta's MAGNITUDE, not just its sign. The previous version applied a fixed
|
|
738
|
+
// 8% step per event, which is roughly right for one mouse notch and badly wrong for a
|
|
739
|
+
// trackpad: a two-finger flick emits dozens of small events, so an 8% step compounded per
|
|
740
|
+
// event sent the subject to the clamp on a gesture the user read as gentle.
|
|
741
|
+
//
|
|
742
|
+
// deltaMode has to be normalised first or the same code means different things per browser:
|
|
743
|
+
// Chrome reports pixels, Firefox reports LINES for a mouse wheel (deltaY 3, not 100), and
|
|
744
|
+
// a page-mode device would otherwise be ~200x more sensitive than a trackpad.
|
|
745
|
+
let px = ev.deltaY;
|
|
746
|
+
if (ev.deltaMode === 1) px *= WHEEL_LINE_PX;
|
|
747
|
+
else if (ev.deltaMode === 2) px *= WHEEL_PAGE_PX;
|
|
748
|
+
// OS pointer acceleration can spike a single event past 500px. Clamping per event keeps one
|
|
749
|
+
// hard flick from teleporting the subject while leaving the gesture's total travel intact,
|
|
750
|
+
// since the events keep coming.
|
|
751
|
+
px = clamp(px, -WHEEL_MAX_PX, WHEEL_MAX_PX);
|
|
752
|
+
|
|
753
|
+
// exp() rather than a multiply-add: zoom is a ratio, so equal deltas should give equal
|
|
754
|
+
// ratios in both directions. `1 + d` and `1 - d` are not inverses, and the asymmetry is
|
|
755
|
+
// felt as zooming out being weaker than zooming in.
|
|
756
|
+
this._targetZoom = clamp(this._targetZoom * Math.exp(-px * ZOOM_PER_PX), ZOOM_MIN, ZOOM_MAX);
|
|
729
757
|
this._lastInput = now();
|
|
730
|
-
|
|
758
|
+
// No _applyTransform() here: _tick() eases toward the target and applies it, which is what
|
|
759
|
+
// makes a wheel notch glide instead of step.
|
|
731
760
|
};
|
|
732
761
|
|
|
733
762
|
el.style.touchAction = 'none'; // or the browser eats the drag as a scroll
|
|
@@ -749,6 +778,24 @@ export class SceneViewer {
|
|
|
749
778
|
}
|
|
750
779
|
}
|
|
751
780
|
|
|
781
|
+
/**
|
|
782
|
+
* Wheel-zoom tuning.
|
|
783
|
+
*
|
|
784
|
+
* ZOOM_PER_PX is set so one ordinary mouse notch (~100 px in Chrome) is about a 10% step, which
|
|
785
|
+
* puts a trackpad's 1-10 px events at a fraction of a percent each — small enough that the easing
|
|
786
|
+
* reads as continuous rather than as a stack of jumps.
|
|
787
|
+
*/
|
|
788
|
+
// A deltaMode-1 "line" is sized to match a wheel DETENT, not a line of text. Firefox reports a
|
|
789
|
+
// notch as deltaY 3 in lines where Chrome reports it as ~100 in pixels, so 33 makes one physical
|
|
790
|
+
// notch feel the same in both; 16 (a text line) would make Firefox roughly half as responsive as
|
|
791
|
+
// Chrome for identical hardware.
|
|
792
|
+
const WHEEL_LINE_PX = 33;
|
|
793
|
+
const WHEEL_PAGE_PX = 400; // a "page" in deltaMode 2; rare, but it must not be unbounded
|
|
794
|
+
const WHEEL_MAX_PX = 120; // per-event ceiling, against OS pointer acceleration spikes
|
|
795
|
+
const ZOOM_PER_PX = 0.001;
|
|
796
|
+
const ZOOM_MIN = 0.2;
|
|
797
|
+
const ZOOM_MAX = 6;
|
|
798
|
+
|
|
752
799
|
function now() {
|
|
753
800
|
return typeof performance !== 'undefined' ? performance.now() : Date.now();
|
|
754
801
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@displayxr/inline3d",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"description": "Turn any HTML <canvas> into a glasses-free-3D window on a DisplayXR display, inside an ordinary web page. Dependency-free; progressive enhancement (falls back to plain 2D everywhere else).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"types": "./index.d.ts",
|