<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>
body {
margin: 0;
padding: 0;
}
#scroll-trigger-container {
position: relative;
height: 500vh;
width: 100%;
}
.pinned-container {
position: sticky;
top: 0;
height: 0;
}
.ball {
position: absolute;
width: 5rem;
height: 5rem;
border-radius: 100%;
background-color: red;
}
.line {
position: absolute;
width: 0.2rem;
background: black;
border-radius: 100%;
opacity: 0;
}
.ball-1 {
top: calc(20% - 0.5 * 5rem);
left: calc(43% - 0.5 * 5rem);
}
.ball-2 {
top: calc(35% - 0.5 * 5rem);
left: calc(70% - 0.5 * 5rem);
}
.ball-3 {
top: calc(45% - 0.5 * 5rem);
left: calc(32% - 0.5 * 5rem);
}
.ball-4 {
top: calc(55% - 0.5 * 5rem);
left: calc(60% - 0.5 * 5rem);
}
.ball-5 {
top: calc(65% - 0.5 * 5rem);
left: calc(50% - 0.5 * 5rem);
}
.ball-6 {
top: calc(75% - 0.5 * 5rem);
left: calc(55% - 0.5 * 5rem);
}
.line-1 {
left: calc(50% - 0.1rem);
height: 80%;
}
.ball-line {
opacity: 0;
position: absolute;
width: 0.2rem;
background: black;
border-radius: 100%;
}
.ball-line-1 {
top: calc(50% - 0.5 * 0.2rem);
width: 500%;
height: 0.2rem;
left: -10rem;
}
.ball-line-2 {
top: calc(50% - 0.5 * 0.2rem);
width: 500%;
height: 0.2rem;
left: -10rem;
}
.ball-line-3 {
top: calc(50% - 0.5 * 0.2rem);
width: 500%;
height: 0.2rem;
left: -10rem;
}
.ball-line-4 {
top: calc(50% - 0.5 * 0.2rem);
width: 500%;
height: 0.2rem;
left: -10rem;
}
.ball-line-5 {
top: calc(50% - 0.5 * 0.2rem);
width: 500%;
height: 0.2rem;
left: -10rem;
}
.ball-line-6 {
top: calc(50% - 0.5 * 0.2rem);
width: 500%;
height: 0.2rem;
left: -10rem;
}
</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>
<script src="https://hammerjs.github.io/dist/hammer.min.js"></script>
<div id="scroll-trigger-container">
<div class="pinned-container">
<div class="ball ball-1"><div class="ball-line ball-line-1"></div></div>
<div class="ball ball-2"><div class="ball-line ball-line-2"></div></div>
<div class="ball ball-3"><div class="ball-line ball-line-3"></div></div>
<div class="ball ball-4"><div class="ball-line ball-line-4"></div></div>
<div class="ball ball-5"><div class="ball-line ball-line-5"></div></div>
<div class="ball ball-6"><div class="ball-line ball-line-6"></div></div>
<div class="line line-1"></div>
<div class="line"></div>
<div class="line"></div>
<div class="line"></div>
<div class="line"></div>
</div>
</div>
</body>
</html>
<script>
gsap.registerPlugin(ScrollTrigger);
const progressRef = document.querySelector('progress');
const eventListener = (e) => {
gsap.to('.ball-1', {x: e.clientX, y: e.clientY, top: '0', left: '0', duration: 1});
gsap.to('.ball-line-1', {opacity: 0});
}
const pinnedContainerRef = document.querySelector('.pinned-container');
const timeline = gsap.timeline({
scrollTrigger: {
trigger: "#scroll-trigger-container",
markers: true,
scrub: true,
start: "top top",
end: "bottom bottom",
onLeave: (e) => {
pinnedContainerRef.addEventListener('mousemove', eventListener);
},
onEnterBack: () => {
pinnedContainerRef.removeEventListener('mousemove', eventListener);
gsap.to('.ball-1', {left: 'calc(43% - 0.5 * 5rem)', top: 'calc(20% - 0.5 * 5rem)', x: '0', y: '0', duration: 1});
gsap.to('.ball-line-1', {opacity: 0});
}
}
});
timeline.addLabel('spread-circles')
.to('.pinned-container', {height: '100vh'})
.to('.line', {opacity: 1})
.to('.ball-line', {opacity: 1})
</script>