3d-spinner 0.9.1 → 0.9.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 +30 -7
- package/dist/cjs/animations/object-motion.cjs +1368 -0
- package/dist/cjs/animations/spin.cjs +1299 -0
- package/dist/cjs/engines/little-3d-engine/little-3d-engine.cjs +1324 -0
- package/dist/cjs/engines/little-3d-engine/loaders/obj.cjs +58 -0
- package/dist/cjs/engines/little-tween-engine/little-tween-engine.cjs +279 -0
- package/dist/cjs/index.cjs +120 -0
- package/dist/cjs/motion/motion.cjs +140 -0
- package/dist/cjs/motion/transitions.cjs +80 -0
- package/dist/engines/little-3d-engine/loaders/obj.d.ts +2 -2
- package/dist/engines/little-3d-engine/loaders/obj.js +2 -2
- package/dist/umd/spinner.global.js +2408 -0
- package/dist/umd/spinner.global.min.js +58 -0
- package/package.json +26 -11
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/engines/little-3d-engine/loaders/obj.ts
|
|
21
|
+
var obj_exports = {};
|
|
22
|
+
__export(obj_exports, {
|
|
23
|
+
parseObj: () => parseObj
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(obj_exports);
|
|
26
|
+
var DEFAULT_COLORS = ["#3b82f6", "#8b5cf6", "#ec4899", "#f59e0b", "#10b981", "#ef4444"];
|
|
27
|
+
function resolveIndex(token, vertexCount) {
|
|
28
|
+
const n = parseInt(token, 10);
|
|
29
|
+
return n < 0 ? vertexCount + n : n - 1;
|
|
30
|
+
}
|
|
31
|
+
function parseObj(text, options = {}) {
|
|
32
|
+
const colors = options.colors ?? DEFAULT_COLORS;
|
|
33
|
+
const vertices = [];
|
|
34
|
+
const faces = [];
|
|
35
|
+
for (const line of text.split("\n")) {
|
|
36
|
+
const trimmed = line.trim();
|
|
37
|
+
if (trimmed === "" || trimmed.startsWith("#")) continue;
|
|
38
|
+
const parts = trimmed.split(/\s+/);
|
|
39
|
+
const keyword = parts[0];
|
|
40
|
+
if (keyword === "v") {
|
|
41
|
+
vertices.push({
|
|
42
|
+
x: parseFloat(parts[1]),
|
|
43
|
+
y: parseFloat(parts[2]),
|
|
44
|
+
z: parseFloat(parts[3])
|
|
45
|
+
});
|
|
46
|
+
} else if (keyword === "f") {
|
|
47
|
+
const indices = [];
|
|
48
|
+
for (let i = 1; i < parts.length; i++) {
|
|
49
|
+
const vertexToken = parts[i].split("/")[0];
|
|
50
|
+
indices.push(resolveIndex(vertexToken, vertices.length));
|
|
51
|
+
}
|
|
52
|
+
if (indices.length >= 3) {
|
|
53
|
+
faces.push({ indices, color: colors[faces.length % colors.length] });
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return { vertices, faces };
|
|
58
|
+
}
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/engines/little-tween-engine/little-tween-engine.ts
|
|
21
|
+
var little_tween_engine_exports = {};
|
|
22
|
+
__export(little_tween_engine_exports, {
|
|
23
|
+
LittleTweenEngine: () => LittleTweenEngine,
|
|
24
|
+
cubic: () => cubic,
|
|
25
|
+
ease: () => ease,
|
|
26
|
+
easeInBack: () => easeInBack,
|
|
27
|
+
easeInBounce: () => easeInBounce,
|
|
28
|
+
easeInCirc: () => easeInCirc,
|
|
29
|
+
easeInCubic: () => easeInCubic,
|
|
30
|
+
easeInElastic: () => easeInElastic,
|
|
31
|
+
easeInExpo: () => easeInExpo,
|
|
32
|
+
easeInOutBack: () => easeInOutBack,
|
|
33
|
+
easeInOutBounce: () => easeInOutBounce,
|
|
34
|
+
easeInOutCirc: () => easeInOutCirc,
|
|
35
|
+
easeInOutCubic: () => easeInOutCubic,
|
|
36
|
+
easeInOutElastic: () => easeInOutElastic,
|
|
37
|
+
easeInOutExpo: () => easeInOutExpo,
|
|
38
|
+
easeInOutQuad: () => easeInOutQuad,
|
|
39
|
+
easeInOutQuart: () => easeInOutQuart,
|
|
40
|
+
easeInOutQuint: () => easeInOutQuint,
|
|
41
|
+
easeInOutSine: () => easeInOutSine,
|
|
42
|
+
easeInQuad: () => easeInQuad,
|
|
43
|
+
easeInQuart: () => easeInQuart,
|
|
44
|
+
easeInQuint: () => easeInQuint,
|
|
45
|
+
easeInSine: () => easeInSine,
|
|
46
|
+
easeOutBack: () => easeOutBack,
|
|
47
|
+
easeOutBounce: () => easeOutBounce,
|
|
48
|
+
easeOutCirc: () => easeOutCirc,
|
|
49
|
+
easeOutCubic: () => easeOutCubic,
|
|
50
|
+
easeOutElastic: () => easeOutElastic,
|
|
51
|
+
easeOutExpo: () => easeOutExpo,
|
|
52
|
+
easeOutQuad: () => easeOutQuad,
|
|
53
|
+
easeOutQuart: () => easeOutQuart,
|
|
54
|
+
easeOutQuint: () => easeOutQuint,
|
|
55
|
+
easeOutSine: () => easeOutSine,
|
|
56
|
+
easeTypes: () => easeTypes,
|
|
57
|
+
linear: () => linear,
|
|
58
|
+
quadratic: () => quadratic,
|
|
59
|
+
quartic: () => quartic,
|
|
60
|
+
quintic: () => quintic
|
|
61
|
+
});
|
|
62
|
+
module.exports = __toCommonJS(little_tween_engine_exports);
|
|
63
|
+
|
|
64
|
+
// src/engines/little-tween-engine/core/tweens.ts
|
|
65
|
+
function input(value, overextend) {
|
|
66
|
+
if (Number.isNaN(value)) return 0;
|
|
67
|
+
if (overextend) return value;
|
|
68
|
+
return Math.min(1, Math.max(0, value));
|
|
69
|
+
}
|
|
70
|
+
function linear(value, overextend = false) {
|
|
71
|
+
return input(value, overextend);
|
|
72
|
+
}
|
|
73
|
+
function quadratic(value, overextend = false) {
|
|
74
|
+
return easeInQuad(value, overextend);
|
|
75
|
+
}
|
|
76
|
+
function cubic(value, overextend = false) {
|
|
77
|
+
return easeInCubic(value, overextend);
|
|
78
|
+
}
|
|
79
|
+
function quartic(value, overextend = false) {
|
|
80
|
+
return easeInQuart(value, overextend);
|
|
81
|
+
}
|
|
82
|
+
function quintic(value, overextend = false) {
|
|
83
|
+
return easeInQuint(value, overextend);
|
|
84
|
+
}
|
|
85
|
+
function easeInSine(value, overextend = false) {
|
|
86
|
+
const x = input(value, overextend);
|
|
87
|
+
return 1 - Math.cos(x * Math.PI / 2);
|
|
88
|
+
}
|
|
89
|
+
function easeOutSine(value, overextend = false) {
|
|
90
|
+
const x = input(value, overextend);
|
|
91
|
+
return Math.sin(x * Math.PI / 2);
|
|
92
|
+
}
|
|
93
|
+
function easeInOutSine(value, overextend = false) {
|
|
94
|
+
const x = input(value, overextend);
|
|
95
|
+
return -(Math.cos(Math.PI * x) - 1) / 2;
|
|
96
|
+
}
|
|
97
|
+
function easeInQuad(value, overextend = false) {
|
|
98
|
+
const x = input(value, overextend);
|
|
99
|
+
return x * x;
|
|
100
|
+
}
|
|
101
|
+
function easeOutQuad(value, overextend = false) {
|
|
102
|
+
const x = input(value, overextend);
|
|
103
|
+
return 1 - (1 - x) * (1 - x);
|
|
104
|
+
}
|
|
105
|
+
function easeInOutQuad(value, overextend = false) {
|
|
106
|
+
const x = input(value, overextend);
|
|
107
|
+
return x < 0.5 ? 2 * x * x : 1 - Math.pow(-2 * x + 2, 2) / 2;
|
|
108
|
+
}
|
|
109
|
+
function easeInCubic(value, overextend = false) {
|
|
110
|
+
const x = input(value, overextend);
|
|
111
|
+
return x * x * x;
|
|
112
|
+
}
|
|
113
|
+
function easeOutCubic(value, overextend = false) {
|
|
114
|
+
const x = input(value, overextend);
|
|
115
|
+
return 1 - Math.pow(1 - x, 3);
|
|
116
|
+
}
|
|
117
|
+
function easeInOutCubic(value, overextend = false) {
|
|
118
|
+
const x = input(value, overextend);
|
|
119
|
+
return x < 0.5 ? 4 * x * x * x : 1 - Math.pow(-2 * x + 2, 3) / 2;
|
|
120
|
+
}
|
|
121
|
+
function easeInQuart(value, overextend = false) {
|
|
122
|
+
const x = input(value, overextend);
|
|
123
|
+
return x * x * x * x;
|
|
124
|
+
}
|
|
125
|
+
function easeOutQuart(value, overextend = false) {
|
|
126
|
+
const x = input(value, overextend);
|
|
127
|
+
return 1 - Math.pow(1 - x, 4);
|
|
128
|
+
}
|
|
129
|
+
function easeInOutQuart(value, overextend = false) {
|
|
130
|
+
const x = input(value, overextend);
|
|
131
|
+
return x < 0.5 ? 8 * x * x * x * x : 1 - Math.pow(-2 * x + 2, 4) / 2;
|
|
132
|
+
}
|
|
133
|
+
function easeInQuint(value, overextend = false) {
|
|
134
|
+
const x = input(value, overextend);
|
|
135
|
+
return x * x * x * x * x;
|
|
136
|
+
}
|
|
137
|
+
function easeOutQuint(value, overextend = false) {
|
|
138
|
+
const x = input(value, overextend);
|
|
139
|
+
return 1 - Math.pow(1 - x, 5);
|
|
140
|
+
}
|
|
141
|
+
function easeInOutQuint(value, overextend = false) {
|
|
142
|
+
const x = input(value, overextend);
|
|
143
|
+
return x < 0.5 ? 16 * x * x * x * x * x : 1 - Math.pow(-2 * x + 2, 5) / 2;
|
|
144
|
+
}
|
|
145
|
+
function easeInExpo(value, overextend = false) {
|
|
146
|
+
const x = input(value, overextend);
|
|
147
|
+
return x === 0 ? 0 : Math.pow(2, 10 * x - 10);
|
|
148
|
+
}
|
|
149
|
+
function easeOutExpo(value, overextend = false) {
|
|
150
|
+
const x = input(value, overextend);
|
|
151
|
+
return x === 1 ? 1 : 1 - Math.pow(2, -10 * x);
|
|
152
|
+
}
|
|
153
|
+
function easeInOutExpo(value, overextend = false) {
|
|
154
|
+
const x = input(value, overextend);
|
|
155
|
+
return x === 0 ? 0 : x === 1 ? 1 : x < 0.5 ? Math.pow(2, 20 * x - 10) / 2 : (2 - Math.pow(2, -20 * x + 10)) / 2;
|
|
156
|
+
}
|
|
157
|
+
function easeInCirc(value, overextend = false) {
|
|
158
|
+
const x = input(value, overextend);
|
|
159
|
+
return 1 - Math.sqrt(1 - Math.pow(x, 2));
|
|
160
|
+
}
|
|
161
|
+
function easeOutCirc(value, overextend = false) {
|
|
162
|
+
const x = input(value, overextend);
|
|
163
|
+
return Math.sqrt(1 - Math.pow(x - 1, 2));
|
|
164
|
+
}
|
|
165
|
+
function easeInOutCirc(value, overextend = false) {
|
|
166
|
+
const x = input(value, overextend);
|
|
167
|
+
return x < 0.5 ? (1 - Math.sqrt(1 - Math.pow(2 * x, 2))) / 2 : (Math.sqrt(1 - Math.pow(-2 * x + 2, 2)) + 1) / 2;
|
|
168
|
+
}
|
|
169
|
+
function easeInBack(value, overextend = false) {
|
|
170
|
+
const x = input(value, overextend);
|
|
171
|
+
const c1 = 1.70158;
|
|
172
|
+
const c3 = c1 + 1;
|
|
173
|
+
return c3 * x * x * x - c1 * x * x;
|
|
174
|
+
}
|
|
175
|
+
function easeOutBack(value, overextend = false) {
|
|
176
|
+
const x = input(value, overextend);
|
|
177
|
+
const c1 = 1.70158;
|
|
178
|
+
const c3 = c1 + 1;
|
|
179
|
+
return 1 + c3 * Math.pow(x - 1, 3) + c1 * Math.pow(x - 1, 2);
|
|
180
|
+
}
|
|
181
|
+
function easeInOutBack(value, overextend = false) {
|
|
182
|
+
const x = input(value, overextend);
|
|
183
|
+
const c1 = 1.70158;
|
|
184
|
+
const c2 = c1 * 1.525;
|
|
185
|
+
return x < 0.5 ? Math.pow(2 * x, 2) * ((c2 + 1) * 2 * x - c2) / 2 : (Math.pow(2 * x - 2, 2) * ((c2 + 1) * (x * 2 - 2) + c2) + 2) / 2;
|
|
186
|
+
}
|
|
187
|
+
function easeInElastic(value, overextend = false) {
|
|
188
|
+
const x = input(value, overextend);
|
|
189
|
+
const c4 = 2 * Math.PI / 3;
|
|
190
|
+
return x === 0 ? 0 : x === 1 ? 1 : -Math.pow(2, 10 * x - 10) * Math.sin((x * 10 - 10.75) * c4);
|
|
191
|
+
}
|
|
192
|
+
function easeOutElastic(value, overextend = false) {
|
|
193
|
+
const x = input(value, overextend);
|
|
194
|
+
const c4 = 2 * Math.PI / 3;
|
|
195
|
+
return x === 0 ? 0 : x === 1 ? 1 : Math.pow(2, -10 * x) * Math.sin((x * 10 - 0.75) * c4) + 1;
|
|
196
|
+
}
|
|
197
|
+
function easeInOutElastic(value, overextend = false) {
|
|
198
|
+
const x = input(value, overextend);
|
|
199
|
+
const c5 = 2 * Math.PI / 4.5;
|
|
200
|
+
return x === 0 ? 0 : x === 1 ? 1 : x < 0.5 ? -(Math.pow(2, 20 * x - 10) * Math.sin((20 * x - 11.125) * c5)) / 2 : Math.pow(2, -20 * x + 10) * Math.sin((20 * x - 11.125) * c5) / 2 + 1;
|
|
201
|
+
}
|
|
202
|
+
function easeInBounce(value, overextend = false) {
|
|
203
|
+
const x = input(value, overextend);
|
|
204
|
+
return 1 - easeOutBounce(1 - x, true);
|
|
205
|
+
}
|
|
206
|
+
function easeOutBounce(value, overextend = false) {
|
|
207
|
+
let x = input(value, overextend);
|
|
208
|
+
const n1 = 7.5625;
|
|
209
|
+
const d1 = 2.75;
|
|
210
|
+
if (x < 1 / d1) {
|
|
211
|
+
return n1 * x * x;
|
|
212
|
+
}
|
|
213
|
+
if (x < 2 / d1) {
|
|
214
|
+
x -= 1.5 / d1;
|
|
215
|
+
return n1 * x * x + 0.75;
|
|
216
|
+
}
|
|
217
|
+
if (x < 2.5 / d1) {
|
|
218
|
+
x -= 2.25 / d1;
|
|
219
|
+
return n1 * x * x + 0.9375;
|
|
220
|
+
}
|
|
221
|
+
x -= 2.625 / d1;
|
|
222
|
+
return n1 * x * x + 0.984375;
|
|
223
|
+
}
|
|
224
|
+
function easeInOutBounce(value, overextend = false) {
|
|
225
|
+
const x = input(value, overextend);
|
|
226
|
+
return x < 0.5 ? (1 - easeOutBounce(1 - 2 * x, true)) / 2 : (1 + easeOutBounce(2 * x - 1, true)) / 2;
|
|
227
|
+
}
|
|
228
|
+
var easeTypes = {
|
|
229
|
+
linear,
|
|
230
|
+
quadratic,
|
|
231
|
+
cubic,
|
|
232
|
+
quartic,
|
|
233
|
+
quintic,
|
|
234
|
+
easeInSine,
|
|
235
|
+
easeOutSine,
|
|
236
|
+
easeInOutSine,
|
|
237
|
+
easeInQuad,
|
|
238
|
+
easeOutQuad,
|
|
239
|
+
easeInOutQuad,
|
|
240
|
+
easeInCubic,
|
|
241
|
+
easeOutCubic,
|
|
242
|
+
easeInOutCubic,
|
|
243
|
+
easeInQuart,
|
|
244
|
+
easeOutQuart,
|
|
245
|
+
easeInOutQuart,
|
|
246
|
+
easeInQuint,
|
|
247
|
+
easeOutQuint,
|
|
248
|
+
easeInOutQuint,
|
|
249
|
+
easeInExpo,
|
|
250
|
+
easeOutExpo,
|
|
251
|
+
easeInOutExpo,
|
|
252
|
+
easeInCirc,
|
|
253
|
+
easeOutCirc,
|
|
254
|
+
easeInOutCirc,
|
|
255
|
+
easeInBack,
|
|
256
|
+
easeOutBack,
|
|
257
|
+
easeInOutBack,
|
|
258
|
+
easeInElastic,
|
|
259
|
+
easeOutElastic,
|
|
260
|
+
easeInOutElastic,
|
|
261
|
+
easeInBounce,
|
|
262
|
+
easeOutBounce,
|
|
263
|
+
easeInOutBounce
|
|
264
|
+
};
|
|
265
|
+
function ease(type, value, overextend = false) {
|
|
266
|
+
return easeTypes[type](value, overextend);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// src/engines/little-tween-engine/little-tween-engine.ts
|
|
270
|
+
var LittleTweenEngine = class {
|
|
271
|
+
constructor(options = {}) {
|
|
272
|
+
this.type = options.type ?? "linear";
|
|
273
|
+
this.overextend = options.overextend ?? false;
|
|
274
|
+
}
|
|
275
|
+
/** Map `value` through the selected ease type. */
|
|
276
|
+
value(value, type = this.type, overextend = this.overextend) {
|
|
277
|
+
return ease(type, value, overextend);
|
|
278
|
+
}
|
|
279
|
+
};
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
createSpinner: () => createSpinner
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(index_exports);
|
|
26
|
+
function clamp01(value) {
|
|
27
|
+
if (Number.isNaN(value)) return 0;
|
|
28
|
+
return Math.min(1, Math.max(0, value));
|
|
29
|
+
}
|
|
30
|
+
function lerp(from, to, t) {
|
|
31
|
+
return from + (to - from) * t;
|
|
32
|
+
}
|
|
33
|
+
function createSpinner(target, options) {
|
|
34
|
+
if (!(target instanceof HTMLElement)) {
|
|
35
|
+
throw new Error("3d-spinner: createSpinner requires a target HTMLElement.");
|
|
36
|
+
}
|
|
37
|
+
const { animation } = options;
|
|
38
|
+
const indeterminate = options.type === "indeterminate";
|
|
39
|
+
if (indeterminate && options.periodMs !== void 0 && (!Number.isFinite(options.periodMs) || options.periodMs <= 0)) {
|
|
40
|
+
throw new RangeError("3d-spinner: periodMs must be a finite number greater than zero.");
|
|
41
|
+
}
|
|
42
|
+
animation.mount(target);
|
|
43
|
+
const start = performance.now();
|
|
44
|
+
let rafId = 0;
|
|
45
|
+
let stopped = false;
|
|
46
|
+
let destroyed = false;
|
|
47
|
+
let entered = false;
|
|
48
|
+
let exiting = false;
|
|
49
|
+
let current = 0;
|
|
50
|
+
let targetProgress = 0;
|
|
51
|
+
let deadline = Infinity;
|
|
52
|
+
if (!indeterminate) {
|
|
53
|
+
const opts = options;
|
|
54
|
+
if (typeof opts.progress === "number") {
|
|
55
|
+
current = clamp01(opts.progress);
|
|
56
|
+
targetProgress = current;
|
|
57
|
+
}
|
|
58
|
+
if (typeof opts.timeout === "number") deadline = Math.min(deadline, start + opts.timeout);
|
|
59
|
+
if (opts.until instanceof Date) deadline = Math.min(deadline, opts.until.getTime());
|
|
60
|
+
}
|
|
61
|
+
function computeProgress(now) {
|
|
62
|
+
if (!indeterminate) {
|
|
63
|
+
if (now >= deadline) targetProgress = 1;
|
|
64
|
+
current = lerp(current, targetProgress, 0.12);
|
|
65
|
+
if (Math.abs(targetProgress - current) < 5e-4) current = targetProgress;
|
|
66
|
+
return current;
|
|
67
|
+
}
|
|
68
|
+
const opts = options;
|
|
69
|
+
const period = opts.periodMs ?? 2e3;
|
|
70
|
+
const t = (now - start) / period;
|
|
71
|
+
if ((opts.loop ?? "bounce") === "restart") return t - Math.floor(t);
|
|
72
|
+
const phase = t - 2 * Math.floor(t / 2);
|
|
73
|
+
return phase <= 1 ? phase : 2 - phase;
|
|
74
|
+
}
|
|
75
|
+
function frame(now) {
|
|
76
|
+
if (stopped) return;
|
|
77
|
+
const progress = computeProgress(now);
|
|
78
|
+
if (!entered && (indeterminate || progress > 0)) {
|
|
79
|
+
animation.enter(now);
|
|
80
|
+
entered = true;
|
|
81
|
+
}
|
|
82
|
+
if (!exiting && entered && !indeterminate && progress >= 1 && targetProgress >= 1) {
|
|
83
|
+
animation.exit(now);
|
|
84
|
+
exiting = true;
|
|
85
|
+
}
|
|
86
|
+
const target2 = indeterminate ? progress : targetProgress;
|
|
87
|
+
animation.render(now, { progress, targetProgress: target2, indeterminate });
|
|
88
|
+
if (exiting && animation.isFinished()) {
|
|
89
|
+
halt();
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
rafId = requestAnimationFrame(frame);
|
|
93
|
+
}
|
|
94
|
+
function halt() {
|
|
95
|
+
if (stopped) return;
|
|
96
|
+
stopped = true;
|
|
97
|
+
if (rafId) cancelAnimationFrame(rafId);
|
|
98
|
+
rafId = 0;
|
|
99
|
+
}
|
|
100
|
+
function setProgress(value) {
|
|
101
|
+
if (!indeterminate) targetProgress = clamp01(value);
|
|
102
|
+
}
|
|
103
|
+
function stop() {
|
|
104
|
+
if (stopped || exiting) return;
|
|
105
|
+
if (!entered) {
|
|
106
|
+
halt();
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
animation.exit(performance.now());
|
|
110
|
+
exiting = true;
|
|
111
|
+
}
|
|
112
|
+
function destroy() {
|
|
113
|
+
if (destroyed) return;
|
|
114
|
+
destroyed = true;
|
|
115
|
+
halt();
|
|
116
|
+
animation.destroy();
|
|
117
|
+
}
|
|
118
|
+
rafId = requestAnimationFrame(frame);
|
|
119
|
+
return { setProgress, stop, destroy };
|
|
120
|
+
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/motion/motion.ts
|
|
21
|
+
var motion_exports = {};
|
|
22
|
+
__export(motion_exports, {
|
|
23
|
+
circleMotion: () => circleMotion,
|
|
24
|
+
figureEightMotion: () => figureEightMotion,
|
|
25
|
+
squareMotion: () => squareMotion,
|
|
26
|
+
wanderMotion: () => wanderMotion
|
|
27
|
+
});
|
|
28
|
+
module.exports = __toCommonJS(motion_exports);
|
|
29
|
+
|
|
30
|
+
// src/motion/circle.ts
|
|
31
|
+
function circleMotion(options = {}) {
|
|
32
|
+
const radius = options.radius ?? 1.3;
|
|
33
|
+
const periodMs = options.periodMs ?? 3e3;
|
|
34
|
+
const tilt = options.tilt ?? 0.5;
|
|
35
|
+
const direction = options.direction ?? 1;
|
|
36
|
+
const cosTilt = Math.cos(tilt);
|
|
37
|
+
const sinTilt = Math.sin(tilt);
|
|
38
|
+
return {
|
|
39
|
+
positionAt(t) {
|
|
40
|
+
const angle = direction * t / periodMs * Math.PI * 2;
|
|
41
|
+
const x = radius * Math.cos(angle);
|
|
42
|
+
const flatY = radius * Math.sin(angle);
|
|
43
|
+
return { x, y: flatY * cosTilt, z: flatY * sinTilt };
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// src/motion/square.ts
|
|
49
|
+
function squareMotion(options = {}) {
|
|
50
|
+
const half = (options.size ?? 2.4) / 2;
|
|
51
|
+
const periodMs = options.periodMs ?? 4e3;
|
|
52
|
+
const tilt = options.tilt ?? 0.45;
|
|
53
|
+
const direction = options.direction ?? 1;
|
|
54
|
+
const cosTilt = Math.cos(tilt);
|
|
55
|
+
const sinTilt = Math.sin(tilt);
|
|
56
|
+
return {
|
|
57
|
+
positionAt(t) {
|
|
58
|
+
const lap = direction * t / periodMs;
|
|
59
|
+
const s = (lap - Math.floor(lap)) * 4;
|
|
60
|
+
const edge = Math.floor(s);
|
|
61
|
+
const f = s - edge;
|
|
62
|
+
let flatX;
|
|
63
|
+
let flatY;
|
|
64
|
+
if (edge === 0) {
|
|
65
|
+
flatX = -half + 2 * half * f;
|
|
66
|
+
flatY = -half;
|
|
67
|
+
} else if (edge === 1) {
|
|
68
|
+
flatX = half;
|
|
69
|
+
flatY = -half + 2 * half * f;
|
|
70
|
+
} else if (edge === 2) {
|
|
71
|
+
flatX = half - 2 * half * f;
|
|
72
|
+
flatY = half;
|
|
73
|
+
} else {
|
|
74
|
+
flatX = -half;
|
|
75
|
+
flatY = half - 2 * half * f;
|
|
76
|
+
}
|
|
77
|
+
return { x: flatX, y: flatY * cosTilt, z: flatY * sinTilt };
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// src/motion/figure-eight.ts
|
|
83
|
+
var LOOP_X = 1.5;
|
|
84
|
+
var LOOP_Y = 1;
|
|
85
|
+
var LOOP_Z = 1.05;
|
|
86
|
+
function figureEightMotion(options = {}) {
|
|
87
|
+
const size = options.size ?? 1;
|
|
88
|
+
const periodMs = options.periodMs ?? 3600;
|
|
89
|
+
return {
|
|
90
|
+
positionAt(t) {
|
|
91
|
+
const a = t / periodMs * Math.PI * 2;
|
|
92
|
+
return {
|
|
93
|
+
x: size * LOOP_X * Math.sin(a),
|
|
94
|
+
y: size * LOOP_Y * Math.sin(a) * Math.cos(a),
|
|
95
|
+
z: size * LOOP_Z * Math.cos(a)
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// src/motion/wander.ts
|
|
102
|
+
function mulberry32(seed) {
|
|
103
|
+
let a = seed >>> 0;
|
|
104
|
+
return () => {
|
|
105
|
+
a = a + 1831565813 | 0;
|
|
106
|
+
let t = Math.imul(a ^ a >>> 15, 1 | a);
|
|
107
|
+
t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
|
|
108
|
+
return ((t ^ t >>> 14) >>> 0) / 4294967296;
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
function axisDrift(rnd, omega, bound) {
|
|
112
|
+
const components = [0, 1, 2].map(() => ({
|
|
113
|
+
freq: 0.5 + rnd() * 1.4,
|
|
114
|
+
phase: rnd() * Math.PI * 2,
|
|
115
|
+
weight: 0.5 + rnd()
|
|
116
|
+
}));
|
|
117
|
+
const total = components.reduce((sum, c) => sum + c.weight, 0);
|
|
118
|
+
return (t) => {
|
|
119
|
+
let value = 0;
|
|
120
|
+
for (const c of components) value += c.weight * Math.sin(omega * c.freq * t + c.phase);
|
|
121
|
+
return value / total * bound;
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
function wanderMotion(options = {}) {
|
|
125
|
+
const boundX = options.bounds?.x ?? 1.4;
|
|
126
|
+
const boundY = options.bounds?.y ?? 1;
|
|
127
|
+
const boundZ = options.bounds?.z ?? 0.6;
|
|
128
|
+
const periodMs = options.periodMs ?? 9e3;
|
|
129
|
+
const seed = options.seed ?? Math.random() * 1e9 | 0;
|
|
130
|
+
const rnd = mulberry32(seed);
|
|
131
|
+
const omega = 2 * Math.PI / periodMs;
|
|
132
|
+
const driftX = axisDrift(rnd, omega, boundX);
|
|
133
|
+
const driftY = axisDrift(rnd, omega, boundY);
|
|
134
|
+
const driftZ = axisDrift(rnd, omega, boundZ);
|
|
135
|
+
return {
|
|
136
|
+
positionAt(t) {
|
|
137
|
+
return { x: driftX(t), y: driftY(t), z: driftZ(t) };
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/motion/transitions.ts
|
|
21
|
+
var transitions_exports = {};
|
|
22
|
+
__export(transitions_exports, {
|
|
23
|
+
enterFromObjectDirection: () => enterFromObjectDirection,
|
|
24
|
+
grow: () => grow,
|
|
25
|
+
leaveInObjectDirection: () => leaveInObjectDirection,
|
|
26
|
+
shrink: () => shrink
|
|
27
|
+
});
|
|
28
|
+
module.exports = __toCommonJS(transitions_exports);
|
|
29
|
+
var DEFAULT_DISTANCE = 3.5;
|
|
30
|
+
function add(a, b) {
|
|
31
|
+
return { x: a.x + b.x, y: a.y + b.y, z: a.z + b.z };
|
|
32
|
+
}
|
|
33
|
+
function scaleVector(v, factor) {
|
|
34
|
+
return { x: v.x * factor, y: v.y * factor, z: v.z * factor };
|
|
35
|
+
}
|
|
36
|
+
function vectorLength(v) {
|
|
37
|
+
return Math.hypot(v.x, v.y, v.z);
|
|
38
|
+
}
|
|
39
|
+
function normalizeVector(v) {
|
|
40
|
+
const length = vectorLength(v);
|
|
41
|
+
if (length < 1e-6) return { x: 1, y: 0, z: 0 };
|
|
42
|
+
return scaleVector(v, 1 / length);
|
|
43
|
+
}
|
|
44
|
+
function resolveDirection(input, fallback) {
|
|
45
|
+
return normalizeVector(fallback ?? input.direction ?? input.velocity ?? { x: 1, y: 0, z: 0 });
|
|
46
|
+
}
|
|
47
|
+
function easeOutBack(delta) {
|
|
48
|
+
const c = 1.70158;
|
|
49
|
+
const u = delta - 1;
|
|
50
|
+
return 1 + (c + 1) * u * u * u + c * u * u;
|
|
51
|
+
}
|
|
52
|
+
function joinVelocity(input, options, durationMs) {
|
|
53
|
+
const inputSpeed = input.velocity ? vectorLength(input.velocity) : 0;
|
|
54
|
+
if (input.velocity && inputSpeed > 1e-6 && !options.direction) {
|
|
55
|
+
return input.velocity;
|
|
56
|
+
}
|
|
57
|
+
const distance = options.distance ?? DEFAULT_DISTANCE;
|
|
58
|
+
return scaleVector(resolveDirection(input, options.direction), distance / durationMs);
|
|
59
|
+
}
|
|
60
|
+
function enterFromObjectDirection(options = {}) {
|
|
61
|
+
return (input) => {
|
|
62
|
+
const durationMs = Math.max(1, input.durationMs);
|
|
63
|
+
const velocity = joinVelocity(input, options, durationMs);
|
|
64
|
+
const remaining = durationMs - input.elapsedMs;
|
|
65
|
+
return { position: add(input.position, scaleVector(velocity, -remaining)) };
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function leaveInObjectDirection(options = {}) {
|
|
69
|
+
return (input) => {
|
|
70
|
+
const durationMs = Math.max(1, input.durationMs);
|
|
71
|
+
const velocity = joinVelocity(input, options, durationMs);
|
|
72
|
+
return { position: add(input.position, scaleVector(velocity, input.elapsedMs)) };
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
function grow() {
|
|
76
|
+
return (input) => ({ size: (input.size ?? 1) * easeOutBack(input.delta) });
|
|
77
|
+
}
|
|
78
|
+
function shrink() {
|
|
79
|
+
return (input) => ({ size: (input.size ?? 1) * (1 - input.delta * input.delta) });
|
|
80
|
+
}
|
|
@@ -15,8 +15,8 @@ export interface ObjOptions {
|
|
|
15
15
|
* `v`, `v/vt`, `v/vt/vn`, or `v//vn` form, with 1-based or negative indices).
|
|
16
16
|
* Normals (`vn`) and texture coordinates (`vt`) are ignored - the engine
|
|
17
17
|
* computes a flat normal per face - as are groups, materials, and other
|
|
18
|
-
* statements. Face winding is preserved
|
|
19
|
-
*
|
|
18
|
+
* statements. Face winding is preserved as-is; the engine expects CCW
|
|
19
|
+
* winding as seen from outside.
|
|
20
20
|
*
|
|
21
21
|
* @param text Contents of an `.obj` file.
|
|
22
22
|
* @param options Color palette to apply to the faces.
|
|
@@ -10,8 +10,8 @@ function resolveIndex(token, vertexCount) {
|
|
|
10
10
|
* `v`, `v/vt`, `v/vt/vn`, or `v//vn` form, with 1-based or negative indices).
|
|
11
11
|
* Normals (`vn`) and texture coordinates (`vt`) are ignored - the engine
|
|
12
12
|
* computes a flat normal per face - as are groups, materials, and other
|
|
13
|
-
* statements. Face winding is preserved
|
|
14
|
-
*
|
|
13
|
+
* statements. Face winding is preserved as-is; the engine expects CCW
|
|
14
|
+
* winding as seen from outside.
|
|
15
15
|
*
|
|
16
16
|
* @param text Contents of an `.obj` file.
|
|
17
17
|
* @param options Color palette to apply to the faces.
|