//style const toggleButton = document.getElementById("theme-toggle"); const body = document.querySelector("body"); const setTheme = (theme) => { body.dataset.theme = theme; localStorage.setItem("preferred-theme", theme); }; const getTheme = () => { const theme = localStorage.getItem("preferred-theme"); return theme || "dark"; }; const toggleTheme = () => { const currentTheme = body.dataset.theme; const newTheme = currentTheme === "light" ? "dark" : "light"; setTheme(newTheme); }; toggleButton.addEventListener("click", toggleTheme); const preferredTheme = getTheme(); setTheme(preferredTheme); // =============== LOADER =============== function runLoaderAnimation() { const loaderText = document.querySelector(".loader-text"); loaderText.textContent = "0"; gsap.to(loaderText, { duration: 1, textContent: 100, snap: { textContent: 1 }, onComplete: () => { const loaderTl = gsap.timeline(); loaderTl .to(".loader-text", { duration: 1.5, yPercent: -800, opacity: 0, ease: "power3.inOut", }) .to( ".loader", { duration: 1.5, yPercent: 110, ease: "power3.inOut", }, 0 ) .from( ".slogan", { ease: "power3.out", filter: "blur(0.5rem)", yPercent: -100, opacity: 0, }, 0.5 ) .from( ".nav_item", { ease: "power3.out", filter: "blur(0.5rem)", yPercent: -100, opacity: 0, stagger: 0.05, }, 0.55 ); }, }); } runLoaderAnimation(); window.addEventListener("pageshow", function (event) { if (event.persisted) { console.log("Page was restored from bfcache. Resetting and re-running loader."); gsap.set("#logo", { yPercent: 0, filter: "blur(0)", opacity: 1 }); gsap.set(".loader", { yPercent: -101 }); } }); // =============== STRONA: PRZEJŚCIA MIĘDZY LINKAMI =============== (function initPageTransitions() { document.querySelectorAll("a").forEach((link) => { const isSameDomain = link.host === window.location.host; if (!isSameDomain) return; link.addEventListener("click", function (event) { event.preventDefault(); const targetUrl = this.getAttribute("href"); // Zakrycie loaderem od góry gsap.fromTo( ".loader", { yPercent: -101 }, { yPercent: 0, ease: "power3.inOut", duration: 0.5, onComplete: () => { window.location.href = targetUrl; }, } ); // Animacja logo gsap.to("#logo", { duration: 0.5, yPercent: -50, filter: "blur(1rem)", opacity: 0, ease: "power3.in", onComplete: () => { window.location.href = targetUrl; }, }); }); }); })(); document.addEventListener("DOMContentLoaded", () => { /** * Dodaje niełamliwą spację ( ) po każdej jednoliterowej spójce/przyimku * (domyślnie i, z, w, a, o, u — małe i duże). * @param {string} selector - Selektor CSS elementów, w których chcemy poprawić tekst. */ function fixSingleLetterWords(selector) { const elements = document.querySelectorAll(selector); elements.forEach(element => { // Pobierz oryginalną zawartość (HTML) elementu let text = element.innerHTML; // Wyrażenie regularne szuka słów składających się wyłącznie z jednej litery // (i, z, w, a, o, u - w obu wariantach wielkości) // i zamienia spację po nich na niełamliwą spację. // // \b([iIaAoOuUwWzZ])\b\s // // \b - granica słowa // ([...]) - grupa znaków jednoliterowych, które nas interesują // \b - kolejna granica słowa (spójka/przyimek samodzielny) // \s - spacja występująca po takim słówku // // Zamieniamy ją na: $1  — czyli tę samą literę i niełamliwą spację. // // "g" - flaga globalna, zamiana we wszystkich wystąpieniach text = text.replace(/\b([iIaAoOuUwWzZ])\b\s/g, '$1 '); // Zapisz zmieniony tekst ponownie do elementu element.innerHTML = text; }); } // Wywołaj funkcję z wybranym selektorem (np. klasa .tekst) fixSingleLetterWords('.blog-rich-text'); }); //gsap document.addEventListener("DOMContentLoaded", (event) => { gsap.registerPlugin(Flip, ScrollTrigger); //cursor const cursor = document.querySelector(".cursor"); const cursorStroke = document.querySelector(".cursor_stroke"); const linksAndButtons = document.querySelectorAll("a, button"); gsap.set([cursor, cursorStroke], { xPercent: -50, yPercent: -50 }); const xC = gsap.quickSetter(cursor, "x", "px"); const yC = gsap.quickSetter(cursor, "y", "px"); window.addEventListener("mousemove", (e) => { xC(e.x); yC(e.y); gsap.to(cursorStroke, { duration: 0.2, x: e.clientX, y: e.clientY, }); }); const handleHover = ( element, opacityOnHover, scaleOnHover, duration = 0.4, ease = "power3.inOut" ) => { element.addEventListener("mouseover", () => { cursor.style.opacity = opacityOnHover; cursorStroke.style.opacity = opacityOnHover; gsap.to(cursorStroke, { scale: scaleOnHover, duration, ease }); }); element.addEventListener("mouseout", () => { cursor.style.opacity = 1; cursorStroke.style.opacity = 1; gsap.to(cursorStroke, { scale: 1, duration, ease }); }); }; linksAndButtons.forEach((element) => handleHover(element, 0, 1.75)); // Default for links and buttons document.addEventListener("mousedown", function (event) { gsap.to(cursorStroke, { scale: 1.5, ease: "power3.in", }); }); document.addEventListener("mouseup", function (event) { gsap.to(cursorStroke, { scale: 1, delay: 0.3, ease: "power3.out", }); }); //CTA Start const splitCTA = new SplitType(".main_cta_component h2, .main_cta_component p", { types: "words, chars", }); const tlCTA = gsap .timeline({ scrollTrigger: { trigger: ".section_main_cta", start: "center 80%", end: "center center", scrub: 2, }, }) .from(splitCTA.chars, { opacity: 0.1, filter: "blur(1rem)", scale: 0.9, stagger: 0.01, yPercent: 10, duration: 0.1, }); //CTA End // startNavbar const navLoad = gsap.timeline(); navLoad.fromTo( "#logo path", { filter: "blur(" + 1 + "rem)", yPercent: 50, opacity: 0, }, { filter: "blur(" + 0 + "rem)", yPercent: 0, opacity: 1, ease: "power3.out", stagger: 0.05, } ); let navbarLogoWrapper = document.querySelector( ".navbar_logo_wrapper" ).offsetHeight; let startPosition = "top+=" + navbarLogoWrapper + "px" + " 100"; function navChange() { navbarLogoWrapper = document.querySelector( ".navbar_logo_wrapper" ).offsetHeight; startPosition = "top+=" + navbarLogoWrapper + "px" + " top"; ScrollTrigger.refresh(); } window.addEventListener("resize", navChange); const showAnim = gsap .fromTo( ".nav_component", { yPercent: -150, opacity: 0, }, { yPercent: 0, opacity: 1, paused: true, duration: 0.45, ease: "power3.inOut", } ) .progress(1); let navTrigger = ScrollTrigger.create({ start: "top top", end: 99999, onUpdate: (self) => { self.direction === -1 ? showAnim.play() : showAnim.reverse(); }, }); ScrollTrigger.create({ trigger: ".footer", start: "top bottom", onEnter: () => { navTrigger.disable(); showAnim.restart(true); }, onLeaveBack: () => { navTrigger.enable(); showAnim.pause(); }, }); ScrollTrigger.refresh(); //endCode gsap.from("#logoFooter path", { scrollTrigger: { trigger: ".footer", start: "center bottom", toggleActions: "play none none reverse", }, filter: "blur(" + 1 + "rem)", ease: "power3.out", yPercent: 50, opacity: 0, stagger: 0.1, }); });