1document.addEventListener('DOMContentLoaded', function() { 2 // Ensure contentMarkers is initialized after DOM is fully loaded 3 const contentMarkers = gsap.utils.toArray(".content-marker"); 4 5 gsap.defaults({ overwrite: 'auto' }); 6 7 // Set initial visibility and opacity for all images 8 gsap.set(".img-sticky > img", { xPercent: -50, yPercent: -50, opacity: 0, visibility: 'hidden' }); 9 10 // Delay ScrollTrigger creation until contentMarkers is initialized 11 const ST = ScrollTrigger.create({ 12 trigger: "#sticky-scroll .site-container", 13 start: "top top", 14 end: "bottom bottom", 15 onUpdate: getCurrentSection, 16 pin: ".img-sticky" 17 }); 18 19 // Set up content behaviors for each marker 20 contentMarkers.forEach((marker, index) => { 21 marker.content = document.querySelector(`#${marker.dataset.markerContent}`); 22 23 // Ensure we're only targeting images for transitions 24 if (marker.content && marker.content.tagName === "IMG") { 25 gsap.set(marker.content, { transformOrigin: "center" }); 26 27 // If it's the first image, set it to be visible immediately 28 if (index === 0) { 29 gsap.set(marker.content, { opacity: 1, visibility: 'visible' }); 30 } else { 31 // Add enter/leave methods for other images 32 marker.content.enter = function() { 33 gsap.fromTo(marker.content, { autoAlpha: 0, visibility: 'hidden' }, { duration: 0.3, autoAlpha: 1, visibility: 'visible', rotateY: 0 }); 34 }; 35 36 // Leave animation for images 37 marker.content.leave = function() { 38 gsap.to(marker.content, { duration: 0.1, autoAlpha: 0, visibility: 'hidden' }); 39 }; 40 } 41 } 42 }); 43 44 // Handle updated scroll position 45 let lastContent; 46 function getCurrentSection() { 47 const currScroll = window.scrollY; 48 let newContent; 49 50 // Loop through markers and check which one is currently in view 51 contentMarkers.forEach(marker => { 52 const markerTop = marker.getBoundingClientRect().top + window.scrollY; // Correct calculation for scroll position 53 54 // Compare current scroll position with marker's position 55 if (currScroll >= markerTop - window.innerHeight / 2 && currScroll < markerTop + marker.offsetHeight) { 56 newContent = marker.content; 57 } 58 }); 59 60 // If the current section is different than the last, animate it in 61 if (newContent && (lastContent == null || !newContent.isSameNode(lastContent))) { 62 if (lastContent && lastContent.leave) { 63 lastContent.leave(); // Fade out last section if the leave method exists 64 } 65 66 // Skip fade-in animation for the first image 67 if (newContent !== contentMarkers[0].content && newContent.enter) { 68 newContent.enter(); // Fade in new section (except for first image) 69 } 70 71 lastContent = newContent; 72 } 73 } 74});
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.