(()=>{ function animate(el){ var numEl = el.querySelector('.art-counter__number'); if(!numEl) return; var to = parseFloat(el.getAttribute('data-target')||'0'); var dur = parseInt(el.getAttribute('data-duration')||'1200',10); var dec = parseInt(el.getAttribute('data-decimals')||'0',10); var start = null, from = 0; function step(ts){ if(!start) start = ts; var t = Math.min(1, (ts - start)/Math.max(200,dur)); var val = from + (to-from)*t; numEl.textContent = val.toFixed(dec); if(t < 1){ requestAnimationFrame(step); } else { el.dataset.played = '1'; // mark completed } } requestAnimationFrame(step); } function inViewport(el){ var r = el.getBoundingClientRect(); return r.top < (window.innerHeight||document.documentElement.clientHeight) && r.bottom > 0; } function wire(el){ // Play-once is now forced by markup; treat any value as on var playOnce = true; if (el.dataset._wired === '1') return; el.dataset._wired = '1'; function triggerOnce(io){ // If we already started or played, skip if (el.dataset.started === '1' || el.dataset.played === '1') { if (io) io.unobserve(el); return; } // mark as started immediately to prevent re-triggers el.dataset.started = '1'; animate(el); if (io) io.unobserve(el); } if ('IntersectionObserver' in window){ var io = new IntersectionObserver(function(entries){ entries.forEach(function(entry){ if (entry.isIntersecting){ triggerOnce(io); } }); }, { threshold: 0.2 }); io.observe(el); // If already in view on load, fire immediately if (inViewport(el)){ triggerOnce(io); } } else { // No IO support: trigger immediately triggerOnce(); } } function init(scope){ var root = scope || document; var nodes = root.querySelectorAll('.wp-block-artversion-blocks-art-counter .art-counter'); nodes.forEach(wire); } if (document.readyState === 'loading'){ document.addEventListener('DOMContentLoaded', function(){ init(); }); } else { init(); } if (window.wp && wp.domReady){ wp.domReady(function(){ init(document); }); } })();; // Robust GSAP Text Animations for art-gsap-text-block (function () { const WRAPPER = '.art-gsap-text'; // Retry helper in case optimizers defer scripts function whenLibsReady(cb, tries = 0) { const ready = typeof window.gsap !== 'undefined' && typeof window.ScrollTrigger !== 'undefined' && typeof window.SplitType !== 'undefined'; if (ready) { try { window.gsap.registerPlugin(window.ScrollTrigger); } catch (e) {} cb(); return; } if (tries > 40) return; // ~4s max setTimeout(() => whenLibsReady(cb, tries + 1), 100); } function findHeading(root) { return root.querySelector('h1,h2,h3,h4,h5,h6,.wp-block-heading'); } function findParagraph(root) { return root.querySelector('p'); } function applyAttrs(node, anim) { if (!node || node.dataset.astbDone === '1') return; node.setAttribute('text-split', ''); if (anim && anim !== 'none') node.setAttribute(anim, ''); node.style.opacity = 1; node.dataset.astbDone = '1'; } function createScrollTrigger(triggerElement, timeline) { const markers = triggerElement.closest(WRAPPER)?.getAttribute('data-markers') === 'true'; // Play once on first enter, then kill the trigger window.ScrollTrigger.create({ trigger: triggerElement, start: 'top 80%', markers, onEnter: (self) => { if (timeline && typeof timeline.play === 'function') { timeline.play(0); } if (self && typeof self.kill === 'function') self.kill(); else if (self && typeof self.disable === 'function') self.disable(); }, }); } function initBlock(wrapper) { const titleAnim = wrapper.getAttribute('data-title-anim') || 'none'; const paraAnim = wrapper.getAttribute('data-para-anim') || 'none'; // Prefer groups if present, otherwise scan the wrapper const headingHost = wrapper.querySelector('.agtsb-heading') || wrapper; const paragraphHost = wrapper.querySelector('.agtsb-paragraph') || wrapper; applyAttrs(findHeading(headingHost), titleAnim); applyAttrs(findParagraph(paragraphHost), paraAnim); // Split after attributes are set wrapper.querySelectorAll('[text-split]').forEach((el) => { if (el.dataset.astbSplit === '1') return; new window.SplitType(el, { types: 'words, chars', tagName: 'span' }); el.dataset.astbSplit = '1'; }); // Wire timelines const gsap = window.gsap; wrapper.querySelectorAll('[words-slide-up]').forEach((el) => { const tl = gsap.timeline({ paused: true }); tl.from(el.querySelectorAll('.word'), { opacity: 0, yPercent: 100, duration: 0.5, ease: 'back.out(2)', stagger: { amount: 0.5 }, }); createScrollTrigger(el, tl); }); wrapper.querySelectorAll('[words-rotate-in]').forEach((el) => { const tl = gsap.timeline({ paused: true }); const words = el.querySelectorAll('.word'); tl.set(words, { transformPerspective: 1000 }); tl.from(words, { rotationX: -90, duration: 0.6, ease: 'power2.out', stagger: { amount: 0.6 }, }); createScrollTrigger(el, tl); }); wrapper.querySelectorAll('[words-slide-from-right]').forEach((el) => { const tl = gsap.timeline({ paused: true }); tl.from(el.querySelectorAll('.word'), { opacity: 0, x: '1em', duration: 0.6, ease: 'power2.out', stagger: { amount: 0.2 }, }); createScrollTrigger(el, tl); }); wrapper.querySelectorAll('[letters-slide-up]').forEach((el) => { const tl = gsap.timeline({ paused: true }); tl.from(el.querySelectorAll('.char'), { yPercent: 100, duration: 0.35, ease: 'power1.out', stagger: { amount: 0.6 }, }); createScrollTrigger(el, tl); }); wrapper.querySelectorAll('[letters-slide-down]').forEach((el) => { const tl = gsap.timeline({ paused: true }); tl.from(el.querySelectorAll('.char'), { yPercent: -120, duration: 0.3, ease: 'power1.out', stagger: { amount: 0.7 }, }); createScrollTrigger(el, tl); }); wrapper.querySelectorAll('[letters-fade-in]').forEach((el) => { const tl = gsap.timeline({ paused: true }); tl.from(el.querySelectorAll('.char'), { opacity: 0, duration: 0.2, ease: 'power1.out', stagger: { amount: 0.8 }, }); createScrollTrigger(el, tl); }); wrapper.querySelectorAll('[letters-fade-in-random]').forEach((el) => { const tl = gsap.timeline({ paused: true }); tl.from(el.querySelectorAll('.char'), { opacity: 0, duration: 0.05, ease: 'power1.out', stagger: { amount: 0.4, from: 'random' }, }); createScrollTrigger(el, tl); }); wrapper.querySelectorAll('[scrub-each-word]').forEach((el) => { const markers = wrapper.getAttribute('data-markers') === 'true'; const tl = gsap.timeline({ scrollTrigger: { trigger: el, start: 'top 90%', end: 'top center', scrub: true, markers, }, }); tl.from(el.querySelectorAll('.word'), { opacity: 0.2, duration: 0.2, ease: 'power1.out', stagger: { each: 0.4 }, }); }); // Make sure split elements are visible wrapper.querySelectorAll('[text-split]').forEach((el) => { gsap.set(el, { opacity: 1 }); }); } function boot() { document .querySelectorAll(WRAPPER) .forEach((wrap) => initBlock(wrap)); } // Wait for libs, then init if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', () => whenLibsReady(boot) ); } else { whenLibsReady(boot); } })(); ;