Reputation: 170
So this is somewhat of a math problem that I'd like to solve using JavaScript. I'm creating a fixed canvas on a website that outputs a different image based on every X amount of pixels scrolled from a particular .offset().top from the top of the window. I 'could' explicitly map a new image to a particular position but I've got a lot of images and it would behoove me to create a function that can handle this process multiple times until particular end point. I'm sort of stuck on how to express this and was wondering if anyone could steer me in the right direction.
EDIT
After consider @Richard Hamilton answer below I've been able to somewhat successfully implement his solution to my own project. It's a little verbose, but here's what I have...
// Preload Images
var totalImages = 203
var images = new Array()
for (var i = 1; i <= totalImages; i++) {
var filename = 'img_'
if (i < 10) filename += '00'
if (i > 9 && i < 100) filename += '0'
filename += i + '.jpg'
var img = new Image
img.src = '/images/temp/' + filename
images.push(img)
}
// Set initial frame index
var currentLocation = 0
// Canvas Context
var canv = document.getElementById('canvas')
var context = canv.getContext('2d')
$(canv)
.width(768)
.height(432)
// Frame Starting Location
var currentLocation = 0
// Determin the breakpoint increment to fit inside the context
var contextHeight = $('.about--context').height() - 200
var frameHeight = contextHeight / totalImages
// Set first breakpoint
var breakpoint = 63
// Get top of context in relation to window
var contextPos = $('.about--context').offset().top - $(window).scrollTop()
// Set where to start scrubbing through frames
var scrubStart = 62
// Initial scroll direction
var lastScrollTop = 0,
st,
direction
// Output the scroll direction as up or down
function detectDirection() {
st = window.pageYOffset;
if (st > lastScrollTop) {
direction = "down"
} else {
direction = "up"
}
lastScrollTop = st
return direction
}
window.addEventListener('scroll', function() {
var dir = detectDirection()
var contextPos = $('.about--context').offset().top - $(window).scrollTop()
var contextHeight = $('.about--context').height()
var frameHeight = contextHeight / totalImages
if (contextPos <= breakpoint && dir === 'down') {
breakpoint -= frameHeight
currentLocation++
context.drawImage(images[currentLocation], 0, 0, 768, 432)
console.log('Breakpoint = ' + breakpoint + ', index = ' + currentLocation)
}
if (contextPos > breakpoint && dir === 'up') {
breakpoint += frameHeight
currentLocation--
context.drawImage(images[currentLocation], 0, 0, 768, 432)
console.log('Breakpoint = ' + breakpoint + ', index = ' + currentLocation)
}
})
This mostly works, but there seems to be a discrepancy between how the frames change during scroll between a mouse wheel and a trackpad. The trackpad is much more sensitive and can get the breakpoint increment correctly, but the mouse wheel ends up scrolling through the section much quicker without correctly keeping up with the proper frame rate, so I never end up reach the final frame by the end of the section. Other than that the frames are moving correctly when scrolling up and down.
Upvotes: 3
Views: 2105
Reputation: 26444
Let's say you have an image tag. If you have a lot of different image files, it would be a good idea to store them in array. This is a hard coded example, but shows the general structure.
var image = document.getElementById("myImage");
var sources = ["image1.png", "image2.png", "image3.png", "image4.png"];
var i = 0;
var breakpoint = 100; // Change to whatever you like
window.addEventListener("scroll", function() {
var scrollDown = document.body.scrollTop;
if (scrollDown >= breakpoint) {
img.setAttribute(src, sources[i]);
breakpoint += 100; //Change to whatever you like
i++;
}
}
You could also have something like this included
var windowHeight = window.innerHeight;
var scrollBottom = document.body.clientHeight - document.body.scrollTop;
if (scrollBottom === windowHeight) {
// Do something
}
First set a breakpoint variable equal to the number of pixels you want to scroll. For an example, I chose 100 because it's a nice round number. You then attach an event listener on the window
object, to detect if a user is scrolling.
The scrollTop
function represents how far the top of the screen is from the top of the window. If that value is higher than the breakpoint, that's when we call our code. We then increment this by 100.
Upvotes: 4