I did an animation on scroll with jpeg images that cover the whole page and it works quite well for the most part but when i reach the bottom of the page, the last image doesn't show up.
Chat-gpt was a real help to make it relatively responsive but this problem resulted from the his responsive modified version.
here is the script :
const html = document.documentElement;
const canvas = document.getElementById("canvas1");
const context = canvas.getContext("2d");
const frameCount = 750;
const imageBasePath = 'images/photo_animation4/';
const currentFrame = index => (
`${imageBasePath}${index.toString().padStart(4, '0')}.jpg`
);
const preloadImages = () => {
const images = [];
for (let i = 1; i < frameCount; i++) {
const img = new Image();
img.src = currentFrame(i);
images.push(img);
}
return images;
};
let images = preloadImages();
let currentFrameIndex = 6;
let imageLoaded = false;
const updateCanvasSize = () => {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
if (imageLoaded) {
updateImage(currentFrameIndex);
}
};
window.addEventListener('resize', () => {
updateCanvasSize();
});
const firstImage = new Image();
firstImage.src = currentFrame(1);
firstImage.onload = function () {
imageLoaded = true;
updateCanvasSize();
};
const updateImage = index => {
const img = images[index - 1];
context.clearRect(0, 0, canvas.width, canvas.height);
context.drawImage(img, 0, 0, canvas.width, canvas.height);
};
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)
);
if (frameIndex + 1 !== currentFrameIndex) {
currentFrameIndex = frameIndex + 1;
updateImage(currentFrameIndex);
}
});
setTimeout(() => {
updateImage(currentFrameIndex);
}, 1000);
This is my first time asking for help on stack overflow so advices on question asking are very welcome.
In your code you are excluding the last frame (750) I'm assuming that is your last image ...
The initialization uses the loop:
... let i = 1; i < frameCount ...
That stops are 749
Then in your
frameIndex
calculation you have:... Math.min(frameCount - 1, ...
that also excludes the last valueTo debug that you can add some
console.log
statement and add some debug text to the canvasHere is a small example showing that...
I'm simulating the scroll with the mousemove over the canvas in the X axis
We can fix that loop with:
i <= frameCount
In the frameIndex calculation we can remove the:
Math.min(frameCount-1
See working code below: