select-animation 1.5.0 → 1.6.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/package.json +1 -1
- package/select-animation.js +38 -848
package/package.json
CHANGED
package/select-animation.js
CHANGED
|
@@ -1,856 +1,46 @@
|
|
|
1
|
-
|
|
2
|
-
* Select-Animation: A High-Performance JavaScript Animation Engine
|
|
3
|
-
* Designed for fluid motion and organic UI transitions.
|
|
4
|
-
* Version: v1
|
|
5
|
-
* Author: Housseyn Cheriet
|
|
6
|
-
* Copyright: ©2026 Housseyn Cheriet
|
|
7
|
-
* License: MIT
|
|
8
|
-
* ------------------------------------------------------------------------- */
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
(function (global) {
|
|
12
|
-
"use strict";
|
|
13
|
-
|
|
14
|
-
// -----------------------------
|
|
15
|
-
// requestAnimationFrame polyfill
|
|
16
|
-
// Ensures consistent animation frame behavior across older browsers.
|
|
17
|
-
// -----------------------------
|
|
18
|
-
let _lastTime = 0;
|
|
19
|
-
const _vendors = ["ms", "moz", "webkit", "o"];
|
|
20
|
-
for (let i = 0; i < _vendors.length && !global.requestAnimationFrame; ++i) {
|
|
21
|
-
global.requestAnimationFrame = global[_vendors[i] + "RequestAnimationFrame"];
|
|
22
|
-
global.cancelAnimationFrame = global[_vendors[i] + "CancelAnimationFrame"] || global[_vendors[i] + "CancelRequestAnimationFrame"];
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
if (!global.requestAnimationFrame) {
|
|
26
|
-
global.requestAnimationFrame = function (callback) {
|
|
27
|
-
const currTime = new Date().getTime();
|
|
28
|
-
const timeToCall = Math.max(0, 16 - (currTime - _lastTime));
|
|
29
|
-
const id = global.setTimeout(function () {
|
|
30
|
-
callback(currTime + timeToCall);
|
|
31
|
-
}, timeToCall);
|
|
32
|
-
_lastTime = currTime + timeToCall;
|
|
33
|
-
return id;
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
if (!global.cancelAnimationFrame) {
|
|
38
|
-
global.cancelAnimationFrame = function (id) {
|
|
39
|
-
clearTimeout(id);
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// -----------------------------
|
|
44
|
-
// Internal defaults and mappings
|
|
45
|
-
// Color defaults and map from logical property -> CSS format.
|
|
46
|
-
// -----------------------------
|
|
47
|
-
const COLOR_DEFAULTS = { rgbR: 255, rgbG: 255, rgbB: 255, rgbA: 1 };
|
|
48
|
-
|
|
49
|
-
const COLOR_PROPERTIES = {
|
|
50
|
-
color: COLOR_DEFAULTS,
|
|
51
|
-
background: COLOR_DEFAULTS,
|
|
52
|
-
backgroundColor: COLOR_DEFAULTS,
|
|
53
|
-
borderColor: COLOR_DEFAULTS
|
|
54
|
-
};
|
|
55
|
-
|
|
56
|
-
const PROPERTY_FORMAT_MAP = {
|
|
57
|
-
zIndex: "*",
|
|
58
|
-
left: "*px",
|
|
59
|
-
top: "*px",
|
|
60
|
-
bottom: "*px",
|
|
61
|
-
right: "*px",
|
|
62
|
-
width: "*px",
|
|
63
|
-
height: "*px",
|
|
64
|
-
minWidth: "*px",
|
|
65
|
-
minHeight: "*px",
|
|
66
|
-
maxWidth: "*px",
|
|
67
|
-
maxHeight: "*px",
|
|
68
|
-
padding: "*px",
|
|
69
|
-
margin: "*px",
|
|
70
|
-
borderRadius: "*%",
|
|
71
|
-
borderWidth: "*px",
|
|
72
|
-
borderTopWidth: "*px",
|
|
73
|
-
borderRightWidth: "*px",
|
|
74
|
-
borderBottomWidth: "*px",
|
|
75
|
-
borderLeftWidth: "*px",
|
|
76
|
-
borderImageWidth: "*px",
|
|
77
|
-
strokeWidth: "*px",
|
|
78
|
-
strokeHeight: "*px",
|
|
79
|
-
strokeOpacity: "*",
|
|
80
|
-
opacity: "*",
|
|
81
|
-
translateX: "translateX(*px)",
|
|
82
|
-
translateY: "translateY(*px)",
|
|
83
|
-
translateZ: "translateZ(*px)",
|
|
84
|
-
rotateX: "rotateX(*deg)",
|
|
85
|
-
rotateY: "rotateY(*deg)",
|
|
86
|
-
rotateZ: "rotateZ(*deg)",
|
|
87
|
-
scale: "scale(*)",
|
|
88
|
-
scaleX: "scaleX(*)",
|
|
89
|
-
scaleY: "scaleY(*)",
|
|
90
|
-
skewX: "skewX(*deg)",
|
|
91
|
-
skewY: "skewY(*deg)",
|
|
92
|
-
rgbR: "rgba(*,",
|
|
93
|
-
rgbG: "*,",
|
|
94
|
-
rgbB: "*,",
|
|
95
|
-
rgba: "rgba(rgbR,rgbG,rgbB,rgbA)"
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
// -----------------------------
|
|
1
|
+
// -----------------------------
|
|
99
2
|
// select: simple DOM selector utility
|
|
100
3
|
// Returns flat array of matched elements given one or more selectors
|
|
101
4
|
// Usage: select('.class', '#id')
|
|
102
5
|
// -----------------------------
|
|
103
|
-
// --- Enhanced DOM Selection Utility with Explicit Error Reporting ---
|
|
104
|
-
const selectDom = function (
|
|
105
|
-
|
|
106
|
-
if (isElement(selector)) return [selector];
|
|
107
|
-
|
|
108
|
-
// 2. Handle string selectors (e.g., ".class", "#id")
|
|
109
|
-
if (typeof selector === "string") {
|
|
110
|
-
const nodes = document.querySelectorAll(selector);
|
|
111
|
-
if (nodes.length === 0) {
|
|
112
|
-
// Warning if the selector is valid string but matches nothing
|
|
113
|
-
console.warn(`Select-Animation: No elements found matching the selector "${selector}".`);
|
|
114
|
-
}
|
|
115
|
-
return Array.from(nodes);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// 3. Handle arrays or collections
|
|
119
|
-
if (Array.isArray(selector) || (selector && typeof selector.length === "number")) {
|
|
120
|
-
return Array.from(selector).filter(isElement);
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
// 4. CRITICAL: Handle invalid types (like numbers, null, undefined)
|
|
124
|
-
if (selector !== undefined && selector !== null) {
|
|
125
|
-
// Throwing a console error to stop the developer and force a fix
|
|
126
|
-
console.error(
|
|
127
|
-
`Select-Animation ERROR: Invalid input passed to selectDom().\n` +
|
|
128
|
-
`Expected: String (selector), HTMLElement, or Array.\n` +
|
|
129
|
-
`Received: ${typeof selector} (${selector})`
|
|
130
|
-
);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
return [];
|
|
134
|
-
};
|
|
135
|
-
|
|
136
|
-
// -----------------------------
|
|
137
|
-
// animate: animation factory
|
|
138
|
-
// Accepts animation definitions and returns a runner function to start animations on targets.
|
|
139
|
-
// -----------------------------
|
|
140
|
-
const animate = function () {
|
|
141
|
-
const definitions = arguments;
|
|
142
|
-
const defsCopy = copyObj(definitions);
|
|
143
|
-
|
|
144
|
-
return function () {
|
|
145
|
-
let tmp, i, propIndex, fromItem, toItem, valFrom, valTo, t;
|
|
146
|
-
let grouped = [];
|
|
147
|
-
let expectNextGroup = false;
|
|
148
|
-
let staging = { color: {}, transform: {}, from: {}, to: {} };
|
|
149
|
-
|
|
150
|
-
// Process the definitions to map elements to their animation settings
|
|
151
|
-
buildPlan();
|
|
152
|
-
|
|
153
|
-
function buildPlan() {
|
|
154
|
-
let secondPass = false;
|
|
155
|
-
|
|
156
|
-
for (let c = 0, total = definitions.length; c < total; c++) {
|
|
157
|
-
propIndex = 0;
|
|
158
|
-
// If current item is an element or an array of elements
|
|
159
|
-
if (expectNextGroup || Array.isArray(defsCopy[c]) || isElement(defsCopy[c])) {
|
|
160
|
-
if (secondPass) {
|
|
161
|
-
Array.isArray(defsCopy[c]) || (defsCopy[c] = [defsCopy[c]]);
|
|
162
|
-
Array.prototype.push.apply(grouped, defsCopy[c]);
|
|
163
|
-
}
|
|
164
|
-
expectNextGroup = false;
|
|
165
|
-
}
|
|
166
|
-
// --- Handle Configuration Object with Validation ---
|
|
167
|
-
else if (typeof defsCopy[c] === 'object' && defsCopy[c] !== null) {
|
|
168
|
-
if (secondPass) {
|
|
169
|
-
// Execute the animation runner for the current group
|
|
170
|
-
runner(grouped, definitions, defsCopy, c)();
|
|
171
|
-
} else {
|
|
172
|
-
expectNextGroup = false;
|
|
173
|
-
|
|
174
|
-
// 1. Validate Duration and Animation Type
|
|
175
|
-
defsCopy[c].duration = (typeof defsCopy[c].duration === 'number' && defsCopy[c].duration > 0) ? defsCopy[c].duration : 1000;
|
|
176
|
-
|
|
177
|
-
let requestedType = defsCopy[c].typeAnimation;
|
|
178
|
-
|
|
179
|
-
if (requestedType === "vibration" && defsCopy[c].vibrationStep === undefined) {
|
|
180
|
-
defsCopy[c].vibrationStep = 6;
|
|
181
|
-
} else if (requestedType) {
|
|
182
|
-
t = getNumber(requestedType);
|
|
183
|
-
if (t && t.length === 4) {
|
|
184
|
-
defsCopy[c].cubicbezier = t;
|
|
185
|
-
defsCopy[c].typeAnimation = "cubicbezier";
|
|
186
|
-
} else {
|
|
187
|
-
// STOP EXECUTION: If easing is not found, do not fall back to linear
|
|
188
|
-
if (requestedType !== "linear" && requestedType !== "vibration" && requestedType !== "cubicbezier" && (!Easing || !Easing[requestedType])) {
|
|
189
|
-
// Use Error instead of warn to make it impossible to ignore
|
|
190
|
-
throw new Error(`Select-Animation ERROR: The easing function "${requestedType}" does not exist. Please check your spelling or definitions.`);
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
// Double-check if the animation type is valid before processing
|
|
196
|
-
if (!defsCopy[c].typeAnimation) return;
|
|
197
|
-
|
|
198
|
-
// 2. Helper to sanitize input values (convert "100px" to 100)
|
|
199
|
-
const parseVal = (v) => {
|
|
200
|
-
if (typeof v === "number") return v;
|
|
201
|
-
let p = parseFloat(v);
|
|
202
|
-
return isNaN(p) ? 0 : p;
|
|
203
|
-
};
|
|
204
|
-
|
|
205
|
-
// Process properties and prepare "from" and "to" values
|
|
206
|
-
if (!defsCopy[c].callback &&
|
|
207
|
-
(Array.isArray(defsCopy[c].property) || (defsCopy[c].property !== undefined && (defsCopy[c].property = [defsCopy[c].property])))) {
|
|
208
|
-
|
|
209
|
-
defsCopy[c].property.forEach(function (propItem) {
|
|
210
|
-
const fromIsObject = typeof defsCopy[c].from === "object";
|
|
211
|
-
const toIsObject = typeof defsCopy[c].to === "object";
|
|
212
|
-
|
|
213
|
-
// Safely extract from/to values based on their types
|
|
214
|
-
if (!fromIsObject) valFrom = parseVal(defsCopy[c].from);
|
|
215
|
-
else fromItem = defsCopy[c]["from"][propIndex] || 0;
|
|
216
|
-
|
|
217
|
-
if (!toIsObject) valTo = parseVal(defsCopy[c].to);
|
|
218
|
-
else toItem = defsCopy[c]["to"][propIndex] || 0;
|
|
219
|
-
|
|
220
|
-
if (typeof propItem === "object") {
|
|
221
|
-
let propName = Object.keys(propItem)[0];
|
|
222
|
-
if (!Array.isArray(propItem[propName])) propItem[propName] = [propItem[propName]];
|
|
223
|
-
|
|
224
|
-
// Handle Colors and Transform objects
|
|
225
|
-
if ((propName.toLowerCase().indexOf("color") !== -1 && (staging.color[propName] = COLOR_PROPERTIES[propName])) ||
|
|
226
|
-
propName.toLowerCase().indexOf("transform") !== -1) {
|
|
227
|
-
|
|
228
|
-
let inner = 0;
|
|
229
|
-
staging["from"][propName] = {};
|
|
230
|
-
staging["to"][propName] = {};
|
|
231
|
-
|
|
232
|
-
propItem[propName].forEach(function (innerProp) {
|
|
233
|
-
if (propName.toLowerCase() === "transform") staging[propName][innerProp] = 0;
|
|
234
|
-
else staging.color[propName][innerProp] = 0;
|
|
235
|
-
|
|
236
|
-
// Validate and assign nested properties
|
|
237
|
-
if (fromIsObject) {
|
|
238
|
-
let raw = (fromItem[propName] !== undefined) ? (Array.isArray(fromItem[propName]) ? fromItem[propName][inner] : fromItem[propName][innerProp]) : valFrom;
|
|
239
|
-
staging["from"][propName][innerProp] = parseVal(raw);
|
|
240
|
-
} else {
|
|
241
|
-
staging["from"][propName][innerProp] = parseVal(defsCopy[c].from);
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
if (toIsObject) {
|
|
245
|
-
let raw = (toItem[propName] !== undefined) ? (Array.isArray(toItem[propName]) ? toItem[propName][inner] : toItem[propName][innerProp]) : valTo;
|
|
246
|
-
staging["to"][propName][innerProp] = parseVal(raw);
|
|
247
|
-
} else {
|
|
248
|
-
staging["to"][propName][innerProp] = parseVal(defsCopy[c].to);
|
|
249
|
-
}
|
|
250
|
-
inner++;
|
|
251
|
-
});
|
|
252
|
-
propIndex++;
|
|
253
|
-
}
|
|
254
|
-
} else {
|
|
255
|
-
// Handle simple numeric CSS properties (width, height, etc.)
|
|
256
|
-
if (fromIsObject) {
|
|
257
|
-
let raw = fromItem[propItem] !== undefined ? fromItem[propItem] : (fromItem !== undefined ? fromItem : valFrom);
|
|
258
|
-
staging["from"][propItem] = parseVal(raw);
|
|
259
|
-
} else {
|
|
260
|
-
staging["from"][propItem] = parseVal(defsCopy[c].from);
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
if (toIsObject) {
|
|
264
|
-
let raw = toItem[propItem] !== undefined ? toItem[propItem] : (toItem !== undefined ? toItem : valTo);
|
|
265
|
-
staging["to"][propItem] = parseVal(raw);
|
|
266
|
-
} else {
|
|
267
|
-
staging["to"][propItem] = parseVal(defsCopy[c].to);
|
|
268
|
-
}
|
|
269
|
-
propIndex++;
|
|
270
|
-
}
|
|
271
|
-
});
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
// 3. Callback Safety Validation
|
|
275
|
-
// Ensure hooks are actual functions to prevent execution errors
|
|
276
|
-
if (defsCopy[c].onStep && typeof defsCopy[c].onStep !== 'function') defsCopy[c].onStep = null;
|
|
277
|
-
if (defsCopy[c].onComplete && typeof defsCopy[c].onComplete !== 'function') defsCopy[c].onComplete = null;
|
|
278
|
-
|
|
279
|
-
// Finalize staging data and store it
|
|
280
|
-
defsCopy[c].storeValueAnim = copyObj(staging);
|
|
281
|
-
staging = { color: {}, transform: {}, from: {}, to: {} };
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
// Determine if the next item starts a new sequence group
|
|
285
|
-
if (definitions[c + 1] !== undefined && (Array.isArray(definitions[c + 1]) || isElement(definitions[c + 1]))) {
|
|
286
|
-
expectNextGroup = true;
|
|
287
|
-
grouped = [];
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
// Switch to second pass to execute the runners
|
|
292
|
-
if (c === total - 1 && !secondPass) {
|
|
293
|
-
expectNextGroup = false;
|
|
294
|
-
secondPass = true;
|
|
295
|
-
c = -1;
|
|
296
|
-
}
|
|
297
|
-
}
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
function runner(group, defs, defsCopyLocal, configIndex) {
|
|
301
|
-
const conf = defs[configIndex];
|
|
302
|
-
const declaredAnim = defsCopyLocal[configIndex].typeAnimation;
|
|
303
|
-
let alternateAnim = declaredAnim;
|
|
304
|
-
|
|
305
|
-
// Sanitize timing inputs
|
|
306
|
-
conf.timeline = !isNaN(Number(conf.timeline)) ? Number(conf.timeline) : 0;
|
|
307
|
-
conf.startafter = !isNaN(Number(conf.startafter)) ? Number(conf.startafter) : 0;
|
|
308
|
-
|
|
309
|
-
// Prepare looping and easing alternates
|
|
310
|
-
if (conf.boucle) {
|
|
311
|
-
conf.delay = !isNaN(Number(conf.delay)) ? Number(conf.delay) : undefined;
|
|
312
|
-
if (conf.boucleType === "returnRepeat" || conf.boucleType === "repeatReturn") {
|
|
313
|
-
alternateAnim = Easing[declaredAnim][1];
|
|
314
|
-
}
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
return function run(indexArg) {
|
|
318
|
-
let pausedAccum = 0;
|
|
319
|
-
let isPaused = false;
|
|
320
|
-
let pauseStart;
|
|
321
|
-
|
|
322
|
-
// Initialize event-based pause/resume logic if configured
|
|
323
|
-
if (conf.pause && Array.isArray(conf.pause)) {
|
|
324
|
-
const eventCfg = conf.pause[1] || "e:click|false";
|
|
325
|
-
const parts = eventCfg.replace('e:', '').split('|');
|
|
326
|
-
const eventName = parts[0];
|
|
327
|
-
const useCapture = parts[1] === 'true';
|
|
328
|
-
|
|
329
|
-
const togglePause = function (e) {
|
|
330
|
-
if (e) {
|
|
331
|
-
if (isPaused) {
|
|
332
|
-
isPaused = false;
|
|
333
|
-
pausedAccum += Date.now() - pauseStart;
|
|
334
|
-
} else {
|
|
335
|
-
isPaused = true;
|
|
336
|
-
pauseStart = Date.now();
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
};
|
|
340
|
-
|
|
341
|
-
const targetEls = document.querySelectorAll(conf.pause[0]);
|
|
342
|
-
targetEls.forEach(el => el.addEventListener(eventName, togglePause, useCapture));
|
|
343
|
-
}
|
|
344
|
-
|
|
345
|
-
const startedAt = Date.now();
|
|
346
|
-
|
|
347
|
-
// Initialize state storage for each element in the group
|
|
348
|
-
group.forEach(function (el, idx) {
|
|
349
|
-
if (!el.storeTransform) el.storeTransform = copyObj(defsCopyLocal[configIndex].storeValueAnim.transform);
|
|
350
|
-
if (!el.storeColor) {
|
|
351
|
-
el.storeColor = copyObj(defsCopyLocal[configIndex].storeValueAnim.color);
|
|
352
|
-
} else {
|
|
353
|
-
Object.keys(defsCopyLocal[configIndex].storeValueAnim.color).forEach(key => {
|
|
354
|
-
if (!el.storeColor[key]) el.storeColor[key] = defsCopyLocal[configIndex].storeValueAnim.color[key];
|
|
355
|
-
});
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
// Start staggered animations if timeline offset exists
|
|
359
|
-
if (conf.timeline !== 0) {
|
|
360
|
-
frameRunner([el], idx, conf.timeline * idx + conf.startafter, conf.startafter);
|
|
361
|
-
}
|
|
362
|
-
});
|
|
363
|
-
|
|
364
|
-
// Start simultaneous animations
|
|
365
|
-
if (conf.timeline === 0) {
|
|
366
|
-
frameRunner(group, 0, 0 + conf.startafter, conf.startafter);
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
function frameRunner(targetArray, idx, timeOffset, startAfter) {
|
|
370
|
-
// Manage animation frame cycles
|
|
371
|
-
if (conf.animFram) cancelAnimationFrame(conf.animFram[idx]);
|
|
372
|
-
else conf.animFram = {};
|
|
373
|
-
|
|
374
|
-
const iterConf = copyObj(defsCopyLocal[configIndex]);
|
|
375
|
-
iterConf.changetypeAnim = iterConf.typeAnimation;
|
|
376
|
-
iterConf.countSkip = 0;
|
|
377
|
-
iterConf.countSkip2 = 0;
|
|
378
|
-
|
|
379
|
-
let skipCounter;
|
|
380
|
-
const sv = iterConf.storeValueAnim;
|
|
381
|
-
|
|
382
|
-
// The main animation loop using requestAnimationFrame
|
|
383
|
-
function loop() {
|
|
384
|
-
if (isPaused) {
|
|
385
|
-
conf.animFram[idx] = requestAnimationFrame(loop);
|
|
386
|
-
return;
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
let delay = 0;
|
|
390
|
-
let eased, tmpVal, css;
|
|
391
|
-
const elapsed = Date.now() - (startedAt + timeOffset + pausedAccum);
|
|
392
|
-
|
|
393
|
-
if (elapsed >= 0) {
|
|
394
|
-
// Logic for handling loops, delays, and reversing (yoyo) animations
|
|
395
|
-
if (iterConf.boucle) {
|
|
396
|
-
if (iterConf.delay !== undefined) {
|
|
397
|
-
delay = iterConf.delay;
|
|
398
|
-
skipCounter = Math.floor((elapsed + delay) / (iterConf.duration + delay));
|
|
399
|
-
if (skipCounter !== iterConf.countSkip) {
|
|
400
|
-
iterConf.countSkip = skipCounter;
|
|
401
|
-
iterConf.skip = iterConf.skipDelay = true;
|
|
402
|
-
} else {
|
|
403
|
-
iterConf.skip = false;
|
|
404
|
-
if (elapsed % (iterConf.duration + delay) < iterConf.duration) {
|
|
405
|
-
iterConf.skipDelay = false;
|
|
406
|
-
if (iterConf.countSkip2 !== iterConf.countSkip) {
|
|
407
|
-
iterConf.countSkip2 = iterConf.countSkip;
|
|
408
|
-
iterConf.skip2 = true;
|
|
409
|
-
} else iterConf.skip2 = false;
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
} else {
|
|
413
|
-
skipCounter = Math.floor((elapsed + delay) / (iterConf.duration + delay));
|
|
414
|
-
if (skipCounter !== iterConf.countSkip) {
|
|
415
|
-
iterConf.countSkip = iterConf.countSkip2 = skipCounter;
|
|
416
|
-
iterConf.skip = iterConf.skip2 = true;
|
|
417
|
-
} else {
|
|
418
|
-
iterConf.skip = iterConf.skip2 = false;
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
iterConf.timeEasing = elapsed % (iterConf.duration + delay);
|
|
423
|
-
if (iterConf.skip) {
|
|
424
|
-
iterConf.impair = !iterConf.impair;
|
|
425
|
-
iterConf.changetypeAnim = iterConf.impair ? alternateAnim : declaredAnim;
|
|
426
|
-
iterConf.timeEasing = (iterConf.impair || iterConf.boucleType.indexOf("repeat") === 0) ? iterConf.duration : 0;
|
|
427
|
-
} else if (!iterConf.skipDelay) {
|
|
428
|
-
if (iterConf.impair && iterConf.boucleType.indexOf("return") === 0) {
|
|
429
|
-
iterConf.timeEasing = iterConf.duration - iterConf.timeEasing;
|
|
430
|
-
}
|
|
431
|
-
}
|
|
432
|
-
} else {
|
|
433
|
-
iterConf.timeEasing = elapsed < iterConf.duration ? elapsed : iterConf.duration;
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
// Update properties if not in delay phase
|
|
437
|
-
if (!iterConf.skipDelay || iterConf.skip) {
|
|
438
|
-
// Calculate ease factor (0 to 1)
|
|
439
|
-
eased = Easing[iterConf.changetypeAnim][0](iterConf.timeEasing, 0, 1, iterConf.duration, iterConf, idx);
|
|
440
|
-
|
|
441
|
-
if (iterConf.callback) {
|
|
442
|
-
targetArray.forEach(function (el, index) {
|
|
443
|
-
iterConf.callback(el, eased, iterConf, idx !== index ? idx : index);
|
|
444
|
-
});
|
|
445
|
-
} else {
|
|
446
|
-
// Apply styles: Transform, Color, or standard Numeric properties
|
|
447
|
-
iterConf.property.forEach(function (prop) {
|
|
448
|
-
css = "";
|
|
449
|
-
let key = typeof prop === "string" ? prop : Object.keys(prop)[0];
|
|
450
|
-
|
|
451
|
-
if (key.toLowerCase() === "transform" && sv[key] != null) {
|
|
452
|
-
prop.transform.forEach(function (tr) {
|
|
453
|
-
tmpVal = sv["from"][key][tr] + eased * (sv["to"][key][tr] - sv["from"][key][tr]);
|
|
454
|
-
targetArray.forEach(el => el.storeTransform[tr] = tmpVal);
|
|
455
|
-
});
|
|
456
|
-
targetArray.forEach(function (el) {
|
|
457
|
-
Object.keys(el.storeTransform).forEach(k => {
|
|
458
|
-
css += " " + PROPERTY_FORMAT_MAP[k].replace("*", el.storeTransform[k]);
|
|
459
|
-
});
|
|
460
|
-
el.style.transform = css;
|
|
461
|
-
css = "";
|
|
462
|
-
});
|
|
463
|
-
} else if (key.toLowerCase().indexOf("color") !== -1 && sv.color != null) {
|
|
464
|
-
targetArray.forEach(function (el) {
|
|
465
|
-
prop[key].forEach(function (colProp) {
|
|
466
|
-
tmpVal = sv["from"][key][colProp] + eased * (sv["to"][key][colProp] - sv["from"][key][colProp]);
|
|
467
|
-
el.storeColor[key][colProp] = tmpVal;
|
|
468
|
-
});
|
|
469
|
-
|
|
470
|
-
let colorStr = PROPERTY_FORMAT_MAP.rgba;
|
|
471
|
-
for (let colKey in COLOR_DEFAULTS) {
|
|
472
|
-
colorStr = colorStr.replace(new RegExp(colKey, "g"), el.storeColor[key][colKey]);
|
|
473
|
-
}
|
|
474
|
-
el.style[key] = colorStr;
|
|
475
|
-
});
|
|
476
|
-
} else {
|
|
477
|
-
css = (iterConf.px === "%" ? PROPERTY_FORMAT_MAP[key].replace("px", "%") : PROPERTY_FORMAT_MAP[key]).replace("*", sv["from"][key] + eased * (sv["to"][key] - sv["from"][key]));
|
|
478
|
-
targetArray.forEach(el => el.style[key] = css);
|
|
479
|
-
}
|
|
480
|
-
});
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
|
|
485
|
-
// Continue the loop if animation is still active or looping
|
|
486
|
-
if (iterConf.boucle || elapsed < iterConf.duration) {
|
|
487
|
-
conf.animFram[idx] = requestAnimationFrame(loop);
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
loop();
|
|
492
|
-
}
|
|
493
|
-
};
|
|
494
|
-
}
|
|
495
|
-
};
|
|
496
|
-
};
|
|
497
|
-
|
|
498
|
-
// -----------------------------
|
|
499
|
-
// Easing functions
|
|
500
|
-
// Standard easing definitions used by the animation engine.
|
|
501
|
-
// -----------------------------
|
|
502
|
-
const Easing = {
|
|
503
|
-
linear: [function(e, n, t, a) {
|
|
504
|
-
return t * e / a + n
|
|
505
|
-
}, "linear"],
|
|
506
|
-
quadin: [function(e, n, t, a) {
|
|
507
|
-
return t * (e /= a) * e + n
|
|
508
|
-
}, "quadout"],
|
|
509
|
-
quadout: [function(e, n, t, a) {
|
|
510
|
-
return -t * (e /= a) * (e - 2) + n
|
|
511
|
-
}, "quadin"],
|
|
512
|
-
quadinout: [function(e, n, t, a) {
|
|
513
|
-
return (e /= a / 2) < 1 ? t / 2 * e * e + n : -t / 2 * (--e * (e - 2) - 1) + n
|
|
514
|
-
}, "quadoutin"],
|
|
515
|
-
quadoutin: [function(e, n, t, a) {
|
|
516
|
-
var p = e / a,
|
|
517
|
-
p0;
|
|
518
|
-
if (p < 0.5) {
|
|
519
|
-
p0 = 1 - 2 * p;
|
|
520
|
-
return t * (0.5 * (1 - (p0 * p0))) + n;
|
|
521
|
-
} else {
|
|
522
|
-
p0 = p * 2 - 1;
|
|
523
|
-
return t * (0.5 * (p0 * p0) + 0.5) + n;
|
|
524
|
-
}
|
|
525
|
-
}, "quadinout"],
|
|
526
|
-
cubicin: [function(e, n, t, a) {
|
|
527
|
-
return t * (e /= a) * e * e + n
|
|
528
|
-
}, "cubicout"],
|
|
529
|
-
cubicout: [function(e, n, t, a) {
|
|
530
|
-
return t * ((e = e / a - 1) * e * e + 1) + n
|
|
531
|
-
}, "cubicin"],
|
|
532
|
-
cubicinout: [function(e, n, t, a) {
|
|
533
|
-
return (e /= a / 2) < 1 ? t / 2 * e * e * e + n : t / 2 * ((e -= 2) * e * e + 2) + n
|
|
534
|
-
}, "cubicoutin"],
|
|
535
|
-
cubicoutin: [function(e, n, t, a) {
|
|
536
|
-
var p = e / a,
|
|
537
|
-
p0;
|
|
538
|
-
if (p < 0.5) {
|
|
539
|
-
p0 = 1 - 2 * p;
|
|
540
|
-
return t * (0.5 * (1 - (p0 * p0 * p0))) + n;
|
|
541
|
-
} else {
|
|
542
|
-
p0 = p * 2 - 1;
|
|
543
|
-
return t * (0.5 * (p0 * p0 * p0) + 0.5) + n;
|
|
544
|
-
}
|
|
545
|
-
}, "cubicinout"],
|
|
546
|
-
quartin: [function(e, n, t, a) {
|
|
547
|
-
return t * (e /= a) * e * e * e + n
|
|
548
|
-
}, "quartout"],
|
|
549
|
-
quartout: [function(e, n, t, a) {
|
|
550
|
-
return -t * ((e = e / a - 1) * e * e * e - 1) + n
|
|
551
|
-
}, "quartin"],
|
|
552
|
-
quartinout: [function(e, n, t, a) {
|
|
553
|
-
return (e /= a / 2) < 1 ? t / 2 * e * e * e * e + n : -t / 2 * ((e -= 2) * e * e * e - 2) + n
|
|
554
|
-
}, "quartoutin"],
|
|
555
|
-
quartoutin: [function(e, n, t, a) {
|
|
556
|
-
var p = e / a,
|
|
557
|
-
p0;
|
|
558
|
-
if (p < 0.5) {
|
|
559
|
-
p0 = 1 - 2 * p;
|
|
560
|
-
return t * (0.5 * (1 - (p0 * p0 * p0 * p0))) + n;
|
|
561
|
-
} else {
|
|
562
|
-
p0 = p * 2 - 1;
|
|
563
|
-
return t * (0.5 * (p0 * p0 * p0 * p0) + 0.5) + n;
|
|
564
|
-
}
|
|
565
|
-
}, "quartinout"],
|
|
566
|
-
quintin: [function(e, n, t, a) {
|
|
567
|
-
return t * (e /= a) * e * e * e * e + n
|
|
568
|
-
}, "quintout"],
|
|
569
|
-
quintout: [function(e, n, t, a) {
|
|
570
|
-
return t * ((e = e / a - 1) * e * e * e * e + 1) + n
|
|
571
|
-
}, "quintin"],
|
|
572
|
-
quintinout: [function(e, n, t, a) {
|
|
573
|
-
return (e /= a / 2) < 1 ? t / 2 * e * e * e * e * e + n : t / 2 * ((e -= 2) * e * e * e * e + 2) + n
|
|
574
|
-
}, "quintoutin"],
|
|
575
|
-
quintoutin: [function(e, n, t, a) {
|
|
576
|
-
var p = e / a,
|
|
577
|
-
p0;
|
|
578
|
-
if (p < 0.5) {
|
|
579
|
-
p0 = 1 - 2 * p;
|
|
580
|
-
return t * (0.5 * (1 - (p0 * p0 * p0 * p0 * p0))) + n;
|
|
581
|
-
} else {
|
|
582
|
-
p0 = p * 2 - 1;
|
|
583
|
-
return t * (0.5 * (p0 * p0 * p0 * p0 * p0) + 0.5) + n;
|
|
584
|
-
}
|
|
585
|
-
}, "quintinout"],
|
|
586
|
-
sinein: [function(e, n, t, a) {
|
|
587
|
-
return -t * Math.cos(e / a * (Math.PI / 2)) + t + n
|
|
588
|
-
}, "sineout"],
|
|
589
|
-
sineout: [function(e, n, t, a) {
|
|
590
|
-
return t * Math.sin(e / a * (Math.PI / 2)) + n
|
|
591
|
-
}, "sinein"],
|
|
592
|
-
sineinout: [function(e, n, t, a) {
|
|
593
|
-
return -t / 2 * (Math.cos(Math.PI * e / a) - 1) + n
|
|
594
|
-
}, "sineoutin"],
|
|
595
|
-
sineoutin: [function(e, n, t, a) {
|
|
596
|
-
var p = e / a,
|
|
597
|
-
p0;
|
|
598
|
-
if (p < 0.5) {
|
|
599
|
-
p0 = 1 - 2 * p;
|
|
600
|
-
return t * (0.5 * (1 - (1 - Math.cos(p0 * Math.PI / 2)))) + n;
|
|
601
|
-
} else {
|
|
602
|
-
p0 = p * 2 - 1;
|
|
603
|
-
return t * (0.5 * (1 - Math.cos(p0 * Math.PI / 2)) + 0.5) + n;
|
|
604
|
-
}
|
|
605
|
-
}, "sineinout"],
|
|
606
|
-
expoin: [function(e, n, t, a) {
|
|
607
|
-
return 0 == e ? n : t * Math.pow(2, 10 * (e / a - 1)) + n
|
|
608
|
-
}, "expoout"],
|
|
609
|
-
expoout: [function(e, n, t, a) {
|
|
610
|
-
return e == a ? n + t : t * (1 - Math.pow(2, -10 * e / a)) + n
|
|
611
|
-
}, "expoin"],
|
|
612
|
-
expoinout: [function(e, n, t, a) {
|
|
613
|
-
return 0 == e ? n : e == a ? n + t : (e /= a / 2) < 1 ? t / 2 * Math.pow(2, 10 * (e - 1)) + n : t / 2 * (2 - Math.pow(2, -10 * --e)) + n
|
|
614
|
-
}, "expooutin"],
|
|
615
|
-
expooutin: [function(e, n, t, a) {
|
|
616
|
-
var p = e / a,
|
|
617
|
-
p0;
|
|
618
|
-
if (p == 0) {
|
|
619
|
-
return n;
|
|
620
|
-
} else if (p == 1) {
|
|
621
|
-
return n + t;
|
|
622
|
-
} else
|
|
623
|
-
if (p < 0.5) {
|
|
624
|
-
p0 = 1 - 2 * p;
|
|
625
|
-
return t * (0.5 * (1 - (Math.pow(2, 10 * (p0 - 1))))) + n;
|
|
626
|
-
} else {
|
|
627
|
-
p0 = p * 2 - 1;
|
|
628
|
-
return t * (0.5 * (Math.pow(2, 10 * (p0 - 1))) + 0.5) + n;
|
|
629
|
-
}
|
|
630
|
-
}, "expoinout"],
|
|
631
|
-
circin: [function(e, n, t, a) {
|
|
632
|
-
return -t * (Math.sqrt(1 - (e /= a) * e) - 1) + n
|
|
633
|
-
}, "circout"],
|
|
634
|
-
circout: [function(e, n, t, a) {
|
|
635
|
-
return t * Math.sqrt(1 - (e = e / a - 1) * e) + n
|
|
636
|
-
}, "circin"],
|
|
637
|
-
circinout: [function(e, n, t, a) {
|
|
638
|
-
return (e /= a / 2) < 1 ? -t / 2 * (Math.sqrt(1 - e * e) - 1) + n : t / 2 * (Math.sqrt(1 - (e -= 2) * e) + 1) + n
|
|
639
|
-
}, "circoutin"],
|
|
640
|
-
circoutin: [function(e, n, t, a) {
|
|
641
|
-
var p = e / a,
|
|
642
|
-
p0;
|
|
643
|
-
if (p < 0.5) {
|
|
644
|
-
p0 = 1 - 2 * p;
|
|
645
|
-
return t * (0.5 * Math.sqrt(1 - p0 * p0)) + n;
|
|
646
|
-
} else {
|
|
647
|
-
p0 = p * 2 - 1;
|
|
648
|
-
return t * (0.5 * (1 - Math.sqrt(1 - p0 * p0)) + 0.5) + n;
|
|
649
|
-
}
|
|
650
|
-
}, "circinout"],
|
|
651
|
-
elasticin: [function(e, n, t, a) {
|
|
652
|
-
var c = 1.70158,
|
|
653
|
-
b = 0,
|
|
654
|
-
r = t;
|
|
655
|
-
return 0 == e ? n : 1 == (e /= a) ? n + t : (b = b || .3 * a, c = r < Math.abs(t) ? (r = t, b / 4) : b / (2 * Math.PI) * Math.asin(t / r), -(r * Math.pow(2, 10 * --e) * Math.sin((e * a - c) * (2 * Math.PI) / b)) + n)
|
|
656
|
-
}, "elasticout"],
|
|
657
|
-
elasticout: [function(e, n, t, a) {
|
|
658
|
-
var c = 1.70158,
|
|
659
|
-
b = 0,
|
|
660
|
-
r = t;
|
|
661
|
-
return 0 == e ? n : 1 == (e /= a) ? n + t : (b = b || .3 * a, c = r < Math.abs(t) ? (r = t, b / 4) : b / (2 * Math.PI) * Math.asin(t / r), r * Math.pow(2, -10 * e) * Math.sin((e * a - c) * (2 * Math.PI) / b) + t + n)
|
|
662
|
-
}, "elasticin"],
|
|
663
|
-
elasticinout: [function(e, n, t, a) {
|
|
664
|
-
var c = 1.70158,
|
|
665
|
-
b = 0,
|
|
666
|
-
r = t;
|
|
667
|
-
return 0 == e ? n : 2 == (e /= a / 2) ? n + t : (b = b || a * (.3 * 1.5), c = r < Math.abs(t) ? (r = t, b / 4) : b / (2 * Math.PI) * Math.asin(t / r), e < 1 ? r * Math.pow(2, 10 * --e) * Math.sin((e * a - c) * (2 * Math.PI) / b) * -.5 + n : r * Math.pow(2, -10 * --e) * Math.sin((e * a - c) * (2 * Math.PI) / b) * .5 + t + n)
|
|
668
|
-
}, "elasticoutin"],
|
|
669
|
-
elasticoutin: [function(e, n, t, a) {
|
|
670
|
-
var p = e / a,
|
|
671
|
-
p0;
|
|
672
|
-
if (p === 0) {
|
|
673
|
-
return n;
|
|
674
|
-
} else if (p === 1) {
|
|
675
|
-
return t + n;
|
|
676
|
-
}
|
|
677
|
-
if (p < 0.5) {
|
|
678
|
-
p0 = 1 - 2 * p;
|
|
679
|
-
return t * (0.5 * (1 - (-Math.pow(2, 8 * (p0 - 1)) * Math.sin(((p0 - 1) * 80 - 7.5) * Math.PI / 15)))) + n;
|
|
680
|
-
} else {
|
|
681
|
-
p0 = p * 2 - 1;
|
|
682
|
-
return t * (0.5 * (-Math.pow(2, 8 * (p0 - 1)) * Math.sin(((p0 - 1) * 80 - 7.5) * Math.PI / 15)) + 0.5) + n
|
|
683
|
-
}
|
|
684
|
-
}, "elasticinout"],
|
|
685
|
-
backin: [function(e, n, t, a) {
|
|
686
|
-
return t * (e /= a) * e * (2.70158 * e - 1.70158) + n
|
|
687
|
-
}, "backout"],
|
|
688
|
-
backout: [function(e, n, t, a) {
|
|
689
|
-
return t * ((e = e / a - 1) * e * (2.70158 * e + 1.70158) + 1) + n
|
|
690
|
-
}, "backin"],
|
|
691
|
-
backinout: [function(e, n, t, a) {
|
|
692
|
-
var c = 1.70158;
|
|
693
|
-
return (e /= a / 2) < 1 ? t / 2 * (e * e * ((1 + (c *= 1.525)) * e - c)) + n : t / 2 * ((e -= 2) * e * ((1 + (c *= 1.525)) * e + c) + 2) + n
|
|
694
|
-
}, "backoutin"],
|
|
695
|
-
backoutin: [function(e, n, t, a) {
|
|
696
|
-
var p = e / a,
|
|
697
|
-
p0;
|
|
698
|
-
if (p < 0.5) {
|
|
699
|
-
p0 = 1 - 2 * p;
|
|
700
|
-
return t * (0.5 * (1 - p0 * p0 * (3 * p0 - 2))) + n;
|
|
701
|
-
} else {
|
|
702
|
-
p0 = p * 2 - 1;
|
|
703
|
-
return t * (0.5 * p0 * p0 * (3 * p0 - 2) + 0.5) + n;
|
|
704
|
-
}
|
|
705
|
-
}, "backinout"],
|
|
706
|
-
bouncein: [function(e, n, t, a) {
|
|
707
|
-
return t - Easing.bounceout[0](a - e, 0, t, a) + n
|
|
708
|
-
}, "bounceout"],
|
|
709
|
-
bounceout: [function(e, n, t, a) {
|
|
710
|
-
return (e /= a) < 1 / 2.75 ? t * (7.5625 * e * e) + n : e < 2 / 2.75 ? t * (7.5625 * (e -= 1.5 / 2.75) * e + .75) + n : e < 2.5 / 2.75 ? t * (7.5625 * (e -= 2.25 / 2.75) * e + .9375) + n : t * (7.5625 * (e -= 2.625 / 2.75) * e + .984375) + n
|
|
711
|
-
}, "bouncein"],
|
|
712
|
-
bounceinout: [function(e, n, t, a) {
|
|
713
|
-
return e < a / 2 ? .5 * Easing.bouncein[0](2 * e, 0, t, a) + n : .5 * Easing.bounceout[0](2 * e - a, 0, t, a) + .5 * t + n
|
|
714
|
-
}, "bounceoutin"],
|
|
715
|
-
bounceoutin: [function(e, n, t, a) {
|
|
716
|
-
var p = e / a,
|
|
717
|
-
p0, pow2, bounce = 4;
|
|
718
|
-
if (p < 0.5) {
|
|
719
|
-
p0 = 1 - 2 * p;
|
|
720
|
-
while (p0 < ((pow2 = Math.pow(2, --bounce)) - 1) / 11) {}
|
|
721
|
-
return t * (0.5 * (1 - (1 / Math.pow(4, 3 - bounce) - 7.5625 * Math.pow((pow2 * 3 - 2) / 22 - p0, 2)))) + n;
|
|
722
|
-
} else {
|
|
723
|
-
p0 = p * 2 - 1;
|
|
724
|
-
while (p0 < ((pow2 = Math.pow(2, --bounce)) - 1) / 11) {}
|
|
725
|
-
return t * (0.5 * (1 / Math.pow(4, 3 - bounce) - 7.5625 * Math.pow((pow2 * 3 - 2) / 22 - p0, 2)) + 0.5) + n;
|
|
726
|
-
}
|
|
727
|
-
}, "bounceinout"],
|
|
728
|
-
vibration: [function(e, n, t, a, c) {
|
|
729
|
-
return n + (t - n) / 2 + Math.sin(e * Math.PI / (a / c.vibrationStep) + 3 * Math.PI / 2) * (t - n) / 2
|
|
730
|
-
}, "vibration"],
|
|
731
|
-
cubicbezier: [function(e, n, t, a, c) {
|
|
732
|
-
let q = 1, qq = 0, sol;
|
|
733
|
-
if (c.impair && (c.boucleType === "returnRepeat" || c.boucleType === "repeatReturn")) {
|
|
734
|
-
q = -1; qq = 1;
|
|
735
|
-
}
|
|
736
|
-
let b = e / a, r = 1 - b,
|
|
737
|
-
l = Number(q * c.cubicbezier[0] + qq),
|
|
738
|
-
o = Number(q * c.cubicbezier[2] + qq);
|
|
739
|
-
|
|
740
|
-
if ((sol = solveCubic(3 * l - 3 * o + 1, 0 - 6 * l + 3 * o, 3 * l, 0 - b))) {
|
|
741
|
-
b = sol;
|
|
742
|
-
r = 1 - b;
|
|
743
|
-
}
|
|
744
|
-
let y = (r = 1 - b) * r * r * 0 + 3 * r * r * b * Number(q * c.cubicbezier[1] + qq) + 3 * r * b * b * Number(q * c.cubicbezier[3] + qq) + b * b * b * 1;
|
|
745
|
-
return n + y * t;
|
|
746
|
-
}, "cubicbezier"]
|
|
747
|
-
};
|
|
748
|
-
|
|
749
|
-
// The rest of easing functions identical to original (unchanged for correctness)
|
|
750
|
-
// (For brevity in this file view we keep the full Easing object above in the same form as original.)
|
|
751
|
-
|
|
752
|
-
// -----------------------------
|
|
753
|
-
// Math helpers: cubic solver and cube root
|
|
754
|
-
// -----------------------------
|
|
755
|
-
function solveCubic(a, b, c, d) {
|
|
756
|
-
let p = (3 * a * c - b * b) / (3 * a * a);
|
|
757
|
-
let q = (2 * b * b * b - 9 * a * b * c + 27 * a * a * d) / (27 * a * a * a);
|
|
758
|
-
let r;
|
|
6
|
+
// --- Enhanced DOM Selection Utility with Explicit Error Reporting (Supports Multiple Arguments) ---
|
|
7
|
+
const selectDom = function (...selectors) {
|
|
8
|
+
const allElements = [];
|
|
759
9
|
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
else return 0;
|
|
765
|
-
} else {
|
|
766
|
-
let D = q * q / 4 + p * p * p / 27;
|
|
767
|
-
if (Math.abs(D) < 1e-8) {
|
|
768
|
-
if (((r = -1.5 * q / p - b / (3 * a)) <= 1 && r >= 0) || ((r = 3 * q / p - b / (3 * a)) <= 1 && r >= 0)) return r;
|
|
769
|
-
} else if (D > 0) {
|
|
770
|
-
let u = cubeRoot(-q / 2 - Math.sqrt(D));
|
|
771
|
-
if ((r = (u - p / (3 * u)) - b / (3 * a)) <= 1 && r >= 0) return r;
|
|
772
|
-
} else {
|
|
773
|
-
let u = 2 * Math.sqrt(-p / 3);
|
|
774
|
-
let t = Math.acos(3 * q / p / u) / 3;
|
|
775
|
-
let k = 2 * Math.PI / 3;
|
|
776
|
-
if (((r = u * Math.cos(t) - b / (3 * a)) <= 1 && r >= 0) || ((r = u * Math.cos(t - k) - b / (3 * a)) <= 1 && r >= 0) || ((r = u * Math.cos(t - 2 * k) - b / (3 * a)) <= 1 && r >= 0)) return r;
|
|
777
|
-
}
|
|
10
|
+
// If no arguments were passed at all
|
|
11
|
+
if (selectors.length === 0) {
|
|
12
|
+
console.warn("Select-Animation: selectDom() was called without any arguments.");
|
|
13
|
+
return [];
|
|
778
14
|
}
|
|
779
|
-
}
|
|
780
|
-
|
|
781
|
-
function cubeRoot(v) {
|
|
782
|
-
let n = Math.pow(Math.abs(v), 1 / 3);
|
|
783
|
-
return v < 0 ? -n : n;
|
|
784
|
-
}
|
|
785
15
|
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
// --- Robust DOM Element Validation ---
|
|
800
|
-
function isElement(element) {
|
|
801
|
-
try {
|
|
802
|
-
// Check for standard DOM Element or HTMLDocument
|
|
803
|
-
return element instanceof Element || element instanceof HTMLDocument;
|
|
804
|
-
} catch (e) {
|
|
805
|
-
// Fallback for environments where Element is not defined
|
|
806
|
-
return (typeof element === "object") &&
|
|
807
|
-
(element.nodeType === 1) &&
|
|
808
|
-
(typeof element.nodeName === "string");
|
|
809
|
-
}
|
|
810
|
-
}
|
|
811
|
-
|
|
812
|
-
const copyObj = function(obj) {
|
|
813
|
-
let ret;
|
|
814
|
-
const assign = function(o, key, target) {
|
|
815
|
-
let sub = Object.prototype.toString.call(o[key]);
|
|
816
|
-
if (sub === "[object Object]" || sub === "[object Array]") {
|
|
817
|
-
target[key] = copyObj(o[key]);
|
|
818
|
-
} else {
|
|
819
|
-
target[key] = o[key];
|
|
820
|
-
}
|
|
821
|
-
};
|
|
822
|
-
|
|
823
|
-
if (Object.prototype.toString.call(obj) === "[object Object]") {
|
|
824
|
-
ret = {};
|
|
825
|
-
for (let key in obj) {
|
|
826
|
-
if (Object.prototype.hasOwnProperty.call(obj, key)) {
|
|
827
|
-
assign(obj, key, ret);
|
|
16
|
+
selectors.forEach((selector) => {
|
|
17
|
+
// 1. If the argument is already a DOM element
|
|
18
|
+
if (isElement(selector)) {
|
|
19
|
+
allElements.push(selector);
|
|
20
|
+
}
|
|
21
|
+
// 2. If the argument is a string (Selector)
|
|
22
|
+
else if (typeof selector === "string") {
|
|
23
|
+
const nodes = document.querySelectorAll(selector);
|
|
24
|
+
if (nodes.length === 0) {
|
|
25
|
+
console.warn(`Select-Animation: No elements found for selector "${selector}".`);
|
|
26
|
+
} else {
|
|
27
|
+
// Spread the NodeList into our results array
|
|
28
|
+
allElements.push(...Array.from(nodes));
|
|
828
29
|
}
|
|
829
|
-
}
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
}
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
copyObj
|
|
847
|
-
};
|
|
848
|
-
}
|
|
849
|
-
|
|
850
|
-
if (typeof global !== 'undefined') {
|
|
851
|
-
global.animate = animate;
|
|
852
|
-
global.selectDom = selectDom;
|
|
853
|
-
global.copyObj = copyObj;
|
|
854
|
-
}
|
|
855
|
-
|
|
856
|
-
})(typeof window !== 'undefined' ? window : this);
|
|
30
|
+
}
|
|
31
|
+
// 3. If the argument is an array or collection
|
|
32
|
+
else if (Array.isArray(selector) || (selector && typeof selector.length === "number")) {
|
|
33
|
+
const filtered = Array.from(selector).filter(isElement);
|
|
34
|
+
allElements.push(...filtered);
|
|
35
|
+
}
|
|
36
|
+
// 4. INVALID INPUT: Alert the developer if they passed a number/null/etc.
|
|
37
|
+
else if (selector !== undefined && selector !== null) {
|
|
38
|
+
console.error(
|
|
39
|
+
`Select-Animation ERROR: Invalid selector type "${typeof selector}". ` +
|
|
40
|
+
`Expected String, Element, or Array, but received:`, selector
|
|
41
|
+
);
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
return allElements;
|
|
46
|
+
};
|