Gallery reveal with slow motion
Offset
<html>
<head>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A==" crossorigin=""/>
<link rel="stylesheet" href="https://unpkg.com/@picocss/pico@latest/css/pico.min.css">
<style>
.container {
height: 80vh;
}
#scroll-trigger-container {
height: 300vh;
position: relative;
}
.pinned-container {
position: sticky;
overflow: hidden;
max-height: 100vh;
top: 0;
}
.overflow-container {
position: relative;
padding: 10vh 0;
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
}
img {
width: 20vw;
height: auto;
padding: 2vw;
opacity: 0;
}
img:nth-child(2n){
margin-top: 10vh;
}
img:nth-child(4n){
margin-top: -20vh;
}
</style>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet-gpx/1.7.0/gpx.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.8.0/gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.8.0/ScrollTrigger.min.js"></script>
<article class="container"><h1>Gallery reveal with slow motion</h1></article>
<div id="scroll-trigger-container">
<div class="pinned-container">
<div class="overflow-container">
<img src="https://picsum.photos/200/300?random=1" />
<img src="https://picsum.photos/200/300?random=2" />
<img src="https://picsum.photos/200/300?random=3" />
<img src="https://picsum.photos/200/300?random=4" />
<img src="https://picsum.photos/200/300?random=1" />
<img src="https://picsum.photos/200/300?random=2" />
<img src="https://picsum.photos/200/300?random=3" />
<img src="https://picsum.photos/200/300?random=4" />
<img src="https://picsum.photos/200/300?random=3" />
<img src="https://picsum.photos/200/300?random=4" />
</div>
</div>
</div>
<article class="container"><h1>Offset</h1></article>
</body>
</html>
<script>
gsap.registerPlugin(ScrollTrigger);
const timeline = gsap.timeline({
scrollTrigger: {
trigger: "#scroll-trigger-container",
markers: true,
start: "top bottom",
scrub: 0.2,
end: `bottom bottom`,
}});
const overflowContainer = document.querySelector('.overflow-container');
const height = overflowContainer.getBoundingClientRect().height;
timeline.add('start');
timeline.to('img', { opacity: 1, delay: "random(0, 0.1)" }, 'start');
timeline.to('.overflow-container', {top: `-${window.innerHeight - height}px`}, 'start+=50%');
// timeline.to('img', { opacity: 1, y: 20, stagger: { // wrap advanced options in an object
// each: 0.2,
// from: "center"
// }}, 'start');
// timeline.to('img', { opacity: 0, y: 20, stagger: 0.1 }, 'start-=1');
</script>