fancoolo-fx 1.6.0 → 1.7.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/README.md +10 -0
- package/package.json +3 -3
- package/readme.txt +6 -0
- package/src/fx.js +80 -9
- package/.distignore +0 -15
package/README.md
CHANGED
|
@@ -159,6 +159,16 @@ All functions accept `(element, options)`:
|
|
|
159
159
|
|
|
160
160
|
Set `trigger: 'scroll'` to enable ScrollTrigger. Pass `scrollTrigger: { trigger: someEl }` to use a different trigger element.
|
|
161
161
|
|
|
162
|
+
### Utility Methods
|
|
163
|
+
|
|
164
|
+
| Method | Description |
|
|
165
|
+
|--------|-------------|
|
|
166
|
+
| `FX.init()` | Re-scan DOM and apply animations (for dynamic content) |
|
|
167
|
+
| `FX.refresh()` | Re-split text after layout change (sidebar toggle, font load) |
|
|
168
|
+
| `FX.config` | Global config object |
|
|
169
|
+
|
|
170
|
+
**Resize handling:** Text-based effects (`textReveal`, `typeWriter`, `splitWords`) automatically re-split when the browser width changes. After one-shot animations complete, the SplitText DOM is reverted so text reflows naturally.
|
|
171
|
+
|
|
162
172
|
## Using in a New Project
|
|
163
173
|
|
|
164
174
|
1. Copy this repo (or `npm install`)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fancoolo-fx",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
4
4
|
"description": "A class-driven GSAP animation wrapper for WordPress and static sites.",
|
|
5
5
|
"main": "src/fx.js",
|
|
6
6
|
"homepage": "https://krstivoja.github.io/fancoolo-fx/",
|
|
@@ -14,8 +14,8 @@
|
|
|
14
14
|
"keywords": ["gsap", "animation", "scrolltrigger", "splittext", "wordpress", "gutenberg"],
|
|
15
15
|
"author": "Fancoolo",
|
|
16
16
|
"scripts": {
|
|
17
|
-
"sync": "cp src/fx.js assets/fx.js && cp src/fx.js docs/vendor/fx.js",
|
|
18
|
-
"build": "wp-scripts build src/editor/index.js --output-path=assets/editor",
|
|
17
|
+
"sync": "cp src/fx.js assets/fx.js && cp src/fx.js docs/vendor/fx.js && cp node_modules/gsap/dist/gsap.min.js assets/gsap.min.js && cp node_modules/gsap/dist/ScrollTrigger.min.js assets/ScrollTrigger.min.js && cp node_modules/gsap/dist/SplitText.min.js assets/SplitText.min.js && cp node_modules/gsap/dist/gsap.min.js docs/vendor/gsap.min.js && cp node_modules/gsap/dist/ScrollTrigger.min.js docs/vendor/ScrollTrigger.min.js && cp node_modules/gsap/dist/SplitText.min.js docs/vendor/SplitText.min.js",
|
|
18
|
+
"build": "wp-scripts build src/editor/index.js --output-path=assets/editor && npm run sync",
|
|
19
19
|
"start": "wp-scripts start src/editor/index.js --output-path=assets/editor"
|
|
20
20
|
},
|
|
21
21
|
"license": "ISC",
|
package/readme.txt
CHANGED
|
@@ -68,6 +68,12 @@ Yes. Use the `fx-start-[top center]` modifier class, or set `scrollStart` in the
|
|
|
68
68
|
|
|
69
69
|
== Changelog ==
|
|
70
70
|
|
|
71
|
+
= 1.7.0 =
|
|
72
|
+
* Fix: Text-based effects (textReveal, typeWriter, splitWords) now re-split on browser resize — line breaks stay correct at every viewport width
|
|
73
|
+
* New: SplitText is reverted after one-shot animations complete — text reflows naturally without extra DOM wrappers
|
|
74
|
+
* New: FX.refresh() public method — manually re-split text after layout changes (sidebar toggle, font load)
|
|
75
|
+
* New: Automatic debounced resize handler (200ms, width-only) for pending scroll-triggered text animations
|
|
76
|
+
|
|
71
77
|
= 1.0.0 =
|
|
72
78
|
* Initial release
|
|
73
79
|
* 5 animation effects
|
package/src/fx.js
CHANGED
|
@@ -157,6 +157,49 @@
|
|
|
157
157
|
return st;
|
|
158
158
|
}
|
|
159
159
|
|
|
160
|
+
// ── SplitText resize handling ───────────────
|
|
161
|
+
|
|
162
|
+
var _splitRegistry = [];
|
|
163
|
+
var _lastWidth = window.innerWidth;
|
|
164
|
+
var _resizeTimer;
|
|
165
|
+
|
|
166
|
+
function registerSplit(entry) {
|
|
167
|
+
_splitRegistry.push(entry);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function unregisterSplit(entry) {
|
|
171
|
+
var idx = _splitRegistry.indexOf(entry);
|
|
172
|
+
if (idx > -1) _splitRegistry.splice(idx, 1);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
function refreshSplits() {
|
|
176
|
+
if (_splitRegistry.length === 0) return;
|
|
177
|
+
|
|
178
|
+
var pending = [];
|
|
179
|
+
|
|
180
|
+
for (var i = _splitRegistry.length - 1; i >= 0; i--) {
|
|
181
|
+
var entry = _splitRegistry[i];
|
|
182
|
+
if (entry.tween) entry.tween.kill();
|
|
183
|
+
if (entry.split) entry.split.revert();
|
|
184
|
+
pending.push(entry);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
_splitRegistry.length = 0;
|
|
188
|
+
|
|
189
|
+
pending.forEach(function (entry) {
|
|
190
|
+
entry.effectFn(entry.el, entry.opts);
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
ScrollTrigger.refresh();
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
window.addEventListener('resize', function () {
|
|
197
|
+
if (window.innerWidth === _lastWidth) return;
|
|
198
|
+
_lastWidth = window.innerWidth;
|
|
199
|
+
clearTimeout(_resizeTimer);
|
|
200
|
+
_resizeTimer = setTimeout(refreshSplits, 200);
|
|
201
|
+
});
|
|
202
|
+
|
|
160
203
|
// ── Effects ──────────────────────────────────
|
|
161
204
|
|
|
162
205
|
function textReveal(el, opts) {
|
|
@@ -172,6 +215,9 @@
|
|
|
172
215
|
wrapper.appendChild(line);
|
|
173
216
|
});
|
|
174
217
|
|
|
218
|
+
var isOneShot = !(opts.trigger === 'scroll' || opts.scrollTrigger) || config.scrollOnce;
|
|
219
|
+
var entry = { el: el, split: split, tween: null, effectFn: textReveal, opts: opts };
|
|
220
|
+
|
|
175
221
|
var tweenVars = {
|
|
176
222
|
y: '100%',
|
|
177
223
|
opacity: 0,
|
|
@@ -179,19 +225,21 @@
|
|
|
179
225
|
ease: o.ease,
|
|
180
226
|
stagger: o.stagger,
|
|
181
227
|
delay: o.delay,
|
|
182
|
-
onComplete: function () {
|
|
183
|
-
split.lines.forEach(function (line) {
|
|
184
|
-
line.style.transform = '';
|
|
185
|
-
line.style.opacity = '';
|
|
186
|
-
});
|
|
187
|
-
},
|
|
188
228
|
};
|
|
189
229
|
|
|
230
|
+
if (isOneShot) {
|
|
231
|
+
tweenVars.onComplete = function () {
|
|
232
|
+
split.revert();
|
|
233
|
+
unregisterSplit(entry);
|
|
234
|
+
};
|
|
235
|
+
}
|
|
236
|
+
|
|
190
237
|
if (opts.trigger === 'scroll' || opts.scrollTrigger) {
|
|
191
238
|
tweenVars.scrollTrigger = buildScrollTrigger(el, opts.scrollTrigger || {});
|
|
192
239
|
}
|
|
193
240
|
|
|
194
|
-
gsap.from(split.lines, tweenVars);
|
|
241
|
+
entry.tween = gsap.from(split.lines, tweenVars);
|
|
242
|
+
registerSplit(entry);
|
|
195
243
|
}
|
|
196
244
|
|
|
197
245
|
function reveal(el, opts) {
|
|
@@ -377,6 +425,9 @@
|
|
|
377
425
|
var split = new SplitText(el, { type: 'chars' });
|
|
378
426
|
gsap.set(split.chars, { opacity: 0 });
|
|
379
427
|
|
|
428
|
+
var isOneShot = !(opts.trigger === 'scroll' || opts.scrollTrigger) || config.scrollOnce;
|
|
429
|
+
var entry = { el: el, split: split, tween: null, effectFn: typeWriter, opts: opts };
|
|
430
|
+
|
|
380
431
|
var tweenVars = {
|
|
381
432
|
opacity: 1,
|
|
382
433
|
duration: o.duration,
|
|
@@ -385,11 +436,19 @@
|
|
|
385
436
|
delay: o.delay,
|
|
386
437
|
};
|
|
387
438
|
|
|
439
|
+
if (isOneShot) {
|
|
440
|
+
tweenVars.onComplete = function () {
|
|
441
|
+
split.revert();
|
|
442
|
+
unregisterSplit(entry);
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
|
|
388
446
|
if (opts.trigger === 'scroll' || opts.scrollTrigger) {
|
|
389
447
|
tweenVars.scrollTrigger = buildScrollTrigger(el, opts.scrollTrigger || {});
|
|
390
448
|
}
|
|
391
449
|
|
|
392
|
-
gsap.to(split.chars, tweenVars);
|
|
450
|
+
entry.tween = gsap.to(split.chars, tweenVars);
|
|
451
|
+
registerSplit(entry);
|
|
393
452
|
}
|
|
394
453
|
|
|
395
454
|
function drawSVG(el, opts) {
|
|
@@ -464,6 +523,9 @@
|
|
|
464
523
|
|
|
465
524
|
var split = new SplitText(el, { type: 'words' });
|
|
466
525
|
|
|
526
|
+
var isOneShot = !(opts.trigger === 'scroll' || opts.scrollTrigger) || config.scrollOnce;
|
|
527
|
+
var entry = { el: el, split: split, tween: null, effectFn: splitWords, opts: opts };
|
|
528
|
+
|
|
467
529
|
var tweenVars = {
|
|
468
530
|
y: opts.y != null ? opts.y : 30,
|
|
469
531
|
opacity: 0,
|
|
@@ -473,11 +535,19 @@
|
|
|
473
535
|
delay: o.delay,
|
|
474
536
|
};
|
|
475
537
|
|
|
538
|
+
if (isOneShot) {
|
|
539
|
+
tweenVars.onComplete = function () {
|
|
540
|
+
split.revert();
|
|
541
|
+
unregisterSplit(entry);
|
|
542
|
+
};
|
|
543
|
+
}
|
|
544
|
+
|
|
476
545
|
if (opts.trigger === 'scroll' || opts.scrollTrigger) {
|
|
477
546
|
tweenVars.scrollTrigger = buildScrollTrigger(el, opts.scrollTrigger || {});
|
|
478
547
|
}
|
|
479
548
|
|
|
480
|
-
gsap.from(split.words, tweenVars);
|
|
549
|
+
entry.tween = gsap.from(split.words, tweenVars);
|
|
550
|
+
registerSplit(entry);
|
|
481
551
|
}
|
|
482
552
|
|
|
483
553
|
function slideIn(el, opts) {
|
|
@@ -774,5 +844,6 @@
|
|
|
774
844
|
splitWords: splitWords,
|
|
775
845
|
slideIn: slideIn,
|
|
776
846
|
init: init,
|
|
847
|
+
refresh: refreshSplits,
|
|
777
848
|
};
|
|
778
849
|
})();
|