fancoolo-fx 1.7.0 → 1.7.1

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 CHANGED
@@ -169,11 +169,36 @@ Set `trigger: 'scroll'` to enable ScrollTrigger. Pass `scrollTrigger: { trigger:
169
169
 
170
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
171
 
172
+ ## Preventing Flash of Unstyled Content (FOUC)
173
+
174
+ FX uses GSAP's `autoAlpha` internally, so elements with `visibility: hidden` are revealed automatically when their animation starts. Add this CSS **before** any content renders to prevent the flash where elements appear briefly before JS loads:
175
+
176
+ ```css
177
+ .fx-text-reveal-pl,.fx-text-reveal-st,.fx-text-reveal,
178
+ .fx-reveal-pl,.fx-reveal-st,.fx-reveal,
179
+ .fx-spin-reveal-pl,.fx-spin-reveal-st,.fx-spin-reveal,
180
+ .fx-bg-reveal-pl,.fx-bg-reveal-st,.fx-bg-reveal,
181
+ .fx-scale-in-pl,.fx-scale-in-st,.fx-scale-in,
182
+ .fx-fade-in-pl,.fx-fade-in-st,.fx-fade-in,
183
+ .fx-blur-in-pl,.fx-blur-in-st,.fx-blur-in,
184
+ .fx-clip-up-pl,.fx-clip-up-st,.fx-clip-up,
185
+ .fx-clip-down-pl,.fx-clip-down-st,.fx-clip-down,
186
+ .fx-tilt-in-st,.fx-tilt-in,
187
+ .fx-type-writer-pl,.fx-type-writer-st,.fx-type-writer,
188
+ .fx-draw-svg-pl,.fx-draw-svg-st,.fx-draw-svg,.fx-draw-svg-scrub,
189
+ .fx-split-words-pl,.fx-split-words-st,.fx-split-words,
190
+ .fx-slide-left-pl,.fx-slide-left-st,.fx-slide-left,
191
+ .fx-slide-right-pl,.fx-slide-right-st,.fx-slide-right{visibility:hidden}
192
+ ```
193
+
194
+ **WordPress:** The plugin injects this CSS automatically in the `<head>` — no action needed.
195
+
172
196
  ## Using in a New Project
173
197
 
174
198
  1. Copy this repo (or `npm install`)
175
199
  2. Add the 4 script tags (gsap, ScrollTrigger, SplitText, fx.js)
176
- 3. Add `.fx-*` classes in your HTML
200
+ 3. Add the FOUC prevention CSS in your `<head>` (see above)
201
+ 4. Add `.fx-*` classes in your HTML
177
202
 
178
203
  For compound sequences, create a project-specific JS file loaded after fx.js:
179
204
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fancoolo-fx",
3
- "version": "1.7.0",
3
+ "version": "1.7.1",
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/",
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.1 =
72
+ * Fix: FOUC prevention — all effects now use autoAlpha instead of opacity, elements start with visibility:hidden and are revealed by GSAP
73
+ * New: WordPress plugin injects visibility:hidden CSS automatically in the head
74
+ * New: Text-based effects set parent visibility before animating children to prevent flash
75
+ * Enhancement: clipUp/clipDown now include autoAlpha for consistent FOUC handling
76
+
71
77
  = 1.7.0 =
72
78
  * Fix: Text-based effects (textReveal, typeWriter, splitWords) now re-split on browser resize — line breaks stay correct at every viewport width
73
79
  * New: SplitText is reverted after one-shot animations complete — text reflows naturally without extra DOM wrappers
package/src/fx.js CHANGED
@@ -206,6 +206,7 @@
206
206
  opts = opts || {};
207
207
  var o = resolveOptions(el, 'textReveal', opts);
208
208
 
209
+ gsap.set(el, { visibility: 'inherit' });
209
210
  var split = new SplitText(el, { type: 'lines', linesClass: 'line-wrapper' });
210
211
 
211
212
  split.lines.forEach(function (line) {
@@ -220,7 +221,7 @@
220
221
 
221
222
  var tweenVars = {
222
223
  y: '100%',
223
- opacity: 0,
224
+ autoAlpha: 0,
224
225
  duration: o.duration,
225
226
  ease: o.ease,
226
227
  stagger: o.stagger,
@@ -248,7 +249,7 @@
248
249
 
249
250
  var tweenVars = {
250
251
  y: opts.y != null ? opts.y : 80,
251
- opacity: 0,
252
+ autoAlpha: 0,
252
253
  duration: o.duration,
253
254
  ease: o.ease,
254
255
  delay: o.delay,
@@ -268,7 +269,7 @@
268
269
  var tweenVars = {
269
270
  rotation: opts.rotation != null ? opts.rotation : -30,
270
271
  scale: opts.scale != null ? opts.scale : 0.9,
271
- opacity: 0,
272
+ autoAlpha: 0,
272
273
  duration: o.duration,
273
274
  ease: o.ease,
274
275
  delay: o.delay,
@@ -287,7 +288,7 @@
287
288
 
288
289
  var tweenVars = {
289
290
  y: '100%',
290
- opacity: 0,
291
+ autoAlpha: 0,
291
292
  duration: o.duration,
292
293
  ease: o.ease,
293
294
  delay: o.delay,
@@ -306,7 +307,7 @@
306
307
 
307
308
  var tweenVars = {
308
309
  scale: opts.scale != null ? opts.scale : 0.92,
309
- opacity: 0,
310
+ autoAlpha: 0,
310
311
  duration: o.duration,
311
312
  ease: o.ease,
312
313
  delay: o.delay,
@@ -324,7 +325,7 @@
324
325
  var o = resolveOptions(el, 'fadeIn', opts);
325
326
 
326
327
  var tweenVars = {
327
- opacity: 0,
328
+ autoAlpha: 0,
328
329
  scale: opts.scale != null ? opts.scale : 0.95,
329
330
  duration: o.duration,
330
331
  ease: o.ease,
@@ -344,7 +345,7 @@
344
345
 
345
346
  var tweenVars = {
346
347
  filter: 'blur(' + (opts.blur != null ? opts.blur : 12) + 'px)',
347
- opacity: 0,
348
+ autoAlpha: 0,
348
349
  duration: o.duration,
349
350
  ease: o.ease,
350
351
  delay: o.delay,
@@ -363,6 +364,7 @@
363
364
 
364
365
  var tweenVars = {
365
366
  clipPath: 'inset(100% 0 0 0)',
367
+ autoAlpha: 0,
366
368
  duration: o.duration,
367
369
  ease: o.ease,
368
370
  delay: o.delay,
@@ -381,6 +383,7 @@
381
383
 
382
384
  var tweenVars = {
383
385
  clipPath: 'inset(0 0 100% 0)',
386
+ autoAlpha: 0,
384
387
  duration: o.duration,
385
388
  ease: o.ease,
386
389
  delay: o.delay,
@@ -400,13 +403,13 @@
400
403
  gsap.fromTo(el, {
401
404
  rotationX: opts.rotationX != null ? opts.rotationX : 45,
402
405
  scale: opts.scale != null ? opts.scale : 0.8,
403
- opacity: opts.opacity != null ? opts.opacity : 0,
406
+ autoAlpha: opts.opacity != null ? opts.opacity : 0,
404
407
  transformPerspective: opts.perspective != null ? opts.perspective : 1000,
405
408
  transformOrigin: opts.transformOrigin || 'center bottom',
406
409
  }, {
407
410
  rotationX: 0,
408
411
  scale: 1,
409
- opacity: 1,
412
+ autoAlpha: 1,
410
413
  transformPerspective: 1000,
411
414
  ease: o.ease,
412
415
  scrollTrigger: {
@@ -422,14 +425,15 @@
422
425
  opts = opts || {};
423
426
  var o = resolveOptions(el, 'typeWriter', opts);
424
427
 
428
+ gsap.set(el, { visibility: 'inherit' });
425
429
  var split = new SplitText(el, { type: 'chars' });
426
- gsap.set(split.chars, { opacity: 0 });
430
+ gsap.set(split.chars, { autoAlpha: 0 });
427
431
 
428
432
  var isOneShot = !(opts.trigger === 'scroll' || opts.scrollTrigger) || config.scrollOnce;
429
433
  var entry = { el: el, split: split, tween: null, effectFn: typeWriter, opts: opts };
430
434
 
431
435
  var tweenVars = {
432
- opacity: 1,
436
+ autoAlpha: 1,
433
437
  duration: o.duration,
434
438
  ease: o.ease,
435
439
  stagger: o.stagger,
@@ -454,6 +458,7 @@
454
458
  function drawSVG(el, opts) {
455
459
  opts = opts || {};
456
460
  var o = resolveOptions(el, 'drawSVG', opts);
461
+ gsap.set(el, { visibility: 'inherit' });
457
462
 
458
463
  var paths = el.tagName === 'path' || el.tagName === 'line' || el.tagName === 'circle' || el.tagName === 'polyline'
459
464
  ? [el]
@@ -521,6 +526,7 @@
521
526
  opts = opts || {};
522
527
  var o = resolveOptions(el, 'splitWords', opts);
523
528
 
529
+ gsap.set(el, { visibility: 'inherit' });
524
530
  var split = new SplitText(el, { type: 'words' });
525
531
 
526
532
  var isOneShot = !(opts.trigger === 'scroll' || opts.scrollTrigger) || config.scrollOnce;
@@ -528,7 +534,7 @@
528
534
 
529
535
  var tweenVars = {
530
536
  y: opts.y != null ? opts.y : 30,
531
- opacity: 0,
537
+ autoAlpha: 0,
532
538
  duration: o.duration,
533
539
  ease: o.ease,
534
540
  stagger: o.stagger,
@@ -558,7 +564,7 @@
558
564
 
559
565
  var tweenVars = {
560
566
  x: direction === 'left' ? -xVal : xVal,
561
- opacity: 0,
567
+ autoAlpha: 0,
562
568
  duration: o.duration,
563
569
  ease: o.ease,
564
570
  delay: o.delay,