select-animation 1.5.1 → 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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/select-animation.js +3 -823
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "select-animation",
3
- "version": "1.5.1",
3
+ "version": "1.6.0",
4
4
  "description": "High-performance JavaScript animation engine for organic & fluid motion",
5
5
  "main": "select-animation.js",
6
6
  "scripts": {
@@ -1,107 +1,9 @@
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
- // --- Enhanced DOM Selection Utility (Supports Multiple Arguments) ---
6
+ // --- Enhanced DOM Selection Utility with Explicit Error Reporting (Supports Multiple Arguments) ---
105
7
  const selectDom = function (...selectors) {
106
8
  const allElements = [];
107
9
 
@@ -141,726 +43,4 @@
141
43
  });
142
44
 
143
45
  return allElements;
144
- };
145
-
146
- // -----------------------------
147
- // animate: animation factory
148
- // Accepts animation definitions and returns a runner function to start animations on targets.
149
- // -----------------------------
150
- const animate = function () {
151
- const definitions = arguments;
152
- const defsCopy = copyObj(definitions);
153
-
154
- return function () {
155
- let tmp, i, propIndex, fromItem, toItem, valFrom, valTo, t;
156
- let grouped = [];
157
- let expectNextGroup = false;
158
- let staging = { color: {}, transform: {}, from: {}, to: {} };
159
-
160
- // Process the definitions to map elements to their animation settings
161
- buildPlan();
162
-
163
- function buildPlan() {
164
- let secondPass = false;
165
-
166
- for (let c = 0, total = definitions.length; c < total; c++) {
167
- propIndex = 0;
168
- // If current item is an element or an array of elements
169
- if (expectNextGroup || Array.isArray(defsCopy[c]) || isElement(defsCopy[c])) {
170
- if (secondPass) {
171
- Array.isArray(defsCopy[c]) || (defsCopy[c] = [defsCopy[c]]);
172
- Array.prototype.push.apply(grouped, defsCopy[c]);
173
- }
174
- expectNextGroup = false;
175
- }
176
- // --- Handle Configuration Object with Validation ---
177
- else if (typeof defsCopy[c] === 'object' && defsCopy[c] !== null) {
178
- if (secondPass) {
179
- // Execute the animation runner for the current group
180
- runner(grouped, definitions, defsCopy, c)();
181
- } else {
182
- expectNextGroup = false;
183
-
184
- // 1. Validate Duration and Animation Type
185
- defsCopy[c].duration = (typeof defsCopy[c].duration === 'number' && defsCopy[c].duration > 0) ? defsCopy[c].duration : 1000;
186
-
187
- let requestedType = defsCopy[c].typeAnimation;
188
-
189
- if (requestedType === "vibration" && defsCopy[c].vibrationStep === undefined) {
190
- defsCopy[c].vibrationStep = 6;
191
- } else if (requestedType) {
192
- t = getNumber(requestedType);
193
- if (t && t.length === 4) {
194
- defsCopy[c].cubicbezier = t;
195
- defsCopy[c].typeAnimation = "cubicbezier";
196
- } else {
197
- // STOP EXECUTION: If easing is not found, do not fall back to linear
198
- if (requestedType !== "linear" && requestedType !== "vibration" && requestedType !== "cubicbezier" && (!Easing || !Easing[requestedType])) {
199
- // Use Error instead of warn to make it impossible to ignore
200
- throw new Error(`Select-Animation ERROR: The easing function "${requestedType}" does not exist. Please check your spelling or definitions.`);
201
- }
202
- }
203
- }
204
-
205
- // Double-check if the animation type is valid before processing
206
- if (!defsCopy[c].typeAnimation) return;
207
-
208
- // 2. Helper to sanitize input values (convert "100px" to 100)
209
- const parseVal = (v) => {
210
- if (typeof v === "number") return v;
211
- let p = parseFloat(v);
212
- return isNaN(p) ? 0 : p;
213
- };
214
-
215
- // Process properties and prepare "from" and "to" values
216
- if (!defsCopy[c].callback &&
217
- (Array.isArray(defsCopy[c].property) || (defsCopy[c].property !== undefined && (defsCopy[c].property = [defsCopy[c].property])))) {
218
-
219
- defsCopy[c].property.forEach(function (propItem) {
220
- const fromIsObject = typeof defsCopy[c].from === "object";
221
- const toIsObject = typeof defsCopy[c].to === "object";
222
-
223
- // Safely extract from/to values based on their types
224
- if (!fromIsObject) valFrom = parseVal(defsCopy[c].from);
225
- else fromItem = defsCopy[c]["from"][propIndex] || 0;
226
-
227
- if (!toIsObject) valTo = parseVal(defsCopy[c].to);
228
- else toItem = defsCopy[c]["to"][propIndex] || 0;
229
-
230
- if (typeof propItem === "object") {
231
- let propName = Object.keys(propItem)[0];
232
- if (!Array.isArray(propItem[propName])) propItem[propName] = [propItem[propName]];
233
-
234
- // Handle Colors and Transform objects
235
- if ((propName.toLowerCase().indexOf("color") !== -1 && (staging.color[propName] = COLOR_PROPERTIES[propName])) ||
236
- propName.toLowerCase().indexOf("transform") !== -1) {
237
-
238
- let inner = 0;
239
- staging["from"][propName] = {};
240
- staging["to"][propName] = {};
241
-
242
- propItem[propName].forEach(function (innerProp) {
243
- if (propName.toLowerCase() === "transform") staging[propName][innerProp] = 0;
244
- else staging.color[propName][innerProp] = 0;
245
-
246
- // Validate and assign nested properties
247
- if (fromIsObject) {
248
- let raw = (fromItem[propName] !== undefined) ? (Array.isArray(fromItem[propName]) ? fromItem[propName][inner] : fromItem[propName][innerProp]) : valFrom;
249
- staging["from"][propName][innerProp] = parseVal(raw);
250
- } else {
251
- staging["from"][propName][innerProp] = parseVal(defsCopy[c].from);
252
- }
253
-
254
- if (toIsObject) {
255
- let raw = (toItem[propName] !== undefined) ? (Array.isArray(toItem[propName]) ? toItem[propName][inner] : toItem[propName][innerProp]) : valTo;
256
- staging["to"][propName][innerProp] = parseVal(raw);
257
- } else {
258
- staging["to"][propName][innerProp] = parseVal(defsCopy[c].to);
259
- }
260
- inner++;
261
- });
262
- propIndex++;
263
- }
264
- } else {
265
- // Handle simple numeric CSS properties (width, height, etc.)
266
- if (fromIsObject) {
267
- let raw = fromItem[propItem] !== undefined ? fromItem[propItem] : (fromItem !== undefined ? fromItem : valFrom);
268
- staging["from"][propItem] = parseVal(raw);
269
- } else {
270
- staging["from"][propItem] = parseVal(defsCopy[c].from);
271
- }
272
-
273
- if (toIsObject) {
274
- let raw = toItem[propItem] !== undefined ? toItem[propItem] : (toItem !== undefined ? toItem : valTo);
275
- staging["to"][propItem] = parseVal(raw);
276
- } else {
277
- staging["to"][propItem] = parseVal(defsCopy[c].to);
278
- }
279
- propIndex++;
280
- }
281
- });
282
- }
283
-
284
- // 3. Callback Safety Validation
285
- // Ensure hooks are actual functions to prevent execution errors
286
- if (defsCopy[c].onStep && typeof defsCopy[c].onStep !== 'function') defsCopy[c].onStep = null;
287
- if (defsCopy[c].onComplete && typeof defsCopy[c].onComplete !== 'function') defsCopy[c].onComplete = null;
288
-
289
- // Finalize staging data and store it
290
- defsCopy[c].storeValueAnim = copyObj(staging);
291
- staging = { color: {}, transform: {}, from: {}, to: {} };
292
- }
293
-
294
- // Determine if the next item starts a new sequence group
295
- if (definitions[c + 1] !== undefined && (Array.isArray(definitions[c + 1]) || isElement(definitions[c + 1]))) {
296
- expectNextGroup = true;
297
- grouped = [];
298
- }
299
- }
300
-
301
- // Switch to second pass to execute the runners
302
- if (c === total - 1 && !secondPass) {
303
- expectNextGroup = false;
304
- secondPass = true;
305
- c = -1;
306
- }
307
- }
308
- }
309
-
310
- function runner(group, defs, defsCopyLocal, configIndex) {
311
- const conf = defs[configIndex];
312
- const declaredAnim = defsCopyLocal[configIndex].typeAnimation;
313
- let alternateAnim = declaredAnim;
314
-
315
- // Sanitize timing inputs
316
- conf.timeline = !isNaN(Number(conf.timeline)) ? Number(conf.timeline) : 0;
317
- conf.startafter = !isNaN(Number(conf.startafter)) ? Number(conf.startafter) : 0;
318
-
319
- // Prepare looping and easing alternates
320
- if (conf.boucle) {
321
- conf.delay = !isNaN(Number(conf.delay)) ? Number(conf.delay) : undefined;
322
- if (conf.boucleType === "returnRepeat" || conf.boucleType === "repeatReturn") {
323
- alternateAnim = Easing[declaredAnim][1];
324
- }
325
- }
326
-
327
- return function run(indexArg) {
328
- let pausedAccum = 0;
329
- let isPaused = false;
330
- let pauseStart;
331
-
332
- // Initialize event-based pause/resume logic if configured
333
- if (conf.pause && Array.isArray(conf.pause)) {
334
- const eventCfg = conf.pause[1] || "e:click|false";
335
- const parts = eventCfg.replace('e:', '').split('|');
336
- const eventName = parts[0];
337
- const useCapture = parts[1] === 'true';
338
-
339
- const togglePause = function (e) {
340
- if (e) {
341
- if (isPaused) {
342
- isPaused = false;
343
- pausedAccum += Date.now() - pauseStart;
344
- } else {
345
- isPaused = true;
346
- pauseStart = Date.now();
347
- }
348
- }
349
- };
350
-
351
- const targetEls = document.querySelectorAll(conf.pause[0]);
352
- targetEls.forEach(el => el.addEventListener(eventName, togglePause, useCapture));
353
- }
354
-
355
- const startedAt = Date.now();
356
-
357
- // Initialize state storage for each element in the group
358
- group.forEach(function (el, idx) {
359
- if (!el.storeTransform) el.storeTransform = copyObj(defsCopyLocal[configIndex].storeValueAnim.transform);
360
- if (!el.storeColor) {
361
- el.storeColor = copyObj(defsCopyLocal[configIndex].storeValueAnim.color);
362
- } else {
363
- Object.keys(defsCopyLocal[configIndex].storeValueAnim.color).forEach(key => {
364
- if (!el.storeColor[key]) el.storeColor[key] = defsCopyLocal[configIndex].storeValueAnim.color[key];
365
- });
366
- }
367
-
368
- // Start staggered animations if timeline offset exists
369
- if (conf.timeline !== 0) {
370
- frameRunner([el], idx, conf.timeline * idx + conf.startafter, conf.startafter);
371
- }
372
- });
373
-
374
- // Start simultaneous animations
375
- if (conf.timeline === 0) {
376
- frameRunner(group, 0, 0 + conf.startafter, conf.startafter);
377
- }
378
-
379
- function frameRunner(targetArray, idx, timeOffset, startAfter) {
380
- // Manage animation frame cycles
381
- if (conf.animFram) cancelAnimationFrame(conf.animFram[idx]);
382
- else conf.animFram = {};
383
-
384
- const iterConf = copyObj(defsCopyLocal[configIndex]);
385
- iterConf.changetypeAnim = iterConf.typeAnimation;
386
- iterConf.countSkip = 0;
387
- iterConf.countSkip2 = 0;
388
-
389
- let skipCounter;
390
- const sv = iterConf.storeValueAnim;
391
-
392
- // The main animation loop using requestAnimationFrame
393
- function loop() {
394
- if (isPaused) {
395
- conf.animFram[idx] = requestAnimationFrame(loop);
396
- return;
397
- }
398
-
399
- let delay = 0;
400
- let eased, tmpVal, css;
401
- const elapsed = Date.now() - (startedAt + timeOffset + pausedAccum);
402
-
403
- if (elapsed >= 0) {
404
- // Logic for handling loops, delays, and reversing (yoyo) animations
405
- if (iterConf.boucle) {
406
- if (iterConf.delay !== undefined) {
407
- delay = iterConf.delay;
408
- skipCounter = Math.floor((elapsed + delay) / (iterConf.duration + delay));
409
- if (skipCounter !== iterConf.countSkip) {
410
- iterConf.countSkip = skipCounter;
411
- iterConf.skip = iterConf.skipDelay = true;
412
- } else {
413
- iterConf.skip = false;
414
- if (elapsed % (iterConf.duration + delay) < iterConf.duration) {
415
- iterConf.skipDelay = false;
416
- if (iterConf.countSkip2 !== iterConf.countSkip) {
417
- iterConf.countSkip2 = iterConf.countSkip;
418
- iterConf.skip2 = true;
419
- } else iterConf.skip2 = false;
420
- }
421
- }
422
- } else {
423
- skipCounter = Math.floor((elapsed + delay) / (iterConf.duration + delay));
424
- if (skipCounter !== iterConf.countSkip) {
425
- iterConf.countSkip = iterConf.countSkip2 = skipCounter;
426
- iterConf.skip = iterConf.skip2 = true;
427
- } else {
428
- iterConf.skip = iterConf.skip2 = false;
429
- }
430
- }
431
-
432
- iterConf.timeEasing = elapsed % (iterConf.duration + delay);
433
- if (iterConf.skip) {
434
- iterConf.impair = !iterConf.impair;
435
- iterConf.changetypeAnim = iterConf.impair ? alternateAnim : declaredAnim;
436
- iterConf.timeEasing = (iterConf.impair || iterConf.boucleType.indexOf("repeat") === 0) ? iterConf.duration : 0;
437
- } else if (!iterConf.skipDelay) {
438
- if (iterConf.impair && iterConf.boucleType.indexOf("return") === 0) {
439
- iterConf.timeEasing = iterConf.duration - iterConf.timeEasing;
440
- }
441
- }
442
- } else {
443
- iterConf.timeEasing = elapsed < iterConf.duration ? elapsed : iterConf.duration;
444
- }
445
-
446
- // Update properties if not in delay phase
447
- if (!iterConf.skipDelay || iterConf.skip) {
448
- // Calculate ease factor (0 to 1)
449
- eased = Easing[iterConf.changetypeAnim][0](iterConf.timeEasing, 0, 1, iterConf.duration, iterConf, idx);
450
-
451
- if (iterConf.callback) {
452
- targetArray.forEach(function (el, index) {
453
- iterConf.callback(el, eased, iterConf, idx !== index ? idx : index);
454
- });
455
- } else {
456
- // Apply styles: Transform, Color, or standard Numeric properties
457
- iterConf.property.forEach(function (prop) {
458
- css = "";
459
- let key = typeof prop === "string" ? prop : Object.keys(prop)[0];
460
-
461
- if (key.toLowerCase() === "transform" && sv[key] != null) {
462
- prop.transform.forEach(function (tr) {
463
- tmpVal = sv["from"][key][tr] + eased * (sv["to"][key][tr] - sv["from"][key][tr]);
464
- targetArray.forEach(el => el.storeTransform[tr] = tmpVal);
465
- });
466
- targetArray.forEach(function (el) {
467
- Object.keys(el.storeTransform).forEach(k => {
468
- css += " " + PROPERTY_FORMAT_MAP[k].replace("*", el.storeTransform[k]);
469
- });
470
- el.style.transform = css;
471
- css = "";
472
- });
473
- } else if (key.toLowerCase().indexOf("color") !== -1 && sv.color != null) {
474
- targetArray.forEach(function (el) {
475
- prop[key].forEach(function (colProp) {
476
- tmpVal = sv["from"][key][colProp] + eased * (sv["to"][key][colProp] - sv["from"][key][colProp]);
477
- el.storeColor[key][colProp] = tmpVal;
478
- });
479
-
480
- let colorStr = PROPERTY_FORMAT_MAP.rgba;
481
- for (let colKey in COLOR_DEFAULTS) {
482
- colorStr = colorStr.replace(new RegExp(colKey, "g"), el.storeColor[key][colKey]);
483
- }
484
- el.style[key] = colorStr;
485
- });
486
- } else {
487
- css = (iterConf.px === "%" ? PROPERTY_FORMAT_MAP[key].replace("px", "%") : PROPERTY_FORMAT_MAP[key]).replace("*", sv["from"][key] + eased * (sv["to"][key] - sv["from"][key]));
488
- targetArray.forEach(el => el.style[key] = css);
489
- }
490
- });
491
- }
492
- }
493
- }
494
-
495
- // Continue the loop if animation is still active or looping
496
- if (iterConf.boucle || elapsed < iterConf.duration) {
497
- conf.animFram[idx] = requestAnimationFrame(loop);
498
- }
499
- }
500
-
501
- loop();
502
- }
503
- };
504
- }
505
- };
506
- };
507
-
508
- // -----------------------------
509
- // Easing functions
510
- // Standard easing definitions used by the animation engine.
511
- // -----------------------------
512
- const Easing = {
513
- linear: [function(e, n, t, a) {
514
- return t * e / a + n
515
- }, "linear"],
516
- quadin: [function(e, n, t, a) {
517
- return t * (e /= a) * e + n
518
- }, "quadout"],
519
- quadout: [function(e, n, t, a) {
520
- return -t * (e /= a) * (e - 2) + n
521
- }, "quadin"],
522
- quadinout: [function(e, n, t, a) {
523
- return (e /= a / 2) < 1 ? t / 2 * e * e + n : -t / 2 * (--e * (e - 2) - 1) + n
524
- }, "quadoutin"],
525
- quadoutin: [function(e, n, t, a) {
526
- var p = e / a,
527
- p0;
528
- if (p < 0.5) {
529
- p0 = 1 - 2 * p;
530
- return t * (0.5 * (1 - (p0 * p0))) + n;
531
- } else {
532
- p0 = p * 2 - 1;
533
- return t * (0.5 * (p0 * p0) + 0.5) + n;
534
- }
535
- }, "quadinout"],
536
- cubicin: [function(e, n, t, a) {
537
- return t * (e /= a) * e * e + n
538
- }, "cubicout"],
539
- cubicout: [function(e, n, t, a) {
540
- return t * ((e = e / a - 1) * e * e + 1) + n
541
- }, "cubicin"],
542
- cubicinout: [function(e, n, t, a) {
543
- return (e /= a / 2) < 1 ? t / 2 * e * e * e + n : t / 2 * ((e -= 2) * e * e + 2) + n
544
- }, "cubicoutin"],
545
- cubicoutin: [function(e, n, t, a) {
546
- var p = e / a,
547
- p0;
548
- if (p < 0.5) {
549
- p0 = 1 - 2 * p;
550
- return t * (0.5 * (1 - (p0 * p0 * p0))) + n;
551
- } else {
552
- p0 = p * 2 - 1;
553
- return t * (0.5 * (p0 * p0 * p0) + 0.5) + n;
554
- }
555
- }, "cubicinout"],
556
- quartin: [function(e, n, t, a) {
557
- return t * (e /= a) * e * e * e + n
558
- }, "quartout"],
559
- quartout: [function(e, n, t, a) {
560
- return -t * ((e = e / a - 1) * e * e * e - 1) + n
561
- }, "quartin"],
562
- quartinout: [function(e, n, t, a) {
563
- return (e /= a / 2) < 1 ? t / 2 * e * e * e * e + n : -t / 2 * ((e -= 2) * e * e * e - 2) + n
564
- }, "quartoutin"],
565
- quartoutin: [function(e, n, t, a) {
566
- var p = e / a,
567
- p0;
568
- if (p < 0.5) {
569
- p0 = 1 - 2 * p;
570
- return t * (0.5 * (1 - (p0 * p0 * p0 * p0))) + n;
571
- } else {
572
- p0 = p * 2 - 1;
573
- return t * (0.5 * (p0 * p0 * p0 * p0) + 0.5) + n;
574
- }
575
- }, "quartinout"],
576
- quintin: [function(e, n, t, a) {
577
- return t * (e /= a) * e * e * e * e + n
578
- }, "quintout"],
579
- quintout: [function(e, n, t, a) {
580
- return t * ((e = e / a - 1) * e * e * e * e + 1) + n
581
- }, "quintin"],
582
- quintinout: [function(e, n, t, a) {
583
- return (e /= a / 2) < 1 ? t / 2 * e * e * e * e * e + n : t / 2 * ((e -= 2) * e * e * e * e + 2) + n
584
- }, "quintoutin"],
585
- quintoutin: [function(e, n, t, a) {
586
- var p = e / a,
587
- p0;
588
- if (p < 0.5) {
589
- p0 = 1 - 2 * p;
590
- return t * (0.5 * (1 - (p0 * p0 * p0 * p0 * p0))) + n;
591
- } else {
592
- p0 = p * 2 - 1;
593
- return t * (0.5 * (p0 * p0 * p0 * p0 * p0) + 0.5) + n;
594
- }
595
- }, "quintinout"],
596
- sinein: [function(e, n, t, a) {
597
- return -t * Math.cos(e / a * (Math.PI / 2)) + t + n
598
- }, "sineout"],
599
- sineout: [function(e, n, t, a) {
600
- return t * Math.sin(e / a * (Math.PI / 2)) + n
601
- }, "sinein"],
602
- sineinout: [function(e, n, t, a) {
603
- return -t / 2 * (Math.cos(Math.PI * e / a) - 1) + n
604
- }, "sineoutin"],
605
- sineoutin: [function(e, n, t, a) {
606
- var p = e / a,
607
- p0;
608
- if (p < 0.5) {
609
- p0 = 1 - 2 * p;
610
- return t * (0.5 * (1 - (1 - Math.cos(p0 * Math.PI / 2)))) + n;
611
- } else {
612
- p0 = p * 2 - 1;
613
- return t * (0.5 * (1 - Math.cos(p0 * Math.PI / 2)) + 0.5) + n;
614
- }
615
- }, "sineinout"],
616
- expoin: [function(e, n, t, a) {
617
- return 0 == e ? n : t * Math.pow(2, 10 * (e / a - 1)) + n
618
- }, "expoout"],
619
- expoout: [function(e, n, t, a) {
620
- return e == a ? n + t : t * (1 - Math.pow(2, -10 * e / a)) + n
621
- }, "expoin"],
622
- expoinout: [function(e, n, t, a) {
623
- 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
624
- }, "expooutin"],
625
- expooutin: [function(e, n, t, a) {
626
- var p = e / a,
627
- p0;
628
- if (p == 0) {
629
- return n;
630
- } else if (p == 1) {
631
- return n + t;
632
- } else
633
- if (p < 0.5) {
634
- p0 = 1 - 2 * p;
635
- return t * (0.5 * (1 - (Math.pow(2, 10 * (p0 - 1))))) + n;
636
- } else {
637
- p0 = p * 2 - 1;
638
- return t * (0.5 * (Math.pow(2, 10 * (p0 - 1))) + 0.5) + n;
639
- }
640
- }, "expoinout"],
641
- circin: [function(e, n, t, a) {
642
- return -t * (Math.sqrt(1 - (e /= a) * e) - 1) + n
643
- }, "circout"],
644
- circout: [function(e, n, t, a) {
645
- return t * Math.sqrt(1 - (e = e / a - 1) * e) + n
646
- }, "circin"],
647
- circinout: [function(e, n, t, a) {
648
- return (e /= a / 2) < 1 ? -t / 2 * (Math.sqrt(1 - e * e) - 1) + n : t / 2 * (Math.sqrt(1 - (e -= 2) * e) + 1) + n
649
- }, "circoutin"],
650
- circoutin: [function(e, n, t, a) {
651
- var p = e / a,
652
- p0;
653
- if (p < 0.5) {
654
- p0 = 1 - 2 * p;
655
- return t * (0.5 * Math.sqrt(1 - p0 * p0)) + n;
656
- } else {
657
- p0 = p * 2 - 1;
658
- return t * (0.5 * (1 - Math.sqrt(1 - p0 * p0)) + 0.5) + n;
659
- }
660
- }, "circinout"],
661
- elasticin: [function(e, n, t, a) {
662
- var c = 1.70158,
663
- b = 0,
664
- r = t;
665
- 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)
666
- }, "elasticout"],
667
- elasticout: [function(e, n, t, a) {
668
- var c = 1.70158,
669
- b = 0,
670
- r = t;
671
- 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)
672
- }, "elasticin"],
673
- elasticinout: [function(e, n, t, a) {
674
- var c = 1.70158,
675
- b = 0,
676
- r = t;
677
- 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)
678
- }, "elasticoutin"],
679
- elasticoutin: [function(e, n, t, a) {
680
- var p = e / a,
681
- p0;
682
- if (p === 0) {
683
- return n;
684
- } else if (p === 1) {
685
- return t + n;
686
- }
687
- if (p < 0.5) {
688
- p0 = 1 - 2 * p;
689
- return t * (0.5 * (1 - (-Math.pow(2, 8 * (p0 - 1)) * Math.sin(((p0 - 1) * 80 - 7.5) * Math.PI / 15)))) + n;
690
- } else {
691
- p0 = p * 2 - 1;
692
- return t * (0.5 * (-Math.pow(2, 8 * (p0 - 1)) * Math.sin(((p0 - 1) * 80 - 7.5) * Math.PI / 15)) + 0.5) + n
693
- }
694
- }, "elasticinout"],
695
- backin: [function(e, n, t, a) {
696
- return t * (e /= a) * e * (2.70158 * e - 1.70158) + n
697
- }, "backout"],
698
- backout: [function(e, n, t, a) {
699
- return t * ((e = e / a - 1) * e * (2.70158 * e + 1.70158) + 1) + n
700
- }, "backin"],
701
- backinout: [function(e, n, t, a) {
702
- var c = 1.70158;
703
- 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
704
- }, "backoutin"],
705
- backoutin: [function(e, n, t, a) {
706
- var p = e / a,
707
- p0;
708
- if (p < 0.5) {
709
- p0 = 1 - 2 * p;
710
- return t * (0.5 * (1 - p0 * p0 * (3 * p0 - 2))) + n;
711
- } else {
712
- p0 = p * 2 - 1;
713
- return t * (0.5 * p0 * p0 * (3 * p0 - 2) + 0.5) + n;
714
- }
715
- }, "backinout"],
716
- bouncein: [function(e, n, t, a) {
717
- return t - Easing.bounceout[0](a - e, 0, t, a) + n
718
- }, "bounceout"],
719
- bounceout: [function(e, n, t, a) {
720
- 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
721
- }, "bouncein"],
722
- bounceinout: [function(e, n, t, a) {
723
- 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
724
- }, "bounceoutin"],
725
- bounceoutin: [function(e, n, t, a) {
726
- var p = e / a,
727
- p0, pow2, bounce = 4;
728
- if (p < 0.5) {
729
- p0 = 1 - 2 * p;
730
- while (p0 < ((pow2 = Math.pow(2, --bounce)) - 1) / 11) {}
731
- return t * (0.5 * (1 - (1 / Math.pow(4, 3 - bounce) - 7.5625 * Math.pow((pow2 * 3 - 2) / 22 - p0, 2)))) + n;
732
- } else {
733
- p0 = p * 2 - 1;
734
- while (p0 < ((pow2 = Math.pow(2, --bounce)) - 1) / 11) {}
735
- return t * (0.5 * (1 / Math.pow(4, 3 - bounce) - 7.5625 * Math.pow((pow2 * 3 - 2) / 22 - p0, 2)) + 0.5) + n;
736
- }
737
- }, "bounceinout"],
738
- vibration: [function(e, n, t, a, c) {
739
- return n + (t - n) / 2 + Math.sin(e * Math.PI / (a / c.vibrationStep) + 3 * Math.PI / 2) * (t - n) / 2
740
- }, "vibration"],
741
- cubicbezier: [function(e, n, t, a, c) {
742
- let q = 1, qq = 0, sol;
743
- if (c.impair && (c.boucleType === "returnRepeat" || c.boucleType === "repeatReturn")) {
744
- q = -1; qq = 1;
745
- }
746
- let b = e / a, r = 1 - b,
747
- l = Number(q * c.cubicbezier[0] + qq),
748
- o = Number(q * c.cubicbezier[2] + qq);
749
-
750
- if ((sol = solveCubic(3 * l - 3 * o + 1, 0 - 6 * l + 3 * o, 3 * l, 0 - b))) {
751
- b = sol;
752
- r = 1 - b;
753
- }
754
- 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;
755
- return n + y * t;
756
- }, "cubicbezier"]
757
- };
758
-
759
- // The rest of easing functions identical to original (unchanged for correctness)
760
- // (For brevity in this file view we keep the full Easing object above in the same form as original.)
761
-
762
- // -----------------------------
763
- // Math helpers: cubic solver and cube root
764
- // -----------------------------
765
- function solveCubic(a, b, c, d) {
766
- let p = (3 * a * c - b * b) / (3 * a * a);
767
- let q = (2 * b * b * b - 9 * a * b * c + 27 * a * a * d) / (27 * a * a * a);
768
- let r;
769
-
770
- if (Math.abs(p) < 1e-8) {
771
- if ((r = cubeRoot(-q) - b / (3 * a)) <= 1 && r >= 0) return r;
772
- } else if (Math.abs(q) < 1e-8) {
773
- if (((r = Math.sqrt(-p) - b / (3 * a)) <= 1 && r >= 0) || ((r = -Math.sqrt(-p) - b / (3 * a)) <= 1 && r >= 0)) return r;
774
- else return 0;
775
- } else {
776
- let D = q * q / 4 + p * p * p / 27;
777
- if (Math.abs(D) < 1e-8) {
778
- if (((r = -1.5 * q / p - b / (3 * a)) <= 1 && r >= 0) || ((r = 3 * q / p - b / (3 * a)) <= 1 && r >= 0)) return r;
779
- } else if (D > 0) {
780
- let u = cubeRoot(-q / 2 - Math.sqrt(D));
781
- if ((r = (u - p / (3 * u)) - b / (3 * a)) <= 1 && r >= 0) return r;
782
- } else {
783
- let u = 2 * Math.sqrt(-p / 3);
784
- let t = Math.acos(3 * q / p / u) / 3;
785
- let k = 2 * Math.PI / 3;
786
- 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;
787
- }
788
- }
789
- }
790
-
791
- function cubeRoot(v) {
792
- let n = Math.pow(Math.abs(v), 1 / 3);
793
- return v < 0 ? -n : n;
794
- }
795
-
796
- // -----------------------------
797
- // Utilities: getNumber, getStyle, isElement, copyObj
798
- // -----------------------------
799
- function getNumber(str) {
800
- return (str || '').match(/[+-]?\d+(\.\d+)?/g);
801
- }
802
-
803
- function getStyle(el, cssprop) {
804
- if (el.currentStyle) return el.currentStyle[cssprop];
805
- else if (document.defaultView && document.defaultView.getComputedStyle) return document.defaultView.getComputedStyle(el, "")[cssprop];
806
- else return el.style[cssprop];
807
- }
808
-
809
- // --- Robust DOM Element Validation ---
810
- function isElement(element) {
811
- try {
812
- // Check for standard DOM Element or HTMLDocument
813
- return element instanceof Element || element instanceof HTMLDocument;
814
- } catch (e) {
815
- // Fallback for environments where Element is not defined
816
- return (typeof element === "object") &&
817
- (element.nodeType === 1) &&
818
- (typeof element.nodeName === "string");
819
- }
820
- }
821
-
822
- const copyObj = function(obj) {
823
- let ret;
824
- const assign = function(o, key, target) {
825
- let sub = Object.prototype.toString.call(o[key]);
826
- if (sub === "[object Object]" || sub === "[object Array]") {
827
- target[key] = copyObj(o[key]);
828
- } else {
829
- target[key] = o[key];
830
- }
831
- };
832
-
833
- if (Object.prototype.toString.call(obj) === "[object Object]") {
834
- ret = {};
835
- for (let key in obj) {
836
- if (Object.prototype.hasOwnProperty.call(obj, key)) {
837
- assign(obj, key, ret);
838
- }
839
- }
840
- } else if (Object.prototype.toString.call(obj) === "[object Array]") {
841
- ret = [];
842
- for (let i = 0; i < obj.length; i++) {
843
- assign(obj, i, ret);
844
- }
845
- } else {
846
- ret = obj;
847
- }
848
- return ret;
849
- };
850
-
851
- // Expose both for browser and Node/npm consumers
852
- if (typeof module !== 'undefined' && module.exports) {
853
- module.exports = {
854
- animate,
855
- selectDom,
856
- copyObj
857
- };
858
- }
859
-
860
- if (typeof global !== 'undefined') {
861
- global.animate = animate;
862
- global.selectDom = selectDom;
863
- global.copyObj = copyObj;
864
- }
865
-
866
- })(typeof window !== 'undefined' ? window : this);
46
+ };