Reputation: 1
I couldn't find an example where this image sequence animation is triggered at any other part except on the top of the website.
The animation is working fine as it is, the problem is: if i put any content above the canvas, the image sequence will still be linked to the top of the page. So when the user gets to the animation, they will see it already half way through.
I'd like to ask for your help to change the starting point of this animation to only when it enters the viewport, not necessarily on the top of the page.
I'll also leave a link to the same exact snippet running on codepen, just in case: https://codepen.io/querubim_reginaldo/pen/OJzoOXK
Thanks in advance!
const html = document.documentElement;
const canvas = document.getElementById("pro_display_animation");
const context = canvas.getContext("2d");
const currentFrame = index => (
`https://www.apple.com/105/media/us/airpods-pro/2019/1299e2f5_9206_4470_b28e_08307a42f19b/anim/sequence/large/01-hero-lightpass/${(index + 1).toString().padStart(4, '0')}.jpg`
);
// total of image files
const frameCount = 160;
// sets the canvas size to full screen
canvas.width = document.documentElement.clientWidth * 1;
canvas.height = document.documentElement.clientHeight * 1;
// draws the first image on screen
const img = new Image();
img.src = currentFrame(1);
img.onload = function() {
context.drawImage(img, 0, 0);
};
// updates the image in sequence
const updateImage = index => {
img.src = currentFrame(index);
context.drawImage(img, 0, 0);
}
// links the scroll position with the correct image
window.addEventListener('scroll', () => {
const scrollTop = html.scrollTop;
const maxScrollTop = html.scrollHeight - window.innerHeight;
const scrollFraction = scrollTop / maxScrollTop;
const frameIndex = Math.min(
frameCount - 1,
Math.ceil(scrollFraction * frameCount)
);
requestAnimationFrame(() => updateImage(frameIndex + 1))
});
body {
margin: 0;
padding: 0;
}
#section_canvas_animation {
display: flex;
justify-content: center;
align-items: flex-start;
height: 1200vh;
width: 100vw;
background: #efefef;
}
canvas {
position: sticky;
top: 0;
max-width: 100vw;
max-height: 100vh;
}
.website_content {
height: 400vh;
background: darkcyan;
display: flex;
justify-content: center;
align-items: center;
color: white;
font-size: 100px;
}
<body>
<div id="section_canvas_animation">
<canvas id="pro_display_animation"></canvas>
</div>
<div class="website_content">THIS IS SOME WEBSITE CONTENT</div>
</body>
`
Upvotes: 0
Views: 1665
Reputation: 21
Check my demo here: https://www.sfertons.dev/lab/apple-scroll-sequence-animation
The trick is to take the "animation sequence" offsetTop into account and use its scrollHeight to calculate the maxScrollTop:
const scrollTop = document.documentElement.scrollTop - heroSequence.offsetTop
const maxScrollTop = heroSequence.scrollHeight - window.innerHeight
The project is also on my Github: https://github.com/Spharian/apple-sequence-animation
Upvotes: 2