animejs 4.4.0 → 4.5.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.
- package/README.md +4 -5
- package/dist/bundles/anime.esm.js +491 -272
- package/dist/bundles/anime.esm.min.js +2 -2
- package/dist/bundles/anime.umd.js +491 -272
- package/dist/bundles/anime.umd.min.js +2 -2
- package/dist/modules/adapters/index.cjs +14 -0
- package/dist/modules/adapters/index.d.ts +1 -0
- package/dist/modules/adapters/index.js +8 -0
- package/dist/modules/adapters/registry.cjs +149 -0
- package/dist/modules/adapters/registry.d.ts +65 -0
- package/dist/modules/adapters/registry.js +146 -0
- package/dist/modules/adapters/three/adapter.cjs +26 -0
- package/dist/modules/adapters/three/adapter.d.ts +15 -0
- package/dist/modules/adapters/three/adapter.js +24 -0
- package/dist/modules/adapters/three/helpers.cjs +297 -0
- package/dist/modules/adapters/three/helpers.d.ts +89 -0
- package/dist/modules/adapters/three/helpers.js +280 -0
- package/dist/modules/adapters/three/index.cjs +20 -0
- package/dist/modules/adapters/three/index.d.ts +2 -0
- package/dist/modules/adapters/three/index.js +12 -0
- package/dist/modules/adapters/three/instance.cjs +368 -0
- package/dist/modules/adapters/three/instance.d.ts +133 -0
- package/dist/modules/adapters/three/instance.js +365 -0
- package/dist/modules/adapters/three/object3d.cjs +214 -0
- package/dist/modules/adapters/three/object3d.d.ts +1 -0
- package/dist/modules/adapters/three/object3d.js +212 -0
- package/dist/modules/adapters/three/resolvers.cjs +105 -0
- package/dist/modules/adapters/three/resolvers.d.ts +1 -0
- package/dist/modules/adapters/three/resolvers.js +103 -0
- package/dist/modules/adapters/three/uniform.cjs +41 -0
- package/dist/modules/adapters/three/uniform.d.ts +1 -0
- package/dist/modules/adapters/three/uniform.js +39 -0
- package/dist/modules/animatable/animatable.cjs +2 -1
- package/dist/modules/animatable/animatable.d.ts +2 -1
- package/dist/modules/animatable/animatable.js +2 -1
- package/dist/modules/animatable/index.cjs +1 -1
- package/dist/modules/animatable/index.js +1 -1
- package/dist/modules/animation/additive.cjs +1 -1
- package/dist/modules/animation/additive.js +1 -1
- package/dist/modules/animation/animation.cjs +43 -16
- package/dist/modules/animation/animation.d.ts +5 -0
- package/dist/modules/animation/animation.js +45 -18
- package/dist/modules/animation/composition.cjs +38 -35
- package/dist/modules/animation/composition.js +38 -35
- package/dist/modules/animation/index.cjs +1 -1
- package/dist/modules/animation/index.js +1 -1
- package/dist/modules/core/clock.cjs +11 -15
- package/dist/modules/core/clock.d.ts +0 -2
- package/dist/modules/core/clock.js +11 -15
- package/dist/modules/core/colors.cjs +1 -1
- package/dist/modules/core/colors.js +1 -1
- package/dist/modules/core/consts.cjs +15 -1
- package/dist/modules/core/consts.d.ts +2 -0
- package/dist/modules/core/consts.js +14 -2
- package/dist/modules/core/globals.cjs +7 -4
- package/dist/modules/core/globals.d.ts +8 -2
- package/dist/modules/core/globals.js +8 -5
- package/dist/modules/core/helpers.cjs +2 -2
- package/dist/modules/core/helpers.js +3 -3
- package/dist/modules/core/render.cjs +93 -73
- package/dist/modules/core/render.js +96 -76
- package/dist/modules/core/styles.cjs +16 -2
- package/dist/modules/core/styles.js +16 -2
- package/dist/modules/core/targets.cjs +11 -13
- package/dist/modules/core/targets.js +11 -13
- package/dist/modules/core/transforms.cjs +1 -1
- package/dist/modules/core/transforms.js +1 -1
- package/dist/modules/core/units.cjs +1 -1
- package/dist/modules/core/units.js +1 -1
- package/dist/modules/core/values.cjs +73 -82
- package/dist/modules/core/values.d.ts +1 -2
- package/dist/modules/core/values.js +76 -84
- package/dist/modules/draggable/draggable.cjs +1 -1
- package/dist/modules/draggable/draggable.js +1 -1
- package/dist/modules/draggable/index.cjs +1 -1
- package/dist/modules/draggable/index.js +1 -1
- package/dist/modules/easings/cubic-bezier/index.cjs +1 -1
- package/dist/modules/easings/cubic-bezier/index.js +1 -1
- package/dist/modules/easings/eases/index.cjs +1 -1
- package/dist/modules/easings/eases/index.js +1 -1
- package/dist/modules/easings/eases/parser.cjs +3 -3
- package/dist/modules/easings/eases/parser.d.ts +4 -5
- package/dist/modules/easings/eases/parser.js +3 -3
- package/dist/modules/easings/index.cjs +1 -1
- package/dist/modules/easings/index.js +1 -1
- package/dist/modules/easings/irregular/index.cjs +1 -1
- package/dist/modules/easings/irregular/index.js +1 -1
- package/dist/modules/easings/linear/index.cjs +1 -1
- package/dist/modules/easings/linear/index.js +1 -1
- package/dist/modules/easings/none.cjs +1 -1
- package/dist/modules/easings/none.js +1 -1
- package/dist/modules/easings/spring/index.cjs +1 -1
- package/dist/modules/easings/spring/index.js +1 -1
- package/dist/modules/easings/steps/index.cjs +1 -1
- package/dist/modules/easings/steps/index.js +1 -1
- package/dist/modules/engine/engine.cjs +4 -2
- package/dist/modules/engine/engine.js +4 -2
- package/dist/modules/engine/index.cjs +1 -1
- package/dist/modules/engine/index.js +1 -1
- package/dist/modules/events/index.cjs +1 -1
- package/dist/modules/events/index.js +1 -1
- package/dist/modules/events/scroll.cjs +3 -1
- package/dist/modules/events/scroll.js +3 -1
- package/dist/modules/index.cjs +1 -1
- package/dist/modules/index.js +1 -1
- package/dist/modules/layout/index.cjs +1 -1
- package/dist/modules/layout/index.js +1 -1
- package/dist/modules/layout/layout.cjs +1 -1
- package/dist/modules/layout/layout.js +1 -1
- package/dist/modules/scope/index.cjs +1 -1
- package/dist/modules/scope/index.js +1 -1
- package/dist/modules/scope/scope.cjs +1 -1
- package/dist/modules/scope/scope.js +1 -1
- package/dist/modules/svg/drawable.cjs +1 -1
- package/dist/modules/svg/drawable.js +1 -1
- package/dist/modules/svg/helpers.cjs +1 -1
- package/dist/modules/svg/helpers.js +1 -1
- package/dist/modules/svg/index.cjs +1 -1
- package/dist/modules/svg/index.js +1 -1
- package/dist/modules/svg/morphto.cjs +1 -1
- package/dist/modules/svg/morphto.js +1 -1
- package/dist/modules/svg/motionpath.cjs +1 -1
- package/dist/modules/svg/motionpath.js +1 -1
- package/dist/modules/text/index.cjs +1 -1
- package/dist/modules/text/index.js +1 -1
- package/dist/modules/text/scramble.cjs +12 -2
- package/dist/modules/text/scramble.d.ts +9 -1
- package/dist/modules/text/scramble.js +12 -2
- package/dist/modules/text/split.cjs +2 -1
- package/dist/modules/text/split.js +2 -1
- package/dist/modules/timeline/index.cjs +1 -1
- package/dist/modules/timeline/index.js +1 -1
- package/dist/modules/timeline/position.cjs +1 -1
- package/dist/modules/timeline/position.js +1 -1
- package/dist/modules/timeline/timeline.cjs +14 -5
- package/dist/modules/timeline/timeline.d.ts +3 -3
- package/dist/modules/timeline/timeline.js +14 -5
- package/dist/modules/timer/index.cjs +1 -1
- package/dist/modules/timer/index.js +1 -1
- package/dist/modules/timer/timer.cjs +1 -1
- package/dist/modules/timer/timer.js +1 -1
- package/dist/modules/types/index.d.ts +36 -11
- package/dist/modules/utils/chainable.cjs +1 -1
- package/dist/modules/utils/chainable.js +1 -1
- package/dist/modules/utils/index.cjs +1 -1
- package/dist/modules/utils/index.js +1 -1
- package/dist/modules/utils/number.cjs +1 -1
- package/dist/modules/utils/number.js +1 -1
- package/dist/modules/utils/random.cjs +4 -3
- package/dist/modules/utils/random.d.ts +1 -1
- package/dist/modules/utils/random.js +4 -3
- package/dist/modules/utils/stagger.cjs +67 -13
- package/dist/modules/utils/stagger.js +69 -15
- package/dist/modules/utils/target.cjs +4 -1
- package/dist/modules/utils/target.js +4 -1
- package/dist/modules/utils/time.cjs +6 -5
- package/dist/modules/utils/time.d.ts +1 -1
- package/dist/modules/utils/time.js +6 -5
- package/dist/modules/waapi/composition.cjs +1 -1
- package/dist/modules/waapi/composition.js +1 -1
- package/dist/modules/waapi/index.cjs +1 -1
- package/dist/modules/waapi/index.js +1 -1
- package/dist/modules/waapi/waapi.cjs +1 -1
- package/dist/modules/waapi/waapi.js +1 -1
- package/package.json +38 -5
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Anime.js - adapters - CJS
|
|
3
|
+
* @version v4.5.0
|
|
4
|
+
* @license MIT
|
|
5
|
+
* @copyright 2026 - Julian Garnier
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
'use strict';
|
|
9
|
+
|
|
10
|
+
var three = require('three');
|
|
11
|
+
var number = require('../../utils/number.cjs');
|
|
12
|
+
var adapter = require('./adapter.cjs');
|
|
13
|
+
var helpers = require('./helpers.cjs');
|
|
14
|
+
|
|
15
|
+
const hasSkewOrigin = (t) => !!(t._skewX || t._skewY || t._skewZ || t._originX || t._originY || t._originZ);
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @import { Object3D, InstancedMesh } from 'three'
|
|
19
|
+
*
|
|
20
|
+
* @typedef {InstancedMesh | BatchedMesh} InstanceParent
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
const DIRTY_POS = 1;
|
|
24
|
+
const DIRTY_ROT = 2;
|
|
25
|
+
const DIRTY_SCALE = 4;
|
|
26
|
+
const DIRTY_SKEW = 8;
|
|
27
|
+
|
|
28
|
+
/** @type {WeakMap<InstanceParent, InstanceBinding>} */
|
|
29
|
+
const bindings = new WeakMap();
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Per-mesh state for `InstancedMesh` / `BatchedMesh` animations. Holds the instance array, the dirty queue, and the chained `onBeforeRender` closure.
|
|
33
|
+
*/
|
|
34
|
+
class InstanceBinding {
|
|
35
|
+
|
|
36
|
+
/** @param {InstanceParent} mesh */
|
|
37
|
+
constructor(mesh) {
|
|
38
|
+
this.mesh = mesh;
|
|
39
|
+
this.hasInstanceMatrix = 'instanceMatrix' in mesh;
|
|
40
|
+
/** @type {(Instance | null)[]} */
|
|
41
|
+
this.instances = [];
|
|
42
|
+
/** @type {Instance[]} */
|
|
43
|
+
this.dirtyList = [];
|
|
44
|
+
/** @type {Object3D['onBeforeRender'] | null} */
|
|
45
|
+
this.userOnBeforeRender = mesh.onBeforeRender || null;
|
|
46
|
+
this.chainedHandler = makeChainedHandler(this);
|
|
47
|
+
Object.defineProperty(mesh, 'onBeforeRender', {
|
|
48
|
+
configurable: true,
|
|
49
|
+
get: () => this.chainedHandler,
|
|
50
|
+
set: (fn) => { this.userOnBeforeRender = fn; },
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
flush() {
|
|
55
|
+
const list = this.dirtyList;
|
|
56
|
+
if (list.length === 0) return;
|
|
57
|
+
for (let i = 0, l = list.length; i < l; i++) list[i]._flush();
|
|
58
|
+
if (this.hasInstanceMatrix) /** @type {InstancedMesh} */(this.mesh).instanceMatrix.needsUpdate = true;
|
|
59
|
+
list.length = 0;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* @param {InstanceBinding} binding
|
|
66
|
+
* @return {Object3D['onBeforeRender']}
|
|
67
|
+
*/
|
|
68
|
+
function makeChainedHandler(binding) {
|
|
69
|
+
return function (renderer, scene, camera, geometry, material, group) {
|
|
70
|
+
binding.flush();
|
|
71
|
+
const u = binding.userOnBeforeRender;
|
|
72
|
+
if (u) u.call(binding.mesh, renderer, scene, camera, geometry, material, group);
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Per-instance adapter for `InstancedMesh` or `BatchedMesh`. Returned by `getInstances(mesh)`. Exposes the same flat properties as the mesh adapter, applied to a single instance id. Writes are coalesced and flushed before each render via `onBeforeRender`; call `commitChanges(mesh)` if you need to read `mesh.instanceMatrix` between a tick and a render.
|
|
78
|
+
*
|
|
79
|
+
* Caveats:
|
|
80
|
+
* - `opacity` writes the parent's shared material, every instance is affected.
|
|
81
|
+
* - `visible` is backed by `BatchedMesh.setVisibleAt`. On `InstancedMesh` it is a no-op, use `scale = 0` to hide an instance.
|
|
82
|
+
*/
|
|
83
|
+
class Instance {
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* @param {InstanceBinding} binding
|
|
87
|
+
* @param {number} id
|
|
88
|
+
*/
|
|
89
|
+
constructor(binding, id) {
|
|
90
|
+
this.isAnimejsInstanceProxy = true;
|
|
91
|
+
this.parent = binding.mesh;
|
|
92
|
+
this.id = id;
|
|
93
|
+
this._position = new three.Vector3();
|
|
94
|
+
this._rotation = new three.Euler(0, 0, 0, 'XYZ');
|
|
95
|
+
this._scale = new three.Vector3(1, 1, 1);
|
|
96
|
+
this._matrix = new three.Matrix4();
|
|
97
|
+
this._quat = new three.Quaternion();
|
|
98
|
+
// Pre-allocate _color so the hidden class stays stable, set color mutates it in place rather than re-binding the field.
|
|
99
|
+
this._color = new three.Color();
|
|
100
|
+
this._dirty = 0;
|
|
101
|
+
// Skew in degrees and transform-origin in object-space.
|
|
102
|
+
// applySkewOrigin computes Math.tan inline per non-zero axis, so we only carry the user-facing angle here.
|
|
103
|
+
this._skewX = 0;
|
|
104
|
+
this._skewY = 0;
|
|
105
|
+
this._skewZ = 0;
|
|
106
|
+
this._originX = 0;
|
|
107
|
+
this._originY = 0;
|
|
108
|
+
this._originZ = 0;
|
|
109
|
+
// Skip the position-only fast path in _flush whenever any skew or origin is non-zero, since both modify the matrix beyond pure translation.
|
|
110
|
+
this._hasSkewOrigin = false;
|
|
111
|
+
// Cache the binding dirty queue once so per-frame setters skip a property hop.
|
|
112
|
+
/** @type {Instance[]} */
|
|
113
|
+
this._dirtyList = binding.dirtyList;
|
|
114
|
+
// Cache parent capability flags once so per-frame setters skip prototype-chain in checks.
|
|
115
|
+
const parent = binding.mesh;
|
|
116
|
+
this._hasSetColor = 'setColorAt' in parent;
|
|
117
|
+
this._hasSetVisible = 'setVisibleAt' in parent;
|
|
118
|
+
this._hasGetVisible = 'getVisibleAt' in parent;
|
|
119
|
+
|
|
120
|
+
parent.getMatrixAt(id, this._matrix);
|
|
121
|
+
if (this._matrix.elements[15] === 0) this._matrix.identity();
|
|
122
|
+
this._matrix.decompose(this._position, this._quat, this._scale);
|
|
123
|
+
this._rotation.setFromQuaternion(this._quat, 'XYZ');
|
|
124
|
+
|
|
125
|
+
if ('getColorAt' in parent && 'instanceColor' in parent && parent.instanceColor) {
|
|
126
|
+
parent.getColorAt(id, this._color);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* @param {number} flag
|
|
132
|
+
*/
|
|
133
|
+
_markDirty(flag) {
|
|
134
|
+
// Enqueue once per frame, later flags only OR into _dirty without re-pushing to the queue.
|
|
135
|
+
if (this._dirty === 0) this._dirtyList.push(this);
|
|
136
|
+
this._dirty |= flag;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
_flush() {
|
|
140
|
+
const d = this._dirty;
|
|
141
|
+
if (!d) return;
|
|
142
|
+
const m = this._matrix;
|
|
143
|
+
const p = this._position;
|
|
144
|
+
if (d === DIRTY_POS && !this._hasSkewOrigin) {
|
|
145
|
+
const e = m.elements;
|
|
146
|
+
e[12] = p.x; e[13] = p.y; e[14] = p.z;
|
|
147
|
+
} else {
|
|
148
|
+
const q = this._quat;
|
|
149
|
+
if (d & DIRTY_ROT) q.setFromEuler(this._rotation);
|
|
150
|
+
m.compose(p, q, this._scale);
|
|
151
|
+
if (this._hasSkewOrigin) {
|
|
152
|
+
helpers.applySkewOrigin(m.elements, this._skewX, this._skewY, this._skewZ, this._originX, this._originY, this._originZ);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
this.parent.setMatrixAt(this.id, m);
|
|
156
|
+
this._dirty = 0;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
get x() { return this._position.x; }
|
|
160
|
+
set x(v) { this._position.x = v; this._markDirty(DIRTY_POS); }
|
|
161
|
+
|
|
162
|
+
get y() { return this._position.y; }
|
|
163
|
+
set y(v) { this._position.y = v; this._markDirty(DIRTY_POS); }
|
|
164
|
+
|
|
165
|
+
get z() { return this._position.z; }
|
|
166
|
+
set z(v) { this._position.z = v; this._markDirty(DIRTY_POS); }
|
|
167
|
+
|
|
168
|
+
get rotateX() { return number.radToDeg(this._rotation.x); }
|
|
169
|
+
set rotateX(v) { this._rotation.x = number.degToRad(v); this._markDirty(DIRTY_ROT); }
|
|
170
|
+
|
|
171
|
+
get rotateY() { return number.radToDeg(this._rotation.y); }
|
|
172
|
+
set rotateY(v) { this._rotation.y = number.degToRad(v); this._markDirty(DIRTY_ROT); }
|
|
173
|
+
|
|
174
|
+
get rotateZ() { return number.radToDeg(this._rotation.z); }
|
|
175
|
+
set rotateZ(v) { this._rotation.z = number.degToRad(v); this._markDirty(DIRTY_ROT); }
|
|
176
|
+
|
|
177
|
+
get scaleX() { return this._scale.x; }
|
|
178
|
+
set scaleX(v) { this._scale.x = v; this._markDirty(DIRTY_SCALE); }
|
|
179
|
+
|
|
180
|
+
get scaleY() { return this._scale.y; }
|
|
181
|
+
set scaleY(v) { this._scale.y = v; this._markDirty(DIRTY_SCALE); }
|
|
182
|
+
|
|
183
|
+
get scaleZ() { return this._scale.z; }
|
|
184
|
+
set scaleZ(v) { this._scale.z = v; this._markDirty(DIRTY_SCALE); }
|
|
185
|
+
|
|
186
|
+
get scale() { return this._scale.x; }
|
|
187
|
+
set scale(v) {
|
|
188
|
+
const s = this._scale;
|
|
189
|
+
s.x = v; s.y = v; s.z = v;
|
|
190
|
+
this._markDirty(DIRTY_SCALE);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
get skewX() { return this._skewX; }
|
|
194
|
+
set skewX(v) {
|
|
195
|
+
this._skewX = v;
|
|
196
|
+
this._hasSkewOrigin = hasSkewOrigin(this);
|
|
197
|
+
this._markDirty(DIRTY_SKEW);
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
get skewY() { return this._skewY; }
|
|
201
|
+
set skewY(v) {
|
|
202
|
+
this._skewY = v;
|
|
203
|
+
this._hasSkewOrigin = hasSkewOrigin(this);
|
|
204
|
+
this._markDirty(DIRTY_SKEW);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
get skewZ() { return this._skewZ; }
|
|
208
|
+
set skewZ(v) {
|
|
209
|
+
this._skewZ = v;
|
|
210
|
+
this._hasSkewOrigin = hasSkewOrigin(this);
|
|
211
|
+
this._markDirty(DIRTY_SKEW);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
get transformOriginX() { return this._originX; }
|
|
215
|
+
set transformOriginX(v) {
|
|
216
|
+
this._originX = v;
|
|
217
|
+
this._hasSkewOrigin = hasSkewOrigin(this);
|
|
218
|
+
this._markDirty(DIRTY_SKEW);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
get transformOriginY() { return this._originY; }
|
|
222
|
+
set transformOriginY(v) {
|
|
223
|
+
this._originY = v;
|
|
224
|
+
this._hasSkewOrigin = hasSkewOrigin(this);
|
|
225
|
+
this._markDirty(DIRTY_SKEW);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
get transformOriginZ() { return this._originZ; }
|
|
229
|
+
set transformOriginZ(v) {
|
|
230
|
+
this._originZ = v;
|
|
231
|
+
this._hasSkewOrigin = hasSkewOrigin(this);
|
|
232
|
+
this._markDirty(DIRTY_SKEW);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
get opacity() {
|
|
236
|
+
return helpers.readScalar(/** @type {any} */(this.parent).material, 'opacity', helpers.PATH_DIRECT, 1);
|
|
237
|
+
}
|
|
238
|
+
/** @param {number} v */
|
|
239
|
+
set opacity(v) {
|
|
240
|
+
helpers.writeScalar(/** @type {any} */(this.parent).material, 'opacity', v, helpers.PATH_DIRECT);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
get visible() {
|
|
244
|
+
return this._hasGetVisible ? /** @type {any} */(this.parent).getVisibleAt(this.id) : true;
|
|
245
|
+
}
|
|
246
|
+
/** @param {boolean} v */
|
|
247
|
+
set visible(v) {
|
|
248
|
+
if (this._hasSetVisible) /** @type {any} */(this.parent).setVisibleAt(this.id, v);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Flushes pending matrix writes for every dirty instance of `mesh`.
|
|
255
|
+
* Called automatically before each render. Call it yourself if you read
|
|
256
|
+
* `mesh.instanceMatrix` between an animation tick and the next render.
|
|
257
|
+
*
|
|
258
|
+
* @param {InstanceParent} mesh
|
|
259
|
+
*/
|
|
260
|
+
function commitChanges(mesh) {
|
|
261
|
+
const binding = bindings.get(mesh);
|
|
262
|
+
if (binding) binding.flush();
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Returns an array of per-instance adapters for `mesh`. Index by id, deleted slots on `BatchedMesh` are `null`. Pass the array (or a slice / a single element) to `animate()`.
|
|
267
|
+
*
|
|
268
|
+
* animate(getInstances(mesh), { x: 100, delay: stagger(5) });
|
|
269
|
+
* animate(getInstances(mesh)[42], { scale: 2 });
|
|
270
|
+
*
|
|
271
|
+
* The same array reference is preserved across `mesh.count` / `addInstance` / `deleteInstance` calls. Entries are pushed, nulled, or truncated in place. Animations bound to an outdated reference keep tweening their original adapters.
|
|
272
|
+
*
|
|
273
|
+
* `mesh.onBeforeRender` is replaced with an accessor that flushes
|
|
274
|
+
* pending instance writes before each render and forwards to your
|
|
275
|
+
* handler. Assigning your own `mesh.onBeforeRender = fn` keeps the
|
|
276
|
+
* auto-flush, but reading `mesh.onBeforeRender` afterwards returns the
|
|
277
|
+
* chained dispatcher rather than `fn` itself, so identity checks
|
|
278
|
+
* (`mesh.onBeforeRender === fn`) will not match.
|
|
279
|
+
*
|
|
280
|
+
* @param {InstanceParent} mesh
|
|
281
|
+
* @return {(Instance | null)[]}
|
|
282
|
+
*/
|
|
283
|
+
function getInstances(mesh) {
|
|
284
|
+
let binding = bindings.get(mesh);
|
|
285
|
+
if (!binding) {
|
|
286
|
+
binding = new InstanceBinding(mesh);
|
|
287
|
+
bindings.set(mesh, binding);
|
|
288
|
+
}
|
|
289
|
+
if (mesh instanceof three.BatchedMesh) {
|
|
290
|
+
return refreshBatched(binding);
|
|
291
|
+
}
|
|
292
|
+
return refreshInstanced(binding);
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/**
|
|
296
|
+
* @param {InstanceBinding} binding
|
|
297
|
+
* @return {(Instance | null)[]}
|
|
298
|
+
*/
|
|
299
|
+
function refreshInstanced(binding) {
|
|
300
|
+
const mesh = /** @type {InstancedMesh} */(binding.mesh);
|
|
301
|
+
const count = mesh.count;
|
|
302
|
+
const arr = binding.instances;
|
|
303
|
+
if (arr.length === 0 && count > 0) {
|
|
304
|
+
arr.length = count;
|
|
305
|
+
for (let i = 0; i < count; i++) arr[i] = new Instance(binding, i);
|
|
306
|
+
return arr;
|
|
307
|
+
}
|
|
308
|
+
if (arr.length < count) {
|
|
309
|
+
for (let i = arr.length; i < count; i++) arr.push(new Instance(binding, i));
|
|
310
|
+
} else if (arr.length > count) {
|
|
311
|
+
arr.length = count;
|
|
312
|
+
}
|
|
313
|
+
return arr;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* @param {InstanceBinding} binding
|
|
318
|
+
* @return {(Instance | null)[]}
|
|
319
|
+
*/
|
|
320
|
+
function refreshBatched(binding) {
|
|
321
|
+
const mesh = /** @type {BatchedMesh} */(binding.mesh);
|
|
322
|
+
const arr = binding.instances;
|
|
323
|
+
// Read three internal _instanceInfo to skip slots marked inactive by deleteInstance.
|
|
324
|
+
// Iterate the full slot count, not instanceCount, since deleted slots leave gaps but live ids past them must still be visited.
|
|
325
|
+
const instanceInfo = /** @type {{ _instanceInfo?: { active: boolean }[] }} */(mesh)._instanceInfo ?? [];
|
|
326
|
+
const len = instanceInfo.length;
|
|
327
|
+
if (arr.length < len) arr.length = len;
|
|
328
|
+
for (let i = 0; i < len; i++) {
|
|
329
|
+
const info = instanceInfo[i];
|
|
330
|
+
const inactive = info && info.active === false;
|
|
331
|
+
if (inactive) {
|
|
332
|
+
arr[i] = null;
|
|
333
|
+
} else if (!arr[i]) {
|
|
334
|
+
arr[i] = new Instance(binding, i);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
if (arr.length > len) arr.length = len;
|
|
338
|
+
return arr;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
const instanceAdapter = adapter.threeAdapter.registerTargetAdapter((t) => t instanceof Instance);
|
|
342
|
+
instanceAdapter.registerProperty('color',
|
|
343
|
+
(t) => helpers.readColorHex(t._color),
|
|
344
|
+
(t, _, tw) => {
|
|
345
|
+
if (!t._hasSetColor) return;
|
|
346
|
+
const ns = tw._numbers;
|
|
347
|
+
t._color.setRGB(ns[0] * helpers.COLOR_NORM, ns[1] * helpers.COLOR_NORM, ns[2] * helpers.COLOR_NORM, three.SRGBColorSpace);
|
|
348
|
+
const p = /** @type {any} */(t.parent);
|
|
349
|
+
p.setColorAt(t.id, t._color);
|
|
350
|
+
if (p.instanceColor) p.instanceColor.needsUpdate = true;
|
|
351
|
+
},
|
|
352
|
+
);
|
|
353
|
+
// Shorthand 3-token string x y z routed via the engine COMPLEX path.
|
|
354
|
+
// The setter reads tween _numbers for the per-frame lerped triplet.
|
|
355
|
+
instanceAdapter.registerProperty('transformOrigin',
|
|
356
|
+
(t) => `${t._originX} ${t._originY} ${t._originZ}`,
|
|
357
|
+
(t, _, tw) => {
|
|
358
|
+
const ns = tw._numbers;
|
|
359
|
+
t._originX = ns[0];
|
|
360
|
+
t._originY = ns[1];
|
|
361
|
+
t._originZ = ns[2];
|
|
362
|
+
t._hasSkewOrigin = hasSkewOrigin(t);
|
|
363
|
+
t._markDirty(DIRTY_SKEW);
|
|
364
|
+
},
|
|
365
|
+
);
|
|
366
|
+
|
|
367
|
+
exports.commitChanges = commitChanges;
|
|
368
|
+
exports.getInstances = getInstances;
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Flushes pending matrix writes for every dirty instance of `mesh`.
|
|
3
|
+
* Called automatically before each render. Call it yourself if you read
|
|
4
|
+
* `mesh.instanceMatrix` between an animation tick and the next render.
|
|
5
|
+
*
|
|
6
|
+
* @param {InstanceParent} mesh
|
|
7
|
+
*/
|
|
8
|
+
export function commitChanges(mesh: InstanceParent): void;
|
|
9
|
+
/**
|
|
10
|
+
* Returns an array of per-instance adapters for `mesh`. Index by id, deleted slots on `BatchedMesh` are `null`. Pass the array (or a slice / a single element) to `animate()`.
|
|
11
|
+
*
|
|
12
|
+
* animate(getInstances(mesh), { x: 100, delay: stagger(5) });
|
|
13
|
+
* animate(getInstances(mesh)[42], { scale: 2 });
|
|
14
|
+
*
|
|
15
|
+
* The same array reference is preserved across `mesh.count` / `addInstance` / `deleteInstance` calls. Entries are pushed, nulled, or truncated in place. Animations bound to an outdated reference keep tweening their original adapters.
|
|
16
|
+
*
|
|
17
|
+
* `mesh.onBeforeRender` is replaced with an accessor that flushes
|
|
18
|
+
* pending instance writes before each render and forwards to your
|
|
19
|
+
* handler. Assigning your own `mesh.onBeforeRender = fn` keeps the
|
|
20
|
+
* auto-flush, but reading `mesh.onBeforeRender` afterwards returns the
|
|
21
|
+
* chained dispatcher rather than `fn` itself, so identity checks
|
|
22
|
+
* (`mesh.onBeforeRender === fn`) will not match.
|
|
23
|
+
*
|
|
24
|
+
* @param {InstanceParent} mesh
|
|
25
|
+
* @return {(Instance | null)[]}
|
|
26
|
+
*/
|
|
27
|
+
export function getInstances(mesh: InstanceParent): (Instance | null)[];
|
|
28
|
+
export type InstanceParent = InstancedMesh | BatchedMesh;
|
|
29
|
+
/**
|
|
30
|
+
* Per-instance adapter for `InstancedMesh` or `BatchedMesh`. Returned by `getInstances(mesh)`. Exposes the same flat properties as the mesh adapter, applied to a single instance id. Writes are coalesced and flushed before each render via `onBeforeRender`; call `commitChanges(mesh)` if you need to read `mesh.instanceMatrix` between a tick and a render.
|
|
31
|
+
*
|
|
32
|
+
* Caveats:
|
|
33
|
+
* - `opacity` writes the parent's shared material, every instance is affected.
|
|
34
|
+
* - `visible` is backed by `BatchedMesh.setVisibleAt`. On `InstancedMesh` it is a no-op, use `scale = 0` to hide an instance.
|
|
35
|
+
*/
|
|
36
|
+
declare class Instance {
|
|
37
|
+
/**
|
|
38
|
+
* @param {InstanceBinding} binding
|
|
39
|
+
* @param {number} id
|
|
40
|
+
*/
|
|
41
|
+
constructor(binding: InstanceBinding, id: number);
|
|
42
|
+
isAnimejsInstanceProxy: boolean;
|
|
43
|
+
parent: InstanceParent;
|
|
44
|
+
id: number;
|
|
45
|
+
_position: Vector3;
|
|
46
|
+
_rotation: Euler;
|
|
47
|
+
_scale: Vector3;
|
|
48
|
+
_matrix: Matrix4;
|
|
49
|
+
_quat: Quaternion;
|
|
50
|
+
_color: Color;
|
|
51
|
+
_dirty: number;
|
|
52
|
+
_skewX: number;
|
|
53
|
+
_skewY: number;
|
|
54
|
+
_skewZ: number;
|
|
55
|
+
_originX: number;
|
|
56
|
+
_originY: number;
|
|
57
|
+
_originZ: number;
|
|
58
|
+
_hasSkewOrigin: boolean;
|
|
59
|
+
/** @type {Instance[]} */
|
|
60
|
+
_dirtyList: Instance[];
|
|
61
|
+
_hasSetColor: boolean;
|
|
62
|
+
_hasSetVisible: boolean;
|
|
63
|
+
_hasGetVisible: boolean;
|
|
64
|
+
/**
|
|
65
|
+
* @param {number} flag
|
|
66
|
+
*/
|
|
67
|
+
_markDirty(flag: number): void;
|
|
68
|
+
_flush(): void;
|
|
69
|
+
set x(v: number);
|
|
70
|
+
get x(): number;
|
|
71
|
+
set y(v: number);
|
|
72
|
+
get y(): number;
|
|
73
|
+
set z(v: number);
|
|
74
|
+
get z(): number;
|
|
75
|
+
set rotateX(v: number);
|
|
76
|
+
get rotateX(): number;
|
|
77
|
+
set rotateY(v: number);
|
|
78
|
+
get rotateY(): number;
|
|
79
|
+
set rotateZ(v: number);
|
|
80
|
+
get rotateZ(): number;
|
|
81
|
+
set scaleX(v: number);
|
|
82
|
+
get scaleX(): number;
|
|
83
|
+
set scaleY(v: number);
|
|
84
|
+
get scaleY(): number;
|
|
85
|
+
set scaleZ(v: number);
|
|
86
|
+
get scaleZ(): number;
|
|
87
|
+
set scale(v: number);
|
|
88
|
+
get scale(): number;
|
|
89
|
+
set skewX(v: number);
|
|
90
|
+
get skewX(): number;
|
|
91
|
+
set skewY(v: number);
|
|
92
|
+
get skewY(): number;
|
|
93
|
+
set skewZ(v: number);
|
|
94
|
+
get skewZ(): number;
|
|
95
|
+
set transformOriginX(v: number);
|
|
96
|
+
get transformOriginX(): number;
|
|
97
|
+
set transformOriginY(v: number);
|
|
98
|
+
get transformOriginY(): number;
|
|
99
|
+
set transformOriginZ(v: number);
|
|
100
|
+
get transformOriginZ(): number;
|
|
101
|
+
/** @param {number} v */
|
|
102
|
+
set opacity(v: number);
|
|
103
|
+
get opacity(): number;
|
|
104
|
+
/** @param {boolean} v */
|
|
105
|
+
set visible(v: boolean);
|
|
106
|
+
get visible(): boolean;
|
|
107
|
+
}
|
|
108
|
+
import type { InstancedMesh } from 'three';
|
|
109
|
+
import { BatchedMesh } from 'three';
|
|
110
|
+
import { Vector3 } from 'three';
|
|
111
|
+
import { Euler } from 'three';
|
|
112
|
+
import { Matrix4 } from 'three';
|
|
113
|
+
import { Quaternion } from 'three';
|
|
114
|
+
import { Color } from 'three';
|
|
115
|
+
/**
|
|
116
|
+
* Per-mesh state for `InstancedMesh` / `BatchedMesh` animations. Holds the instance array, the dirty queue, and the chained `onBeforeRender` closure.
|
|
117
|
+
*/
|
|
118
|
+
declare class InstanceBinding {
|
|
119
|
+
/** @param {InstanceParent} mesh */
|
|
120
|
+
constructor(mesh: InstanceParent);
|
|
121
|
+
mesh: InstanceParent;
|
|
122
|
+
hasInstanceMatrix: boolean;
|
|
123
|
+
/** @type {(Instance | null)[]} */
|
|
124
|
+
instances: (Instance | null)[];
|
|
125
|
+
/** @type {Instance[]} */
|
|
126
|
+
dirtyList: Instance[];
|
|
127
|
+
/** @type {Object3D['onBeforeRender'] | null} */
|
|
128
|
+
userOnBeforeRender: Object3D["onBeforeRender"] | null;
|
|
129
|
+
chainedHandler: (renderer: import("three").WebGLRenderer, scene: import("three").Scene, camera: import("three").Camera, geometry: import("three").BufferGeometry, material: import("three").Material, group: import("three").Group) => void;
|
|
130
|
+
flush(): void;
|
|
131
|
+
}
|
|
132
|
+
import type { Object3D } from 'three';
|
|
133
|
+
export {};
|