select-animation 1.2.5 → 1.3.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 +38 -28
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "select-animation",
3
- "version": "1.2.5",
3
+ "version": "1.3.0",
4
4
  "description": "High-performance JavaScript animation engine for organic & fluid motion",
5
5
  "main": "select-animation.js",
6
6
  "scripts": {
@@ -117,54 +117,37 @@
117
117
  const definitions = arguments;
118
118
  const defsCopy = copyObj(definitions);
119
119
 
120
- return function (targets, primaryParam, runtimeContext) {
121
- let currentTargets, eventCheckResult, tmp, i, propIndex, fromItem, toItem, valFrom, valTo, t;
120
+ return function () {
121
+ let tmp, i, propIndex, fromItem, toItem, valFrom, valTo, t;
122
122
  let grouped = [];
123
- let runtimeGrouped = [];
124
123
  let expectNextGroup = false;
125
124
  let staging = { color: {}, transform: {}, from: {}, to: {} };
126
125
 
126
+ // Process the definitions to map elements to their animation settings
127
127
  buildPlan();
128
128
 
129
129
  function buildPlan() {
130
- if (targets !== undefined) {
131
- if (!Array.isArray(targets)) targets = [targets];
132
- runtimeGrouped = targets;
133
- }
134
-
135
130
  let secondPass = false;
136
131
 
137
132
  for (let c = 0, total = definitions.length; c < total; c++) {
138
133
  propIndex = 0;
134
+ // If current item is an element or an array of elements
139
135
  if (expectNextGroup || Array.isArray(defsCopy[c]) || isElement(defsCopy[c])) {
140
136
  if (secondPass) {
141
137
  Array.isArray(defsCopy[c]) || (defsCopy[c] = [defsCopy[c]]);
142
138
  Array.prototype.push.apply(grouped, defsCopy[c]);
143
139
  }
144
140
  expectNextGroup = false;
145
- } else if (typeof defsCopy[c] === 'object' && defsCopy[c] !== null) {
141
+ }
142
+ // If current item is a configuration object
143
+ else if (typeof defsCopy[c] === 'object' && defsCopy[c] !== null) {
146
144
  if (secondPass) {
147
- if (c === 0) {
148
- for (let u = 0; void 0 !== targets[u]; u++) {
149
- if (typeof targets[u] !== "number") grouped.push(targets[u]);
150
- }
151
- }
152
- if (targets !== undefined) {
153
- for (let j = 0; void 0 !== runtimeGrouped[j]; j++) {
154
- if (typeof runtimeGrouped[j] !== "number") {
155
- eventCheckResult = checkValEvent(runtimeContext, primaryParam, currentTargets, runtimeGrouped[j + 1]);
156
- if (eventCheckResult[0]) currentTargets = eventCheckResult[0];
157
- bindEvent(runtimeGrouped[j], runner(grouped, definitions, defsCopy, c), eventCheckResult[1]);
158
- }
159
- }
160
- } else {
161
- runner(grouped, definitions, defsCopy, c)();
162
- }
145
+ // Execute the runner for the current group and config
146
+ runner(grouped, definitions, defsCopy, c)();
163
147
  } else {
164
148
  expectNextGroup = false;
165
- const fromIsObject = typeof defsCopy[c].from === "object";
166
- const toIsObject = typeof defsCopy[c].to === "object";
167
-
149
+
150
+ // Handle specialized animation types like vibration
168
151
  if (defsCopy[c].typeAnimation === "vibration" && defsCopy[c].vibrationStep === undefined) {
169
152
  defsCopy[c].vibrationStep = 6;
170
153
  } else {
@@ -175,20 +158,26 @@
175
158
  }
176
159
  }
177
160
 
161
+ // Set default loop behavior
178
162
  if (defsCopy[c].boucle && defsCopy[c].boucleType === undefined) {
179
163
  defsCopy[c].boucleType = "return";
180
164
  }
181
165
 
166
+ // Organize properties and prepare "from" and "to" values
182
167
  if (!defsCopy[c].callback &&
183
168
  (Array.isArray(defsCopy[c].property) || (defsCopy[c].property !== undefined && (defsCopy[c].property = [defsCopy[c].property])))) {
184
169
 
185
170
  defsCopy[c].property.forEach(function (propItem) {
171
+ const fromIsObject = typeof defsCopy[c].from === "object";
172
+ const toIsObject = typeof defsCopy[c].to === "object";
173
+
186
174
  if (!fromIsObject) valFrom = defsCopy[c].from;
187
175
  else fromItem = defsCopy[c]["from"][propIndex];
188
176
 
189
177
  if (!toIsObject) valTo = defsCopy[c].to;
190
178
  else toItem = defsCopy[c]["to"][propIndex];
191
179
 
180
+ // Handle complex properties (Colors and Transforms)
192
181
  if (typeof propItem === "object") {
193
182
  let propName = Object.keys(propItem)[0];
194
183
  if (!Array.isArray(propItem[propName])) propItem[propName] = [propItem[propName]];
@@ -204,6 +193,7 @@
204
193
  if (propName.toLowerCase() === "transform") staging[propName][innerProp] = 0;
205
194
  else staging.color[propName][innerProp] = 0;
206
195
 
196
+ // Parse specific sub-properties (like scale, rotate, or RGB channels)
207
197
  if (fromIsObject) {
208
198
  if (fromItem[propName] !== undefined) {
209
199
  if (typeof fromItem[propName] === "number") {
@@ -220,6 +210,7 @@
220
210
  staging["from"][propName][innerProp] = defsCopy[c].from;
221
211
  }
222
212
 
213
+ // Repeat logic for "to" values
223
214
  if (toIsObject) {
224
215
  if (toItem[propName] !== undefined) {
225
216
  if (typeof toItem[propName] === "number") {
@@ -240,6 +231,7 @@
240
231
  propIndex++;
241
232
  }
242
233
  } else {
234
+ // Handle simple numeric CSS properties (e.g., width, opacity)
243
235
  if (fromIsObject) {
244
236
  valFrom = staging["from"][propItem] = fromItem[propItem] !== undefined ? fromItem[propItem] : (fromItem !== undefined ? fromItem : valFrom);
245
237
  } else {
@@ -255,14 +247,19 @@
255
247
  }
256
248
  });
257
249
  }
250
+ // Save the processed plan into a store for runtime use
258
251
  defsCopy[c].storeValueAnim = copyObj(staging);
259
252
  staging = { color: {}, transform: {}, from: {}, to: {} };
260
253
  }
254
+
255
+ // Check if the next argument starts a new animation sequence
261
256
  if (definitions[c + 1] !== undefined && (Array.isArray(definitions[c + 1]) || isElement(definitions[c + 1]))) {
262
257
  expectNextGroup = true;
263
258
  grouped = [];
264
259
  }
265
260
  }
261
+
262
+ // Switch to second pass to execute the runners
266
263
  if (c === total - 1 && !secondPass) {
267
264
  expectNextGroup = false;
268
265
  secondPass = true;
@@ -276,9 +273,11 @@
276
273
  const declaredAnim = defsCopyLocal[configIndex].typeAnimation;
277
274
  let alternateAnim = declaredAnim;
278
275
 
276
+ // Sanitize timing inputs
279
277
  conf.timeline = !isNaN(Number(conf.timeline)) ? Number(conf.timeline) : 0;
280
278
  conf.startafter = !isNaN(Number(conf.startafter)) ? Number(conf.startafter) : 0;
281
279
 
280
+ // Prepare looping and easing alternates
282
281
  if (conf.boucle) {
283
282
  conf.delay = !isNaN(Number(conf.delay)) ? Number(conf.delay) : undefined;
284
283
  if (conf.boucleType === "returnRepeat" || conf.boucleType === "repeatReturn") {
@@ -291,6 +290,7 @@
291
290
  let isPaused = false;
292
291
  let pauseStart;
293
292
 
293
+ // Initialize event-based pause/resume logic if configured
294
294
  if (conf.pause && Array.isArray(conf.pause)) {
295
295
  const eventCfg = conf.pause[1] || "e:click|false";
296
296
  const parts = eventCfg.replace('e:', '').split('|');
@@ -315,6 +315,7 @@
315
315
 
316
316
  const startedAt = Date.now();
317
317
 
318
+ // Initialize state storage for each element in the group
318
319
  group.forEach(function (el, idx) {
319
320
  if (!el.storeTransform) el.storeTransform = copyObj(defsCopyLocal[configIndex].storeValueAnim.transform);
320
321
  if (!el.storeColor) {
@@ -325,16 +326,19 @@
325
326
  });
326
327
  }
327
328
 
329
+ // Start staggered animations if timeline offset exists
328
330
  if (conf.timeline !== 0) {
329
331
  frameRunner([el], idx, conf.timeline * idx + conf.startafter, conf.startafter);
330
332
  }
331
333
  });
332
334
 
335
+ // Start simultaneous animations
333
336
  if (conf.timeline === 0) {
334
337
  frameRunner(group, 0, 0 + conf.startafter, conf.startafter);
335
338
  }
336
339
 
337
340
  function frameRunner(targetArray, idx, timeOffset, startAfter) {
341
+ // Manage animation frame cycles
338
342
  if (conf.animFram) cancelAnimationFrame(conf.animFram[idx]);
339
343
  else conf.animFram = {};
340
344
 
@@ -346,6 +350,7 @@
346
350
  let skipCounter;
347
351
  const sv = iterConf.storeValueAnim;
348
352
 
353
+ // The main animation loop using requestAnimationFrame
349
354
  function loop() {
350
355
  if (isPaused) {
351
356
  conf.animFram[idx] = requestAnimationFrame(loop);
@@ -357,6 +362,7 @@
357
362
  const elapsed = Date.now() - (startedAt + timeOffset + pausedAccum);
358
363
 
359
364
  if (elapsed >= 0) {
365
+ // Logic for handling loops, delays, and reversing (yoyo) animations
360
366
  if (iterConf.boucle) {
361
367
  if (iterConf.delay !== undefined) {
362
368
  delay = iterConf.delay;
@@ -398,7 +404,9 @@
398
404
  iterConf.timeEasing = elapsed < iterConf.duration ? elapsed : iterConf.duration;
399
405
  }
400
406
 
407
+ // Update properties if not in delay phase
401
408
  if (!iterConf.skipDelay || iterConf.skip) {
409
+ // Calculate ease factor (0 to 1)
402
410
  eased = Easing[iterConf.changetypeAnim][0](iterConf.timeEasing, 0, 1, iterConf.duration, iterConf, idx);
403
411
 
404
412
  if (iterConf.callback) {
@@ -406,6 +414,7 @@
406
414
  iterConf.callback(el, eased, iterConf, idx !== index ? idx : index);
407
415
  });
408
416
  } else {
417
+ // Apply styles: Transform, Color, or standard Numeric properties
409
418
  iterConf.property.forEach(function (prop) {
410
419
  css = "";
411
420
  let key = typeof prop === "string" ? prop : Object.keys(prop)[0];
@@ -444,6 +453,7 @@
444
453
  }
445
454
  }
446
455
 
456
+ // Continue the loop if animation is still active or looping
447
457
  if (iterConf.boucle || elapsed < iterConf.duration) {
448
458
  conf.animFram[idx] = requestAnimationFrame(loop);
449
459
  }