PageSourceSearch

https://punch-marionnettes.fr/wp-content/themes/revalice/assets/js/blocs.js?ver=1778765178

js punch-marionnettes.fr collected 2026-10-08 07:21:28 UTC 5,147 bytes, 113 lines download raw bytes

1/**
2 * blocs.js — Animations JS spécifiques aux blocs PUNCH Gutenberg
3 *
4 * Anime :
5 *   - .bloc-mots-rotateur__rotateur : glitch + rotation de mots
6 *   - .bloc-mots-rotateur__inner    : déploiement trapèze (scaleY)
7 *   - .bloc-teaser-video__arrow        : déploiement triangle (scaleY)
8 *
9 * Dépend de GSAP + ScrollTrigger (fournis par le parent revalice).
10 */
11(function () {
12    'use strict';
13
14    function init() {
15        if (typeof gsap === 'undefined') return;
16        if (window.matchMedia('(prefers-reduced-motion: reduce)').matches) return;
17
18        // ════════════════════════════════════════════════════════
19        //  1. Rotateur de catégories — effet GLITCH brutaliste
20        // ════════════════════════════════════════════════════════
21        const rotEl = document.querySelector('.bloc-mots-rotateur__rotateur');
22        if (rotEl) {
23            let cats = [];
24            try { cats = JSON.parse(rotEl.dataset.mots || '[]'); } catch (e) {}
25            if (cats.length > 1) {
26                let i = 0;
27                let timer = null;
28                const rand = (min, max) => Math.random() * (max - min) + min;
29
30                function glitchBurst(onDone) {
31                    const tl = gsap.timeline({ onComplete: onDone });
32                    for (let k = 0; k < 5; k++) {
33                        tl.to(rotEl, {
34                            x          : rand(-12, 12),
35                            y          : rand(-4, 4),
36                            skewX      : rand(-8, 8),
37                            opacity    : rand(0.3, 1),
38                            textShadow : `${rand(-5,5).toFixed(1)}px 0 #fff, ${rand(-5,5).toFixed(1)}px 0 #000`,
39                            duration   : 0.05,
40                            ease       : 'none'
41                        });
42                    }
43                    tl.to(rotEl, {
44                        x: 0, y: 0, skewX: 0, opacity: 1, textShadow: 'none',
45                        duration: 0.08, ease: 'power2.out'
46                    });
47                }
48
49                function tick() {
50                    glitchBurst(() => {
51                        i = (i + 1) % cats.length;
52                        rotEl.textContent = cats[i];
53                        glitchBurst();
54                    });
55                }
56
57                const io = new IntersectionObserver(entries => {
58                    entries.forEach(entry => {
59                        if (entry.isIntersecting && !timer) {
60                            timer = setInterval(tick, 2800);
61                        } else if (!entry.isIntersecting && timer) {
62                            clearInterval(timer);
63                            timer = null;
64                        }
65                    });
66                }, { threshold: 0.3 });
67                io.observe(rotEl);
68            }
69        }
70
71        // ════════════════════════════════════════════════════════
72        //  2. Trapèze catégories qui se déplie
73        // ════════════════════════════════════════════════════════
74        const trapEl = document.querySelector('.bloc-mots-rotateur__inner');
75        if (trapEl && typeof ScrollTrigger !== 'undefined') {
76            gsap.set(trapEl, { scaleY: 0, transformOrigin: 'top center' });
77            gsap.to(trapEl, {
78                scaleY: 1,
79                duration: 1.4,
80                ease: 'back.out(1.4)',
81                scrollTrigger: {
82                    trigger: trapEl,
83                    start: 'top 80%',
84                    toggleActions: 'play none none reverse'
85                }
86            });
87        }
88
89        // ════════════════════════════════════════════════════════
90        //  3. Triangle teaser qui se déplie
91        // ════════════════════════════════════════════════════════
92        const triEl = document.querySelector('.bloc-teaser-video__arrow');
93        if (triEl && typeof ScrollTrigger !== 'undefined') {
94            gsap.set(triEl, { scaleY: 0, transformOrigin: 'top center' });
95            gsap.to(triEl, {
96                scaleY: 1,
97                duration: 1.4,
98                ease: 'back.out(1.4)',
99                scrollTrigger: {
100                    trigger: triEl,
101                    start: 'top 80%',
102                    toggleActions: 'play none none reverse'
103                }
104            });
105        }
106    }
107
108    if (document.readyState === 'loading') {
109        document.addEventListener('DOMContentLoaded', init);
110    } else {
111        init();
112    }
113})();

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.