I’m trying to program a webpage animation where a user can have the choice of clicking & dragging or simply scrolling using the mouse wheel to view a vertical stack of images. Click & drag works fine, however the scrolling input doesn’t work as desired. When I attempt to scroll though the pictures, input doesn’t seem to register. When I click & drag first, and then scroll, the scroll feature works.
Html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<title>CoolEffect</title>
</head>
<body>
<div id = "image-track" data-mouse-down-at = "0" data-prev-percentage = "0">
<img class="image" src="assets/photo-1542051841857-5f90071e7989.jpeg" draggable="false">
<img class="image" src="assets/photo-1533050487297-09b450131914.jpeg" draggable="false">
<img class="image" src="assets/photo-1564284369929-026ba231f89b.jpeg" draggable="false">
<img class="image" src="assets/photo-1528360983277-13d401cdc186.jpeg" draggable="false">
<img class="image" src="assets/photo-1492571350019-22de08371fd3.jpeg" draggable="false">
<img class="image" src="assets/photo-1532884928231-ef40895eb654.jpeg" draggable="false">
<img class="image" src="assets/photo-1540959733332-eab4deabeeaf.jpeg" draggable="false">
</div>
<script src="script.js"></script>
</body>
</html>
CSS
body{
height: 100vh;
width: 100vw;
background-color: black;
margin: 0rem;
overflow: hidden;
}
#image-track > .image {
width: 150vmin;
height: 50vmin;
object-fit: cover;
object-position: 100% 0%;
}
#image-track {
display: flex;
flex-direction: column;
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
}
JavaScript
const track = document.getElementById("image-track");
window.onmousedown = e => {
track.dataset.mouseDownAt = e.clientY;
}
window.onmouseup = () => {
track.dataset.mouseDownAt = "0";
track.dataset.prevPercentage = track.dataset.percentage;
}
window.onmousemove = e => {
if(track.dataset.mouseDownAt === "0") return;
const mouseDelta = parseFloat(track.dataset.mouseDownAt) - e.clientY,
maxDelta = window.innerHeight;
let percentage = (mouseDelta / maxDelta) * -100,
nextPercentage = parseFloat(track.dataset.prevPercentage) + percentage;
nextPercentage = Math.max(-100, Math.min(0, nextPercentage));
track.dataset.percentage = nextPercentage;
track.animate(
{transform :`translate(-50%, ${nextPercentage}%)`},
{duration: 1200, fill: "forwards"});
for(const image of track.getElementsByClassName("image")){
image.animate(
{objectPosition : `50% ${nextPercentage + 100}%`},
{duration: 1200, fill: "forwards"});
}
}
window.addEventListener("wheel", e => {
e.preventDefault();
const deltaY = e.deltaY;
const maxDelta = window.innerHeight;
let percentage = (deltaY / maxDelta) * -100,
nextPercentage = parseFloat(track.dataset.percentage) + percentage;
nextPercentage = Math.max(-100, Math.min(0, nextPercentage));
track.dataset.percentage = nextPercentage;
track.animate(
{ transform: `translate(-50%, ${nextPercentage}%)` },
{ duration: 1200, fill: "forwards" }
);
for (const image of track.getElementsByClassName("image")) {
image.animate(
{ objectPosition: `50% ${nextPercentage + 100}%` },
{ duration: 1200, fill: "forwards" }
);
}
scrollStartY = e.pageY;
});
What I expected to happen was regardless of previous input, the user can scroll or click & drag to view the images. Without clicking and dragging first, the user is unable to do so. I first thought the issue lied in the default scrolling behaviour of the page, so I added to e.preventDefault() to negate this. This however wasn’t the issue. Any suggestions as to what could be causing the issue?