(function ($) { "use strict"; $(document).ready(function () { // ===== Menu Toggle ===== $(".menu-trigger").click(() => $(".slide-menu").addClass("active")); $(".menu-close").click(() => $(".slide-menu").removeClass("active")); // ===== Sticky Header ===== $(window).on("scroll", () => { const scroll = $(window).scrollTop(); $(".header").toggleClass("sticky", scroll >= 100); }); // ===== Infinite Brand Slider ===== const brandTrack = document.querySelector(".slider-track"); if (brandTrack) { brandTrack.innerHTML += brandTrack.innerHTML; const totalBrandWidth = brandTrack.scrollWidth / 2; gsap.to(brandTrack, { x: -totalBrandWidth, duration: 20, ease: "none", repeat: -1 }); } // ===== Owl Carousel Sliders ===== $(".inspiration-overlay-slider").owlCarousel({ loop: true, margin: 10, nav: false, items: 1, stagePadding: 45, autoplay: true, autoplayTimeout: 5000, autoplayHoverPause: true, dots: true }); $(".showcase-gellary").owlCarousel({ loop: true, margin: 15, nav: false, items: 1, stagePadding: 50, autoplay: true, autoplayTimeout: 2000, autoplayHoverPause: true, dots: false }); }); // ===== Portfolio Filter (Multi-Select) ===== const filterButtons = document.querySelectorAll(".portfolio-filter button"); const projectCards = document.querySelectorAll(".project-card"); let activeFilters = new Set(); filterButtons.forEach(btn => { btn.addEventListener("click", () => { const filter = btn.dataset.filter; if (filter === "all") { activeFilters.clear(); filterButtons.forEach(b => b.classList.remove("active")); btn.classList.add("active"); projectCards.forEach(c => c.classList.remove("hide")); return; } activeFilters.has(filter) ? activeFilters.delete(filter) : activeFilters.add(filter); btn.classList.toggle("active"); document.querySelector(".portfolio-filter button[data-filter='all']").classList.remove("active"); projectCards.forEach(card => { const matches = [...activeFilters].some(f => card.classList.contains(f)); card.classList.toggle("hide", activeFilters.size > 0 && !matches); }); }); }); // ===== Portfolio Filter (Multi-Select) ===== // Beyond the Brief Card Infinite Slider Start gsap.registerPlugin(Draggable); const teamTrack = document.querySelector(".team-track"); if (teamTrack) { // 1. Duplicate content for seamless loop teamTrack.innerHTML += teamTrack.innerHTML; const totalTeamWidth = teamTrack.scrollWidth / 2; // 2. Create the base animation const teamTween = gsap.to(teamTrack, { x: -totalTeamWidth, duration: 25, ease: "none", repeat: -1 }); // 3. Track scroll direction for timeScale let lastScrollY = window.scrollY; window.addEventListener("scroll", () => { const currentY = window.scrollY; // Smoothly transition the direction change gsap.to(teamTween, { timeScale: currentY > lastScrollY ? 1 : -1, overwrite: true }); lastScrollY = currentY; }); // 4. Add Drag Functionality // We use a dummy element (proxy) to capture drag logic const proxy = document.createElement("div"); Draggable.create(proxy, { type: "x", trigger: teamTrack, // Dragging the track triggers the logic onPress() { this.startProgress = teamTween.progress(); }, onDrag: function() { // Calculate how far we've dragged relative to the width const change = (this.startX - this.x) / totalTeamWidth; let newProgress = this.startProgress + change; // Wrap the progress so it stays between 0 and 1 teamTween.progress(gsap.utils.wrap(0, 1, newProgress)); }, onRelease: function() { // Optional: Resume the animation if you want it to keep moving // teamTween.play(); } }); } // Beyond the Brief Card Infinite Slider Start // ===== Flip Card ===== let currentCard = null; function handleFlip(card) { if (currentCard === card) return card.classList.remove("active"), currentCard = null; if (currentCard) currentCard.classList.remove("active"); card.classList.add("active"); currentCard = card; } // ===== Branding Gallery Hover Effect ===== document.querySelectorAll(".branding-list h2").forEach(item => { const hoverImage = document.querySelector(".hover-image"); const hoverImgTag = hoverImage.querySelector("img"); item.addEventListener("mouseenter", () => { hoverImgTag.src = item.dataset.img; hoverImage.style.opacity = 1; }); item.addEventListener("mouseleave", () => hoverImage.style.opacity = 0); item.addEventListener("mousemove", e => { hoverImage.style.left = e.clientX + "px"; hoverImage.style.top = e.clientY + "px"; }); }); // ===== Text Vertical Slide ===== window.addEventListener("load", () => { document.querySelectorAll(".shkVrtx91A").forEach(container => { const items = container.querySelectorAll(".shk-vrtx-item-91A"); if (!items.length) return; container.appendChild(items[0].cloneNode(true)); const itemHeight = items[0].offsetHeight; const tl = gsap.timeline({ repeat: -1 }); items.forEach((_, i) => { tl.to(container, { y: -itemHeight * (i + 1), duration: 0.5, ease: "power2.inOut" }) .to({}, { duration: 1.2 }); // pause }); }); }); // ===== Scroll-triggered GSAP Animations ===== gsap.registerPlugin(ScrollTrigger, MorphSVGPlugin); // Awards fade in gsap.to(".awards-wrap", { opacity: 1, y: 0, duration: 1, ease: "power3.out", scrollTrigger: { trigger: ".awards-wrap", start: "top 80%", toggleActions: "play none none none" } }); // Showcase Items gsap.utils.toArray(".showcase-item").forEach(item => { gsap.set(item, { opacity: 0, y: 20 }); gsap.to(item, { opacity: 1, y: 0, stagger: 0.12, ease: "power1.out", scrollTrigger: { trigger: ".slider-wrap", start: "top 75%", end: "bottom 25%", toggleActions: "play none none none" } }); }); // Footer Shake Animation const down = 'M0-0.3C0-0.3,464,156,1139,156S2278-0.3,2278-0.3V683H0V-0.3z'; const center = 'M0-0.3C0-0.3,464,0,1139,0s1139-0.3,1139-0.3V683H0V-0.3z'; ScrollTrigger.create({ trigger: '.footer', start: 'top bottom', toggleActions: 'play pause resume reverse', onEnter: self => { const variation = self.getVelocity() / 10000; gsap.fromTo('#bouncy-path', { morphSVG: down }, { duration: 2, morphSVG: center, ease: `elastic.out(${1 + variation}, ${1 - variation})`, overwrite: 'true' }); } }); // ===== Interactive Movement Effects ===== function addPointerEffect(elements, options) { elements.forEach(el => { const rotX = gsap.quickTo(el, "rotationX", options); const rotY = gsap.quickTo(el, "rotationY", options); const moveX = gsap.quickTo(el, "x", options); const moveY = gsap.quickTo(el, "y", options); const scale = gsap.quickTo(el, "scale", options); el.addEventListener("pointermove", e => { const rect = el.getBoundingClientRect(); const x = (e.clientX - rect.left) / rect.width; const y = (e.clientY - rect.top) / rect.height; rotX(gsap.utils.interpolate(options.rotXMin, options.rotXMax, y)); rotY(gsap.utils.interpolate(options.rotYMin, options.rotYMax, x)); moveX(gsap.utils.interpolate(options.moveXMin, options.moveXMax, x)); moveY(gsap.utils.interpolate(options.moveYMin, options.moveYMax, y)); scale(options.scaleValue); }); el.addEventListener("pointerleave", () => { rotX(0); rotY(0); moveX(0); moveY(0); scale(1); }); }); } addPointerEffect(document.querySelectorAll(".showcase-item"), { duration: 0.6, ease: "power4.out", rotXMin: 25, rotXMax: -25, rotYMin: -25, rotYMax: 25, moveXMin: -40, moveXMax: 40, moveYMin: -40, moveYMax: 40, scaleValue: 1.08 }); addPointerEffect(document.querySelectorAll(".awards-wrap img"), { duration: 0.3, ease: "power3.out", rotXMin: 35, rotXMax: -35, rotYMin: -35, rotYMax: 35, moveXMin: -25, moveXMax: 25, moveYMin: -25, moveYMax: 25, scaleValue: 1.12 }); addPointerEffect(document.querySelectorAll(".team-card"), { duration: 0.2, ease: "power3.out", rotXMin: 25, rotXMax: -25, rotYMin: -25, rotYMax: 25, moveXMin: 0, moveXMax: 0, moveYMin: 0, moveYMax: 0, scaleValue: 1.1 }); // ===== Falling Buttons Animation ===== document.querySelectorAll(".ct-falling-btn-wrap a").forEach(btn => { const randomX = gsap.utils.random(-50, 50); const randomRot = gsap.utils.random(-25, 25); const randomDelay = gsap.utils.random(0, 0.5); gsap.fromTo(btn, { y: -200, x: 0, rotation: 0, opacity: 0 }, { y: 0, x: randomX, rotation: randomRot, opacity: 1, duration: 1.2, ease: "power3.out", delay: randomDelay, scrollTrigger: { trigger: ".branding-area", start: "top 85%", toggleActions: "play none none none" } } ); }); })(jQuery); // Text Vertical Slide Effect Start document.addEventListener("DOMContentLoaded", function () { const container = document.getElementById("ctVertical"); const items = container.children; container.appendChild(items[0].cloneNode(true)); const itemHeight = items[0].offsetHeight; const tl = gsap.timeline({ repeat: -1 }); for (let i = 0; i < items.length; i++) { tl.to(container, { y: -itemHeight * i, duration: 0.6, ease: "power2.inOut" }) .to({}, { duration: 1.5 }); // ⏸ pause time } }); // Text Vertical Slide Effect End