1 2// import { preloadImages } from './utils.js'; 3 4// Variable to store the Lenis smooth scrolling object 5let lenis; 6 7// Selecting DOM elements 8 9const contentElements = [...document.querySelectorAll('.content--sticky')]; 10const totalContentElements = contentElements.length; 11 12// Initializes Lenis for smooth scrolling with specific properties 13const initSmoothScrolling = () => { 14 // Instantiate the Lenis object with specified properties 15 lenis = new Lenis({ 16 lerp: 0.2, // Lower values create a smoother scroll effect 17 smoothWheel: true // Enables smooth scrolling for mouse wheel events 18 }); 19 20 // Update ScrollTrigger each time the user scrolls 21 lenis.on('scroll', () => ScrollTrigger.update()); 22 23 // Define a function to run at each animation frame 24 const scrollFn = (time) => { 25 lenis.raf(time); // Run Lenis' requestAnimationFrame method 26 requestAnimationFrame(scrollFn); // Recursively call scrollFn on each frame 27 }; 28 // Start the animation frame loop 29 requestAnimationFrame(scrollFn); 30}; 31 32// Function to trigger Flip animations when scrolling 33const triggerFlipOnScroll = (galleryEl, options) => { 34 // Default settings for Flip and ScrollTrigger 35 let settings = { 36 flip: { 37 absoluteOnLeave: false, 38 absolute: false, 39 scale: true, 40 simple: true, 41 //... 42 }, 43 scrollTrigger: { 44 start: 'center center', 45 end: '+=300%', 46 }, 47 stagger: 0 48 }; 49 50 // Merge default settings with options provided when calling the function 51 settings = Object.assign({}, settings, options); 52 53 // Select elements within the gallery that will be animated 54 const galleryCaption = galleryEl.querySelector('.caption'); 55 const galleryItems = galleryEl.querySelectorAll('.gallery__item'); 56 const galleryItemsInner = [...galleryItems].map(item => item.children.length > 0 ? [...item.children] : []).flat(); 57 58 // Temporarily add the final class to capture the final state 59 galleryEl.classList.add('gallery--switch'); 60 const flipstate = Flip.getState([galleryItems, galleryCaption], {props: 'filter, opacity'}); 61 62 // Remove the final class to revert to the initial state 63 galleryEl.classList.remove('gallery--switch'); 64 65 // Create the Flip animation timeline 66 const tl = Flip.to(flipstate, { 67 ease: 'none', 68 absoluteOnLeave: settings.flip.absoluteOnLeave, 69 absolute: settings.flip.absolute, 70 scale: settings.flip.scale, 71 simple: settings.flip.simple, 72 scrollTrigger: { 73 trigger: galleryEl, 74 start: settings.scrollTrigger.start, 75 end: settings.scrollTrigger.end, 76 pin: galleryEl.parentNode, 77 scrub: true, 78 }, 79 stagger: settings.stagger 80 }); 81 82 // If there are inner elements in the gallery items, animate them too 83 if ( galleryItemsInner.length ) { 84 tl.fromTo(galleryItemsInner, { 85 scale: 2 86 }, { 87 scale: 1, 88 scrollTrigger: { 89 trigger: galleryEl, 90 start: settings.scrollTrigger.start, 91 end: settings.scrollTrigger.end, 92 scrub: true, 93 }, 94 }, 0) 95 } 96}; 97
98// Function to handle scroll-triggered animations 99const scroll = () => { 100 101 // Define the gallery IDs and their options 102 const galleries = [ 103 { id: '#gallery-2' }, 104 { id: '#gallery-12' }, 105 // { id: '#gallery-3', options: { flip: { absolute: true, scale: false }, scrollTrigger: { start: 'center center', end: '+=900%' }, stagger: 0.05 } }, 106 // { id: '#gallery-4' }, 107 // { id: '#gallery-5' }, 108 // { id: '#gallery-6' }, 109 { id: '#gallery-7' }, 110 // { id: '#gallery-8', options: { flip: { scale: false } } }, 111 // { id: '#gallery-9' }, 112 // { id: '#gallery-1' }, 113 // { id: '#gallery-2' }, 114 // { id: '#gallery-3' }, 115 // { id: '#gallery-4' }, 116 // { id: '#gallery-5' }, 117 // { id: '#gallery-6' }, 118 // { id: '#gallery-7' }, 119 // { id: '#gallery-8' }, 120 { id: '#gallery-9' } 121 ]; 122 123 // Loop through the galleries and apply the scroll-triggered animations 124 galleries.forEach(gallery => { 125 const galleryElement = document.querySelector(gallery.id); 126 triggerFlipOnScroll(galleryElement, gallery.options); 127 }); 128 129 contentElements.forEach((el, position) => { 130 131 const isLast = position === totalContentElements-1; 132 133 gsap.timeline({ 134 scrollTrigger: { 135 trigger: el, 136 start: 'top top', 137 end: '+=100%', 138 scrub: true 139 } 140 }) 141 .to(el, { 142 ease: 'none', 143 startAt: {filter: 'brightness(100%) contrast(100%)'}, 144 filter: isLast ? 'none' : 'brightness(60%) contrast(135%) ', 145 yPercent: isLast ? 0 : -15 146 }, 0) 147 // Animate the content inner image 148 .to(el.querySelector('.content__img'), { 149 ease: 'power1.in', 150 yPercent: -40, 151 rotation: -20 152 }, 0); 153 }); 154 155}; 156 157// Initialization function 158// const init = () => { 159// initSmoothScrolling(); // Initialize Lenis for smooth scrolling 160// scroll(); // Apply scroll-triggered animations 161// }; 162 163// initSmoothScrolling(); // Initialize Lenis for smooth scrolling 164scroll(); // Apply scroll-triggered animations 165
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.