fancoolo-fx 1.4.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/fx.js +208 -6
package/package.json
CHANGED
package/src/fx.js
CHANGED
|
@@ -74,6 +74,19 @@
|
|
|
74
74
|
* }
|
|
75
75
|
*/
|
|
76
76
|
tagMap: null,
|
|
77
|
+
|
|
78
|
+
/** Disable all animations on mobile (window.innerWidth <= mobileBreakpoint). */
|
|
79
|
+
disableMobile: false,
|
|
80
|
+
mobileBreakpoint: 768,
|
|
81
|
+
|
|
82
|
+
/** Multiply all animation durations globally (e.g. 0.5 = half speed, 2 = double). */
|
|
83
|
+
speedMultiplier: 1,
|
|
84
|
+
|
|
85
|
+
/** Skip all animations when OS prefers-reduced-motion is enabled. */
|
|
86
|
+
respectReducedMotion: true,
|
|
87
|
+
|
|
88
|
+
/** CSS selector string — matching elements are never animated. */
|
|
89
|
+
excludeSelectors: '',
|
|
77
90
|
};
|
|
78
91
|
|
|
79
92
|
// ── Defaults ────────────────────────────────
|
|
@@ -89,6 +102,11 @@
|
|
|
89
102
|
clipUp: { duration: 1, ease: 'power3.inOut' },
|
|
90
103
|
clipDown: { duration: 1, ease: 'power3.inOut' },
|
|
91
104
|
tiltIn: { duration: 1.4, ease: 'power3.out' },
|
|
105
|
+
typeWriter: { duration: 0.05, ease: 'none', stagger: 0.03 },
|
|
106
|
+
drawSVG: { duration: 2, ease: 'power2.inOut' },
|
|
107
|
+
parallax: { duration: 1, ease: 'none' },
|
|
108
|
+
splitWords: { duration: 0.8, ease: 'power3.out', stagger: 0.05 },
|
|
109
|
+
slideIn: { duration: 1, ease: 'power3.out' },
|
|
92
110
|
};
|
|
93
111
|
|
|
94
112
|
// ── Helpers ──────────────────────────────────
|
|
@@ -108,8 +126,12 @@
|
|
|
108
126
|
|
|
109
127
|
function resolveOptions(el, effectName, overrides) {
|
|
110
128
|
var d = EFFECT_DEFAULTS[effectName];
|
|
129
|
+
var dur = getClassModifier(el, 'duration', overrides.duration != null ? overrides.duration : d.duration);
|
|
130
|
+
if (config.speedMultiplier && config.speedMultiplier !== 1) {
|
|
131
|
+
dur = dur * config.speedMultiplier;
|
|
132
|
+
}
|
|
111
133
|
return {
|
|
112
|
-
duration:
|
|
134
|
+
duration: dur,
|
|
113
135
|
ease: getClassModifier(el, 'ease', overrides.ease != null ? overrides.ease : d.ease),
|
|
114
136
|
stagger: getClassModifier(el, 'stagger', overrides.stagger != null ? overrides.stagger : (d.stagger || 0)),
|
|
115
137
|
delay: getClassModifier(el, 'delay', overrides.delay != null ? overrides.delay : 0),
|
|
@@ -348,6 +370,137 @@
|
|
|
348
370
|
});
|
|
349
371
|
}
|
|
350
372
|
|
|
373
|
+
function typeWriter(el, opts) {
|
|
374
|
+
opts = opts || {};
|
|
375
|
+
var o = resolveOptions(el, 'typeWriter', opts);
|
|
376
|
+
|
|
377
|
+
var split = new SplitText(el, { type: 'chars' });
|
|
378
|
+
gsap.set(split.chars, { opacity: 0 });
|
|
379
|
+
|
|
380
|
+
var tweenVars = {
|
|
381
|
+
opacity: 1,
|
|
382
|
+
duration: o.duration,
|
|
383
|
+
ease: o.ease,
|
|
384
|
+
stagger: o.stagger,
|
|
385
|
+
delay: o.delay,
|
|
386
|
+
};
|
|
387
|
+
|
|
388
|
+
if (opts.trigger === 'scroll' || opts.scrollTrigger) {
|
|
389
|
+
tweenVars.scrollTrigger = buildScrollTrigger(el, opts.scrollTrigger || {});
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
gsap.to(split.chars, tweenVars);
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
function drawSVG(el, opts) {
|
|
396
|
+
opts = opts || {};
|
|
397
|
+
var o = resolveOptions(el, 'drawSVG', opts);
|
|
398
|
+
|
|
399
|
+
var paths = el.tagName === 'path' || el.tagName === 'line' || el.tagName === 'circle' || el.tagName === 'polyline'
|
|
400
|
+
? [el]
|
|
401
|
+
: el.querySelectorAll('path, line, circle, polyline, polygon, ellipse, rect');
|
|
402
|
+
|
|
403
|
+
if (!paths.length) return;
|
|
404
|
+
|
|
405
|
+
Array.prototype.forEach.call(paths, function(path) {
|
|
406
|
+
if (typeof path.getTotalLength === 'function') {
|
|
407
|
+
var len = path.getTotalLength();
|
|
408
|
+
gsap.set(path, { strokeDasharray: len, strokeDashoffset: len });
|
|
409
|
+
}
|
|
410
|
+
});
|
|
411
|
+
|
|
412
|
+
// Scrub mode: SVG draws as user scrolls (class fx-scrub-[0.6] or opts.scrub)
|
|
413
|
+
var scrubVal = getClassModifier(el, 'scrub', opts.scrub != null ? opts.scrub : null);
|
|
414
|
+
if (scrubVal !== null) {
|
|
415
|
+
gsap.to(paths, {
|
|
416
|
+
strokeDashoffset: 0,
|
|
417
|
+
ease: o.ease,
|
|
418
|
+
scrollTrigger: {
|
|
419
|
+
trigger: (opts.scrollTrigger && opts.scrollTrigger.trigger) || el,
|
|
420
|
+
start: config.scrollStart || 'top 85%',
|
|
421
|
+
end: opts.end || 'top 20%',
|
|
422
|
+
scrub: scrubVal === true || scrubVal === 'true' ? true : scrubVal,
|
|
423
|
+
},
|
|
424
|
+
});
|
|
425
|
+
return;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
var tweenVars = {
|
|
429
|
+
strokeDashoffset: 0,
|
|
430
|
+
duration: o.duration,
|
|
431
|
+
ease: o.ease,
|
|
432
|
+
delay: o.delay,
|
|
433
|
+
};
|
|
434
|
+
|
|
435
|
+
if (opts.trigger === 'scroll' || opts.scrollTrigger) {
|
|
436
|
+
tweenVars.scrollTrigger = buildScrollTrigger(el, opts.scrollTrigger || {});
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
gsap.to(paths, tweenVars);
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
function parallax(el, opts) {
|
|
443
|
+
opts = opts || {};
|
|
444
|
+
// Read y from modifier class fx-y-[80] or opts or default 50
|
|
445
|
+
var yShift = getClassModifier(el, 'y', opts.y != null ? opts.y : 50);
|
|
446
|
+
|
|
447
|
+
gsap.fromTo(el, {
|
|
448
|
+
y: -yShift,
|
|
449
|
+
}, {
|
|
450
|
+
y: yShift,
|
|
451
|
+
ease: 'none',
|
|
452
|
+
scrollTrigger: {
|
|
453
|
+
trigger: (opts.scrollTrigger && opts.scrollTrigger.trigger) || el,
|
|
454
|
+
start: config.scrollStart || 'top 85%',
|
|
455
|
+
end: opts.end || 'bottom top',
|
|
456
|
+
scrub: opts.scrub != null ? opts.scrub : true,
|
|
457
|
+
},
|
|
458
|
+
});
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
function splitWords(el, opts) {
|
|
462
|
+
opts = opts || {};
|
|
463
|
+
var o = resolveOptions(el, 'splitWords', opts);
|
|
464
|
+
|
|
465
|
+
var split = new SplitText(el, { type: 'words' });
|
|
466
|
+
|
|
467
|
+
var tweenVars = {
|
|
468
|
+
y: opts.y != null ? opts.y : 30,
|
|
469
|
+
opacity: 0,
|
|
470
|
+
duration: o.duration,
|
|
471
|
+
ease: o.ease,
|
|
472
|
+
stagger: o.stagger,
|
|
473
|
+
delay: o.delay,
|
|
474
|
+
};
|
|
475
|
+
|
|
476
|
+
if (opts.trigger === 'scroll' || opts.scrollTrigger) {
|
|
477
|
+
tweenVars.scrollTrigger = buildScrollTrigger(el, opts.scrollTrigger || {});
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
gsap.from(split.words, tweenVars);
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
function slideIn(el, opts) {
|
|
484
|
+
opts = opts || {};
|
|
485
|
+
var o = resolveOptions(el, 'slideIn', opts);
|
|
486
|
+
var direction = opts.direction || 'left';
|
|
487
|
+
var xVal = opts.x != null ? opts.x : 100;
|
|
488
|
+
|
|
489
|
+
var tweenVars = {
|
|
490
|
+
x: direction === 'left' ? -xVal : xVal,
|
|
491
|
+
opacity: 0,
|
|
492
|
+
duration: o.duration,
|
|
493
|
+
ease: o.ease,
|
|
494
|
+
delay: o.delay,
|
|
495
|
+
};
|
|
496
|
+
|
|
497
|
+
if (opts.trigger === 'scroll' || opts.scrollTrigger) {
|
|
498
|
+
tweenVars.scrollTrigger = buildScrollTrigger(el, opts.scrollTrigger || {});
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
gsap.from(el, tweenVars);
|
|
502
|
+
}
|
|
503
|
+
|
|
351
504
|
// ── Class-to-effect mapping ─────────────────
|
|
352
505
|
|
|
353
506
|
var effects = {
|
|
@@ -360,6 +513,11 @@
|
|
|
360
513
|
'fx-blur-in': blurIn,
|
|
361
514
|
'fx-clip-up': clipUp,
|
|
362
515
|
'fx-clip-down': clipDown,
|
|
516
|
+
'fx-type-writer': typeWriter,
|
|
517
|
+
'fx-draw-svg': drawSVG,
|
|
518
|
+
'fx-split-words': splitWords,
|
|
519
|
+
'fx-slide-left': function(el, opts) { opts = opts || {}; opts.direction = 'left'; slideIn(el, opts); },
|
|
520
|
+
'fx-slide-right': function(el, opts) { opts = opts || {}; opts.direction = 'right'; slideIn(el, opts); },
|
|
363
521
|
};
|
|
364
522
|
|
|
365
523
|
var effectsByName = {
|
|
@@ -373,6 +531,11 @@
|
|
|
373
531
|
clipUp: clipUp,
|
|
374
532
|
clipDown: clipDown,
|
|
375
533
|
tiltIn: tiltIn,
|
|
534
|
+
typeWriter: typeWriter,
|
|
535
|
+
drawSVG: drawSVG,
|
|
536
|
+
parallax: parallax,
|
|
537
|
+
splitWords: splitWords,
|
|
538
|
+
slideIn: slideIn,
|
|
376
539
|
};
|
|
377
540
|
|
|
378
541
|
// ── Helpers ──────────────────────────────────
|
|
@@ -403,6 +566,11 @@
|
|
|
403
566
|
return str.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
|
|
404
567
|
}
|
|
405
568
|
|
|
569
|
+
function isExcluded(el) {
|
|
570
|
+
if (!config.excludeSelectors) return false;
|
|
571
|
+
try { return el.matches(config.excludeSelectors); } catch (e) { return false; }
|
|
572
|
+
}
|
|
573
|
+
|
|
406
574
|
// ── Init ────────────────────────────────────
|
|
407
575
|
|
|
408
576
|
function init() {
|
|
@@ -414,6 +582,7 @@
|
|
|
414
582
|
// 1. Page-load variant: .fx-<name>-pl
|
|
415
583
|
var plGroups = groupByParent(document.querySelectorAll('.' + name + '-pl'));
|
|
416
584
|
plGroups.forEach(function (group) {
|
|
585
|
+
group = group.filter(function (el) { return !isExcluded(el); });
|
|
417
586
|
group.forEach(function (el, i) {
|
|
418
587
|
fn(el, { delay: i * 0.15 });
|
|
419
588
|
processed.add(el);
|
|
@@ -426,6 +595,7 @@
|
|
|
426
595
|
var stEls = document.querySelectorAll('.' + name + '-st');
|
|
427
596
|
var stGroups = groupByParent(stEls);
|
|
428
597
|
stGroups.forEach(function (group) {
|
|
598
|
+
group = group.filter(function (el) { return !isExcluded(el); });
|
|
429
599
|
group.forEach(function (el, i) {
|
|
430
600
|
fn(el, {
|
|
431
601
|
trigger: 'scroll',
|
|
@@ -442,7 +612,7 @@
|
|
|
442
612
|
if (config.sectionSelector) {
|
|
443
613
|
document.querySelectorAll(config.sectionSelector).forEach(function (section) {
|
|
444
614
|
var bareEls = Array.from(section.querySelectorAll('.' + name))
|
|
445
|
-
.filter(function (el) { return !processed.has(el); });
|
|
615
|
+
.filter(function (el) { return !processed.has(el) && !isExcluded(el); });
|
|
446
616
|
if (bareEls.length === 0) return;
|
|
447
617
|
|
|
448
618
|
var groups = groupByParent(bareEls);
|
|
@@ -460,14 +630,25 @@
|
|
|
460
630
|
}
|
|
461
631
|
});
|
|
462
632
|
|
|
463
|
-
// 4.
|
|
464
|
-
// Processed before tagMap so tilt elements aren't grabbed by tagMap first.
|
|
633
|
+
// 4. Scrub-based effects — always scroll-linked, processed before tagMap.
|
|
465
634
|
document.querySelectorAll('.fx-tilt-in-st, .fx-tilt-in-pl, .fx-tilt-in').forEach(function (el) {
|
|
466
|
-
if (!processed.has(el)) {
|
|
635
|
+
if (!processed.has(el) && !isExcluded(el)) {
|
|
467
636
|
tiltIn(el);
|
|
468
637
|
processed.add(el);
|
|
469
638
|
}
|
|
470
639
|
});
|
|
640
|
+
document.querySelectorAll('.fx-parallax-st, .fx-parallax-pl, .fx-parallax').forEach(function (el) {
|
|
641
|
+
if (!processed.has(el) && !isExcluded(el)) {
|
|
642
|
+
parallax(el);
|
|
643
|
+
processed.add(el);
|
|
644
|
+
}
|
|
645
|
+
});
|
|
646
|
+
document.querySelectorAll('.fx-draw-svg-scrub').forEach(function (el) {
|
|
647
|
+
if (!processed.has(el) && !isExcluded(el)) {
|
|
648
|
+
drawSVG(el, { scrub: getClassModifier(el, 'scrub', 0.6) });
|
|
649
|
+
processed.add(el);
|
|
650
|
+
}
|
|
651
|
+
});
|
|
471
652
|
|
|
472
653
|
// 5. Tag-based auto-animation inside sections
|
|
473
654
|
if (config.tagMap && config.sectionSelector) {
|
|
@@ -478,7 +659,7 @@
|
|
|
478
659
|
if (!fn) return;
|
|
479
660
|
|
|
480
661
|
var els = Array.from(section.querySelectorAll(selector))
|
|
481
|
-
.filter(function (el) { return !processed.has(el); });
|
|
662
|
+
.filter(function (el) { return !processed.has(el) && !isExcluded(el); });
|
|
482
663
|
if (els.length === 0) return;
|
|
483
664
|
|
|
484
665
|
var groups = groupByParent(els);
|
|
@@ -544,10 +725,26 @@
|
|
|
544
725
|
if (pre.scrollStart !== undefined) config.scrollStart = pre.scrollStart;
|
|
545
726
|
if (pre.scrollOnce !== undefined) config.scrollOnce = pre.scrollOnce;
|
|
546
727
|
if (pre.tagMap !== undefined) config.tagMap = pre.tagMap;
|
|
728
|
+
if (pre.disableMobile !== undefined) config.disableMobile = pre.disableMobile;
|
|
729
|
+
if (pre.mobileBreakpoint !== undefined) config.mobileBreakpoint = pre.mobileBreakpoint;
|
|
730
|
+
if (pre.speedMultiplier !== undefined) config.speedMultiplier = pre.speedMultiplier;
|
|
731
|
+
if (pre.respectReducedMotion !== undefined) config.respectReducedMotion = pre.respectReducedMotion;
|
|
732
|
+
if (pre.excludeSelectors !== undefined) config.excludeSelectors = pre.excludeSelectors;
|
|
547
733
|
}
|
|
548
734
|
|
|
549
735
|
function boot() {
|
|
550
736
|
applyPreConfig();
|
|
737
|
+
|
|
738
|
+
// Skip animations if OS reduced motion is enabled
|
|
739
|
+
if (config.respectReducedMotion && window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
|
|
740
|
+
return;
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
// Skip animations on mobile
|
|
744
|
+
if (config.disableMobile && window.innerWidth <= config.mobileBreakpoint) {
|
|
745
|
+
return;
|
|
746
|
+
}
|
|
747
|
+
|
|
551
748
|
init();
|
|
552
749
|
}
|
|
553
750
|
|
|
@@ -571,6 +768,11 @@
|
|
|
571
768
|
clipUp: clipUp,
|
|
572
769
|
clipDown: clipDown,
|
|
573
770
|
tiltIn: tiltIn,
|
|
771
|
+
typeWriter: typeWriter,
|
|
772
|
+
drawSVG: drawSVG,
|
|
773
|
+
parallax: parallax,
|
|
774
|
+
splitWords: splitWords,
|
|
775
|
+
slideIn: slideIn,
|
|
574
776
|
init: init,
|
|
575
777
|
};
|
|
576
778
|
})();
|