scroll driven image sequence animation only plays first animation

4 days ago 2
ARTICLE AD BOX

I want to put 'multiple scroll driven image sequence animations' on the same page. I tried many times but I cannot get the solution.

Whatever I tried, only the top one is working, but the others are just blank. Can you help me solve this?

My page structure is like this:

=========== header =========== -------------------------------------- --- image sequence animation A --- -------------------------------------- < -------------------------------------- --- image sequence animation B --- -------------------------------------- < -------------------------------------- --- image sequence animation C --- -------------------------------------- < ============ footer ============

The original demo page is here.

The demo page code:

html

<div class="hero"> <h1>Apple Sequence Animation</h1> <p>Scroll down to admire the magic.</p> </div> <div class="hero-sequence"> <div class="sticky-element"> <div class="sequence-element"> <canvas width="1336" height="786"></canvas> </div> </div> </div> <footer> You are awesome! </footer>

css

body { margin: 0; font-family: -apple-system, sans-serif; color: #1d1d1f; } h1 { font-size: 40px; margin: 0 0 10px; } p { font-size: 22px; } .hero { padding: 40px; text-align: center; } .hero-sequence { height: 430vh; } .sticky-element { position: sticky; top: 0; height: 100vh; min-height: 1033px; overflow: hidden; display: grid; place-items: center; } .sequence-element { width: 1336px; height: 786px; } footer { background: #f5f5f7; font-weight: 700; font-size: 40px; height: 400px; display: grid; place-items: center; }

javascript

const canvas = document.querySelector('canvas') const ctx = canvas.getContext('2d') const heroSequence = document.querySelector('.hero-sequence') const images = [] const frameCount = 87 const prepareImages = () => { for (var i = 0; i < frameCount; i++) { const image = new Image() image.src = `https://spharian.vercel.app/lab/apple-sequence-animation/images/${i}.jpg` images.push(image) if (i === 0) { images[i].onload = () => drawImage(0) } } } const drawImage = frameIndex => { ctx.drawImage(images[frameIndex], 0, 0) } prepareImages() window.addEventListener('scroll', () => { const scrollTop = document.documentElement.scrollTop - heroSequence.offsetTop const maxScrollTop = heroSequence.scrollHeight - window.innerHeight const scrollFraction = scrollTop / maxScrollTop const frameIndex = Math.max(0, Math.min(frameCount - 1, Math.ceil(scrollFraction * frameCount))) images[frameIndex].onload = () => drawImage(frameIndex) requestAnimationFrame(() => drawImage(frameIndex)) })

MaanBek Yi's user avatar

New contributor

MaanBek Yi is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.

1

Read Entire Article