// This file was generated by Slater.app - script.js // --- GSAP gsap.registerPlugin(ScrollTrigger); gsap.config({ nullTargetWarn: false, trialWarn: false, }); let mm = gsap.matchMedia(); // --- GLOBAL - RELOAD AT THE TOP window.addEventListener('beforeunload', function () { history.scrollRestoration = 'manual'; }); // --- LENIS window.lenis = new Lenis(); lenis.on('scroll', ScrollTrigger.update); gsap.ticker.add((time) => { lenis.raf(time * 1000); }); gsap.ticker.lagSmoothing(0); // --- PAPER TIGET SIGNATURE const pprtgr = ['color: #F2F3F3', 'background: #080808', 'font-size: 12px', 'padding-left: 10px', 'line-height: 2', 'border-left: 5px solid #ff3c31'].join(';'); console.info( ` %cWebsite by Paper Tiger${' '} www.papertiger.com${' '} `, pprtgr ); // --- CURRENT YEAR const currentYear = document.querySelector('[current-year]'); if (currentYear) { currentYear.innerHTML = new Date().getFullYear(); } // --- GLOBAL - FADE function fade() { const fadeElements = document.querySelectorAll('[fade]'); gsap.set(fadeElements, { opacity: 0 }); ScrollTrigger.batch(fadeElements, { once: true, start: 'top 95%', onEnter: (batch) => gsap.to(batch, { opacity: 1, duration: 1.8, ease: 'power3.out', stagger: 0.2, }), }); } // --- HEADER BG function headerBg() { const header = document.querySelector('.c-header'); if (!header) return; ScrollTrigger.create({ trigger: 'body', start: '300 top', onToggle: (self) => { if (self.isActive) { header.classList.add('scrolled'); } else { header.classList.remove('scrolled'); } }, }); } // --- ACCORDIONS function accordions() { const accordions = document.querySelectorAll('.c-ac-item'); let active = null; if (accordions.length === 0) return; accordions.forEach((accordion, index) => { const question = accordion.querySelector('.c-ac-question'); const response = accordion.querySelector('.c-ac-response'); const arrow = accordion.querySelector('.c-ac-icon'); const arrowBar = accordion.querySelector('.c-ac-icon-bar.is-2'); const icon = accordion.querySelector('.c-img-contain.ac-capab-icon'); const tl = gsap.timeline({ paused: true, defaults: { ease: 'power2.inOut', duration: 0.5, }, }); tl.to(response, { height: 'auto' }); tl.to(arrow, { rotation: 90 }, 0); tl.to(arrowBar, { width: 0 }, 0); // Customize the accordion if it has a specific class if (accordion.classList.contains('capab')) { tl.to(icon, { height: '3em', opacity: 1, marginBottom: '1.5em' }, 0); tl.to(accordion, { background: 'white' }, 0); } accordion.tl = tl; accordion.addEventListener('click', function () { if (active === accordion) { tl.reverse(); active = null; } else { if (active) active.tl.reverse(); tl.play(); active = accordion; } }); // Open the first accordion on page load if (index === 0) { accordion.click(); } }); } // --- Reviews testimonials slider function initPrintReviewsSlider() { if (window.location.pathname.indexOf('/capabilities/print-services') >= 0) { const S = $('.c-splide-slider.review'); if (S.length < 1) return; const buttons = S.find('.c-swiper-arrow'); const splide = new Splide('.splide.review', { type: 'loop', perPage: 1, padding: 0, // gap: '2em', gap: '0', clones: 4, arrows: false, pagination: true, }); buttons[0].addEventListener('click', () => splide.go('<')); buttons[1].addEventListener('click', () => splide.go('>')); splide.mount(); } } function initCapsVideoSlider() { if (window.location.pathname.indexOf('/capabilities/videography') >= 0) { const S = $('.c-splide-slider.reel'); if (S.length < 1) return; const buttons = S.find('.c-swiper-arrow'); const splide = new Splide('.splide.reel', { type: 'loop', perPage: 1, padding: 0, // gap: '2em', gap: '0', clones: 4, arrows: false, pagination: true, }); buttons[0].addEventListener('click', () => splide.go('<')); buttons[1].addEventListener('click', () => splide.go('>')); splide.mount(); } } // --- HP Latest Resources slider function hpLatestResourcesSlider() { if (window.location.pathname != '/') return; const S = $('.c-splide-slider.late-res'); if (S.length < 1) return; const buttons = S.find('.c-swiper-arrow'); const splide = new Splide('.splide.late-res', { type: 'loop', perPage: 1, padding: 0, gap: '2em', clones: 4, arrows: false, pagination: true, }); buttons[0].addEventListener('click', () => splide.go('<')); buttons[1].addEventListener('click', () => splide.go('>')); splide.mount(); } // -- Capabilities sliders function initCapabilitiesSliders() { if (window.location.pathname.indexOf('/capabilities/') >= 0) { const S = $('.c-splide-slider.capabilities'); if (S.length < 1) return; const buttons = S.find('.c-swiper-arrow'); const splide = new Splide('.splide.capabilities', { type: 'loop', perPage: 1, padding: 0, gap: '2em', clones: 4, arrows: false, pagination: true, }); buttons[0].addEventListener('click', () => splide.go('<')); buttons[1].addEventListener('click', () => splide.go('>')); splide.mount(); } } // -- Success Stories sliders function initSuccessStoriesSliders() { if (window.location.pathname.indexOf('/project/') >= 0) { succLatestResourcesSlider(); succPortfolioSlider(); } } function succLatestResourcesSlider() { const S = $('.c-splide-slider.late-res'); if (S.length < 1) return; const buttons = S.find('.c-swiper-arrow'); const splide = new Splide('.splide.late-res', { type: 'loop', perPage: 1, padding: 0, gap: '2em', clones: 4, arrows: false, pagination: true, }); buttons[0].addEventListener('click', () => splide.go('<')); buttons[1].addEventListener('click', () => splide.go('>')); splide.mount(); } function succPortfolioSlider() { const S = $('.c-splide-slider.portfolio'); if (S.length < 1) return; const buttons = S.find('.c-swiper-arrow'); const splide = new Splide('.splide.portfolio', { type: 'loop', perPage: 1, padding: 0, gap: '2em', clones: 4, arrows: false, pagination: true, }); buttons[0].addEventListener('click', () => splide.go('<')); buttons[1].addEventListener('click', () => splide.go('>')); splide.mount(); } // --- STUDIO function initStudioSliders() { if (window.location.pathname.indexOf('/studio') >= 0) { sliderTakes(); sliderStudio(); sliderBehind(); } } function sliderTakes() { const S = $('.c-splide-slider.takes'); if (S.length < 1) return; const buttons = S.find('.c-swiper-arrow'); const splide = new Splide('.splide.takes', { type: 'loop', perPage: 1, padding: 0, gap: '2em', clones: 4, arrows: false, pagination: true, }); buttons[0].addEventListener('click', () => splide.go('<')); buttons[1].addEventListener('click', () => splide.go('>')); splide.mount(); } function sliderStudio() { const S = $('.c-splide-slider.studio'); if (S.length < 1) return; const buttons = S.find('.c-swiper-arrow'); const splide = new Splide('.splide.studio', { type: 'loop', perPage: 1, padding: 0, gap: '2em', clones: 4, arrows: false, pagination: true, }); buttons[0].addEventListener('click', () => splide.go('<')); buttons[1].addEventListener('click', () => splide.go('>')); splide.mount(); } function sliderBehind() { const S = $('.c-splide-slider.behind'); if (S.length < 1) return; const buttons = S.find('.c-swiper-arrow'); const splide = new Splide('.splide.behind', { type: 'loop', perPage: 1, padding: 0, gap: '2em', clones: 4, arrows: false, pagination: true, }); buttons[0].addEventListener('click', () => splide.go('<')); buttons[1].addEventListener('click', () => splide.go('>')); splide.mount(); } // --- SUCCESS STORIES SLIDER function storiesSlider() { const successSection = document.querySelector('.c-section.success'); const slider = new Swiper('.swiper.success', { slidesPerView: 1, speed: 0, effect: 'fade', fadeEffect: { crossFade: true, }, navigation: { nextEl: '.swiper-next.success', prevEl: '.swiper-prev.success', }, pagination: { el: '.swiper-pagination.success', type: 'fraction', }, }); slider.on('slideChange', function () { // Get the current active slide const activeSlide = slider.slides[slider.activeIndex]; // Find the first accordion question within this slide and click it const firstAccordion = activeSlide.querySelector('.c-ac-question'); if (firstAccordion) { firstAccordion.click(); } // Scroll to section after switching slide setTimeout(() => { lenis.scrollTo(successSection, { offset: 100 }); }, 100); }); } // --- LATEST RESOURCES SLIDER function resourcesSlider() { const slider = new Swiper('.swiper.post', { slidesPerView: 'auto', // spaceBetween: 32, speed: 500, grabCursor: true, navigation: { nextEl: '.swiper-next.post', prevEl: '.swiper-prev.post', }, pagination: { el: '.swiper-pagination.post', clickable: true, }, breakpoints: { 320: { spaceBetween: 20, }, 992: { spaceBetween: 32, }, }, }); } // --- WHO TABBER // function whoTabber() { // const tabber = document.querySelectorAll(".c-tabber"); // if (!tabber) return; // tabber.forEach(tab => { // const items = tab.querySelectorAll(".c-tabber-item"); // // Page load // items[0].classList.add("is-active"); // const allLinks = document.querySelectorAll(".c-tabber-link"); // allLinks[0].classList.add("is-active"); // tab.addEventListener("click", function (e) { // const link = e.target.closest(".c-tabber-link"); // if (link) { // // Get all links within the clicked tab's card // const cardTop = link.closest('.c-tabber-card_top'); // const links = Array.from(cardTop.querySelectorAll(".c-tabber-link")); // const index = links.indexOf(link); // // Only proceed if we found a valid index // if (index !== -1 && index < items.length) { // // Remove is-active class from all items and ALL links across tabs // items.forEach(item => item.classList.remove("is-active")); // document.querySelectorAll(".c-tabber-link").forEach(link => link.classList.remove( // "is-active")); // // Add is-active class to the matching item and ALL corresponding links // items[index].classList.add("is-active"); // document.querySelectorAll(`.c-tabber-link:nth-child(${index + 1})`).forEach( // link => { // link.classList.add("is-active"); // }); // } // } // }); // }); // } function whoTabber() { const tabber = document.querySelectorAll('.c-tabber'); if (!tabber) return; tabber.forEach((tab) => { const items = tab.querySelectorAll('.c-tabber-item'); let autoplayInterval; // Store interval reference let currentIndex = 0; // Function to change tab const changeTab = (index) => { items.forEach((item) => item.classList.remove('is-active')); document.querySelectorAll('.c-tabber-link').forEach((link) => link.classList.remove('is-active')); items[index].classList.add('is-active'); document.querySelectorAll(`.c-tabber-link:nth-child(${index + 1})`).forEach((link) => { link.classList.add('is-active'); }); }; // Page load changeTab(0); // Start autoplay const startAutoplay = () => { autoplayInterval = setInterval(() => { currentIndex = (currentIndex + 1) % items.length; changeTab(currentIndex); }, 6000); // 6 seconds }; startAutoplay(); // Click handler tab.addEventListener('click', function (e) { const link = e.target.closest('.c-tabber-link'); if (link) { // Stop autoplay on user interaction clearInterval(autoplayInterval); const cardTop = link.closest('.c-tabber-card_top'); const links = Array.from(cardTop.querySelectorAll('.c-tabber-link')); const index = links.indexOf(link); if (index !== -1 && index < items.length) { currentIndex = index; changeTab(index); } } }); }); } // --- REVIEWS SLIDER function reviewsSlider() { const thumbs = new Swiper('.swiper.reviews-thumb', { slidesPerView: 4, }); const slider = new Swiper('.swiper.reviews-item', { slidesPerView: 1, speed: 600, navigation: { nextEl: '.swiper-next.reviews-item', prevEl: '.swiper-prev.reviews-item', }, effect: 'fade', fadeEffect: { crossFade: true, }, thumbs: { swiper: thumbs, }, }); } // --- GALLERY SLIDER function gallerySlider() { const slider = new Swiper('.swiper.gallery', { slidesPerView: 'auto', speed: 600, navigation: { nextEl: '.swiper-next.gallery', prevEl: '.swiper-prev.gallery', }, pagination: { el: '.swiper-pagination.gallery', }, breakpoints: { 320: { spaceBetween: 20, pagination: { type: 'bullets', }, }, 992: { spaceBetween: 32, pagination: { type: 'fraction', }, }, }, }); } // --- HEADER/BACK TOP SCROLL VISIBILITY function headerScrollVisibility() { let lastScrollTop = 0; window.addEventListener('scroll', function () { const header = document.querySelector('.c-header'); if (!header) return; const backTopLinks = document.querySelectorAll('.c-back-top'); let scrollTop = window.pageYOffset || document.documentElement.scrollTop; if (scrollTop > lastScrollTop) { if (!header.classList.contains('not-visible')) { // Header header.classList.add('not-visible'); gsap.to(header, { autoAlpha: 0, duration: 0.4, ease: 'power2.inOut' }); // Back top link backTopLinks.forEach((link) => { gsap.to(link, { autoAlpha: 0, duration: 0.4, ease: 'power2.inOut' }); }); } } else { if (header.classList.contains('not-visible')) { // Header header.classList.remove('not-visible'); gsap.to(header, { autoAlpha: 1, duration: 0.4, ease: 'power2.inOut' }); // Back top link backTopLinks.forEach((link) => { gsap.to(link, { autoAlpha: 1, duration: 0.4, ease: 'power2.inOut' }); }); } } lastScrollTop = scrollTop; }); } // --- HEADER MOBILE function headerMobile() { let header = document.querySelector('.c-header'); let headerBtn = document.querySelector('.c-nav-btn'); let headerNav = document.querySelector('.c-header-nav'); let menuLine1 = document.querySelectorAll('.c-nav-bar.is-1'); let menuLine2 = document.querySelectorAll('.c-nav-bar.is-2'); let menuLine3 = document.querySelectorAll('.c-nav-bar.is-3'); let tl = gsap.timeline({ paused: true, defaults: { ease: 'expo.inOut', duration: 1 } }); gsap.set(menuLine1, { transformOrigin: 'center center' }); gsap.set(menuLine2, { transformOrigin: 'center center' }); gsap.set(menuLine3, { transformOrigin: 'center center' }); tl.to(headerNav, { clipPath: 'inset(0% 0% 0% 0%)' }); tl.to(menuLine1, { rotation: 45, y: 7 }, 0); tl.to(menuLine2, { width: 0 }, 0); tl.to(menuLine3, { rotation: -45, y: -7 }, 0); headerBtn.addEventListener('click', function () { header.classList.toggle('is-open'); if (header.classList.contains('is-open')) { lenis.stop(); tl.restart(); } else { lenis.start(); tl.reverse(); } }); // Links const links = document.querySelectorAll('.c-nav-link'); links.forEach((link) => { link.addEventListener('click', function (e) { lenis.start(); headerBtn.click(); }); }); } // --- BUTTONS HOVER function buttonsHover() { const buttonsWrap = document.querySelectorAll('.c-btn-wrap'); // Core Buttons buttonsWrap.forEach((item) => { const arrow1 = item.querySelector('.c-icon.btn-arrow.is-1'); const arrow2 = item.querySelector('.c-icon.btn-arrow.is-2'); const arrowWrap = item.querySelector('.c-btn-arrow'); const button = item.querySelector('.c-btn'); const buttonbackground = window.getComputedStyle(button).backgroundColor; const buttonColor = window.getComputedStyle(button).color; const tl = gsap.timeline({ paused: true, defaults: { duration: 0.8, ease: 'expo.inOut', }, }); tl.to(arrow1, { x: 48, y: -48 }); tl.to(arrow2, { x: 0, y: 0 }, 0); tl.to(arrowWrap, { background: buttonbackground, color: buttonColor }, 0); item.addEventListener('mouseenter', function () { tl.restart(); }); item.addEventListener('mouseleave', function () { tl.reverse(); }); // Latest Resources Card const cards = document.querySelectorAll('.swiper-slide.post'); const otherCards = document.querySelectorAll('.c-post-item'); const featuredCard = document.querySelector('.c-featured-post'); const allElements = [...cards, ...otherCards, featuredCard]; allElements.forEach((card) => { if (!card) return; const arrow = card.querySelector('.c-btn-arrow.post'); const tl = gsap.timeline({ paused: true, defaults: { duration: 0.8, ease: 'expo.inOut', }, }); tl.to(arrow, { rotation: 45, background: '#071d32', color: 'white', border: '1px solid #071d32', }); card.addEventListener('mouseenter', function () { tl.restart(); }); card.addEventListener('mouseleave', function () { tl.reverse(); }); }); }); } // --- GLOBAL - LINE ANIMATION function drawLine() { // Draw line gsap.set('[draw-line]', { opacity: 1, scaleX: 0, transformOrigin: 'top left', }); ScrollTrigger.batch('[draw-line]', { once: true, onEnter: (batch) => gsap.to(batch, { scaleX: 1, delay: 0.1, duration: 1.6, ease: 'power3.out', stagger: 0.2, markers: true, }), }); } // --- GLOBAL - STATS COUNTER // function statsCounter() { // document.querySelectorAll("[counter]").forEach((element, index) => { // let thisId = "countup" + index; // element.setAttribute("id", thisId); // // Extract numeric value and optional suffix // let finalValue = element.getAttribute("final-number"); // let match = finalValue.match(/^([\d.]+)(\D*)$/); // Separate numeric part and suffix // let endNumber = parseFloat(match[1]); // Numeric part // let suffix = match[2] || ""; // Suffix (if any) // let startNumber = 0; // let decimals = +element.getAttribute("decimals"); // let duration = element.getAttribute("count-duration"); // let myCounter = new CountUp(thisId, startNumber, endNumber, decimals, duration, { // suffix: suffix, // Add suffix dynamically // }); // ScrollTrigger.create({ // trigger: element, // start: "top bottom", // onEnter: () => { // myCounter.start(); // }, // }); // }); // } // --- GLOBAL - STATS COUNTER function statsCounter() { document.querySelectorAll('[counter]').forEach((element, index) => { let thisId = 'countup' + index; element.setAttribute('id', thisId); let finalValue = element.getAttribute('final-number'); let cleanValue = finalValue.replace(/,/g, ''); let match = cleanValue.match(/^([\d.]+)(\D*)$/); if (match) { let numberPart = match[1]; let endNumber = parseFloat(numberPart); let suffix = match[2] || ''; // Calculate decimals based on the actual number if not specified let decimals = element.hasAttribute('decimals') ? +element.getAttribute('decimals') : numberPart.includes('.') ? numberPart.split('.')[1].length : 0; let startNumber = 0; let duration = element.getAttribute('count-duration'); let useCommas = finalValue.includes(','); let myCounter = new CountUp(thisId, startNumber, endNumber, decimals, duration, { suffix: suffix, useGrouping: useCommas, decimalPlaces: decimals, // Ensure decimal places matches }); ScrollTrigger.create({ trigger: element, start: 'top bottom', onEnter: () => { myCounter.start(); }, }); } else { console.error(`Invalid final-number attribute: ${finalValue}`); } }); } function statsCounterMobile() { const cards = document.querySelectorAll('.c-stats-card'); cards.forEach((card) => { const text = card.querySelector('.t-display-2'); const value = text.getAttribute('final-number'); text.textContent = value; }); } // --- SERVICE CARDS function serviceCards() { const cards = document.querySelectorAll('.c-service-card'); cards.forEach((card) => { const background = card.querySelector('.c-img-contain.service-bg'); const thumb = card.querySelector('.c-service-thumb'); const buttonWrap = card.querySelector('.c-btn-wrap.service-card'); // const button = card.querySelector(".c-btn"); // const arrow = card.querySelector(".c-btn-arrow"); const tl = gsap.timeline({ paused: true, defaults: { ease: 'power4.inOut', duration: 0.5, }, }); tl.to(thumb, { opacity: 0 }, 0); tl.to(background, { opacity: 1 }, 0); tl.to(card, { color: 'white' }, 0); tl.to(buttonWrap, { height: 'auto', opacity: 1 }, 0); // tl.to(button, { background: "white" }, 0); // tl.to(arrow, { borderColor: "white", color: "white" }, 0); card.addEventListener('mouseenter', function () { tl.restart(); }); card.addEventListener('mouseleave', function () { tl.reverse(); }); }); } // --- BLOG FILTERS function blogFilters() { const contentSection = document.querySelector('.c-section.filter-content'); const paginationBtn = document.querySelectorAll('.c-btn.pagination'); paginationBtn.forEach((button) => { button.addEventListener('click', function () { lenis.scrollTo(contentSection, { offset: -64 }); setTimeout(() => { ScrollTrigger.refresh(); buttonsHover(); }, 100); }); }); } // --- TEAM MODAL function teamModal() { const items = document.querySelectorAll('.c-team-item'); if (items.length === 0) return; items.forEach((item) => { const modal = item.querySelector('.c-team-modal'); const bg = item.querySelector('.c-team-modal-bg'); const card = item.querySelector('.c-team-modal-card'); const closeBtn = item.querySelector('.c-team-modal-close-btn'); const trigger = item.querySelector('.c-team-modal-trigger'); const plusIcon = item.querySelector('.c-icon.modal-plus'); let tl = gsap.timeline({ paused: true, defaults: { ease: 'power4.inOut', duration: 0.8, }, }); tl.to(bg, { opacity: 0.2 }); tl.fromTo(card, { clipPath: 'inset(0% 0% 0% 100%)' }, { clipPath: 'inset(0% 0% 0% 0%)' }, '<0.3'); tl.to(plusIcon, { rotation: 45 }, '<'); function openModal() { lenis.stop(); modal.classList.add('is-open'); tl.restart(); } function closeModal() { lenis.start(); modal.classList.remove('is-open'); tl.reverse(); } trigger.addEventListener('click', openModal); bg.addEventListener('click', closeModal); closeBtn.addEventListener('click', closeModal); document.addEventListener('keydown', closeModal); }); } // --- BLOG SINGLE function blogSingleCatLink() { const items = document.querySelectorAll('.c-post-cat-item'); items.forEach((item) => { const link = item.querySelector('.c-post-cat-link'); const text = item.textContent; const customCat = text.replace(/\//g, '%2F').replace(/\s+/g, '+'); const location = `${window.location.origin}/blog?cat=${customCat}`; console.log(text); link.setAttribute('href', location); }); } // --- DATE function date() { const dateInput = document.getElementById('date'); if (!dateInput) return; // Get today's date const today = new Date(); // Format date as YYYY-MM-DD const year = today.getFullYear(); const month = String(today.getMonth() + 1).padStart(2, '0'); const day = String(today.getDate()).padStart(2, '0'); const formattedDate = `${year}-${month}-${day}`; dateInput.min = formattedDate; dateInput.addEventListener('click', () => { dateInput.showPicker(); }); } // --- SECTION SCROLL TO LINK function sectionScrollToLink() { const links = document.querySelectorAll('[data-link]'); const sections = document.querySelectorAll('.c-section'); const header = document.querySelector('.c-header'); const headerHeight = header ? parseFloat(window.getComputedStyle(header).height) : 0; links.forEach((link) => { const linkInfo = link.getAttribute('data-link'); link.addEventListener('click', function () { setTimeout(() => { lenis.scrollTo(`.c-section[id=${linkInfo}]`, { duration: 1.2, offset: window.innerWidth <= 991 ? -headerHeight : 0, }); }, 10); }); }); } let homepage = document.querySelector("[data-page='homepage']"); let blog = document.querySelector("[data-page='blog']"); let blogSingle = document.querySelector("[data-page='blog-single']"); // --- INIT function init() { accordions(); storiesSlider(); resourcesSlider(); whoTabber(); headerBg(); reviewsSlider(); gallerySlider(); serviceCards(); teamModal(); date(); sectionScrollToLink(); if (blog) { blogFilters(); } if (blogSingle) { blogSingleCatLink(); } hpLatestResourcesSlider(); initStudioSliders(); initSuccessStoriesSliders(); initCapabilitiesSliders(); initPrintReviewsSlider(); initCapsVideoSlider(); } init(); // --- MATCHMEDIA - DESKTOP mm.add('(min-width: 992px)', () => { headerScrollVisibility(); buttonsHover(); drawLine(); fade(); statsCounter(); return () => { // }; }); // --- MATCHMEDIA - TABLET AND MOBILE mm.add('(max-width: 991px)', () => { headerMobile(); statsCounterMobile(); return () => { // }; });