I’m trying to create a diagonal gallery that moves with scroll, but when I scroll too fast the sliders (pictures) don’t return to their positions, I tried to solve this problem, but it doesn’t look good, the pictures have to return to a position when I scroll up or down without getting disordered.
examples:
https://www.env.studio/
https://3rcore.com/
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="styles.css">
<title>Locomotive scrolling</title>
</head>
<body>
<div class="container">
<div class="container__gallery">
<div class="slide__1">
<div class="img1">
</div>
<div class="img2">
</div>
<div class="img3">
</div>
<div class="img4">
</div>
</div>
<div class="slide__2">
<div class="img2"></div>
<div class="img4">
</div>
<div class="img1">
</div>
<div class="img3">
</div>
</div>
<div class="slide__3">
<div class="img1">
</div>
<div class="img3">
</div>
<div class="img2">
</div>
<div class="img4">
</div>
</div>
<div class="slide__4">
<div class="img4">
</div>
<div class="img1">
</div>
<div class="img2">
</div>
<div class="img3">
</div>
</div>
</div>
</div>
</body>
<script src="main.js"></script>
</html>
*{
margin: 0;
padding: 0;
}
.container{
background-color: white;
width: 100%;
height: 800px;
margin-top: 1000px;
margin-bottom: 1000px;
display: flex;
align-items: center;
justify-content: center;
}
.container__gallery{
position: relative;
background-color: white;
width: 70%;
height: 80%;
overflow: hidden;
border-radius: 8px;
}
.slide__1, .slide__2, .slide__3, .slide__4{
position: absolute;
background-color: white;
width: 140%;
height: 40%;
display: flex;
margin-bottom: 5px;
transform: skew(-10deg) rotateZ(20deg);
}
.slide__1{
top: -37px;
right: -830px;
transition: all 50ms ease-in;
}
.slide__2{
top: 10px;
right: -190px;
transition: all 50ms ease-in;
}
.slide__3{
top: 400px;
right: -430px;
transition: all 50ms ease-in;
}
.slide__4{
top: 568px;
right: -100px;
transition: all 50ms ease-in;
}
.img1{
background-color: blueviolet;
background-image: url("https://static.fundacion-affinity.org/cdn/farfuture/PVbbIC-0M9y4fPbbCsdvAD8bcjjtbFc0NSP3lRwlWcE/mtime:1643275542/sites/default/files/los-10-sonidos-principales-del-perro.jpg");
background-position: center;
background-size: cover;
background-repeat: no-repeat;
height: 100%;
width: 25%;
margin-right: 5px;
}
.img2{
background-color: orange;
background-image: url("https://media.glamour.mx/photos/6529b544daab1b14402e2b34/16:9/w_2992,h_1683,c_limit/qu%C3%A9-significa-encontrarte-con-un-gato-negro-en-viernes-13-.png");
background-position: center;
background-size: cover;
background-repeat: no-repeat;
height: 100%;
width: 25%;
margin-right: 5px;
}
.img3{
background-color: crimson;
background-image: url("https://ca-times.brightspotcdn.com/dims4/default/796e6c9/2147483647/strip/true/crop/1970x1108+39+0/resize/1200x675!/quality/75/?url=https%3A%2F%2Fcalifornia-times-brightspot.s3.amazonaws.com%2F12%2Fa5%2F79e097ccf62312d18a025f22ce48%2Fhoyla-recuento-11-cosas-aman-gatos-top-001");
background-position: center;
background-size: cover;
background-repeat: no-repeat;
height: 100%;
width: 25%;
margin-right: 5px;
}
.img4{
background-color: black;
background-image: url("https://www.ngenespanol.com/wp-content/uploads/2023/12/descubren-que-los-humanos-influimos-en-el-color-de-ojos-de-los-perros-1280x720.jpg");
background-position: center;
background-size: cover;
background-repeat: no-repeat;
height: 100%;
width: 25%;
margin-right: 5px;
}
const element = document.querySelector('.container__gallery')
const slider1 = document.querySelector('.slide__1')
const slider2 = document.querySelector('.slide__2')
const slider3 = document.querySelector('.slide__3')
const slider4 = document.querySelector('.slide__4')
let lastScrollTop = 0
let control = {
top1: -37,
right1: -830,
top2: 10,
right2: -190,
top3: 400,
right3: -430,
top4: 350,
right4: 460,
}
const options = {
root: null,
rootMargin: '600px',
threshold: 0.05
}
const observer = new IntersectionObserver(callback, options)
observer.observe(element)
function validateScrolling(){
const currentScrollTop = window.pageYOffset || document.documentElement.scrollTop;
const isScrollingDown = currentScrollTop > lastScrollTop;
lastScrollTop = currentScrollTop;
return isScrollingDown;
}
function move(isScrollingDown){
// Definir el ángulo en radianes (20 grados)
const anguloRadianes = 158.72 * (Math.PI / 180);
const scale = 0.01;
let deltaX = 0
let deltaY = 0
const scrollY = window.scrollY || window.pageYOffset;
if(!(isScrollingDown ===false && scrollY <= 200 && scrollY >= 122))
// Calcular el cambio en las coordenadas X e Y utilizando funciones trigonométricas
deltaX = scrollY * Math.cos(anguloRadianes) * scale;
deltaY = scrollY * Math.sin(anguloRadianes) * scale;
return {deltaX, deltaY}
}
function scrollerEvent(){
let isScrollingDown = validateScrolling()
let delta = move(isScrollingDown)
if(isScrollingDown == false && scrollY <= 200 && scrollY >= 120){
control.right1 = -830;
control.top1 = -37;
control.right2 = -190;
control.top2 = 10;
control.right3 = -430 ;
control.top3 = 400 ;
control.right4 = 460;
control.top4 = 350;
slider1.style.right = control.right1 + "px";
slider1.style.top = control.top1 + "px";
slider2.style.right = control.right2 + "px";
slider2.style.top = control.top2 + "px";
slider3.style.right = control.right3 + "px";
slider3.style.top = control.top3 + "px";
slider4.style.right = control.right4 + "px";
slider4.style.top = control.top4 + "px";
}
else if(isScrollingDown == false && scrollY <= 1000 && scrollY >= 977){
control.right1 = -537.9142029413038 ;
control.top1 = -150.7620539573103;
control.right2 = -482.0857970586964 ;
control.top2 = 123.7620539573103;
control.right3 = -225.5399420589124 ;
control.top3 = 320.36656222988285 ;
control.right4 = 167.91420294130347;
control.top4 = 463.76205395731006;
slider1.style.transition = "600ms"
slider1.style.right = control.right1 + "px";
slider1.style.top = control.top1 + "px";
//slider1.style.transition = "50ms"
slider2.style.transition = "600ms"
slider2.style.right = control.right2 + "px";
slider2.style.top = control.top2 + "px";
//slider2.style.transition = "50ms"
slider3.style.transition = "600ms"
slider3.style.right = control.right3 + "px";
slider3.style.top = control.top3 + "px";
slider4.style.transition = "600ms"
slider4.style.right = control.right4 + "px";
slider4.style.top = control.top4 + "px";
//slider4.style.transition = "50ms"
}
else if (isScrollingDown){
// Actualizar las coordenadas del objeto
control.right1 -= delta.deltaX;
control.top1 -= delta.deltaY;
control.right2 += delta.deltaX;
control.top2 += delta.deltaY;
control.right3 -= (delta.deltaX * 0.7);
control.top3 -= (delta.deltaY * 0.7);
control.right4 += delta.deltaX;
control.top4 += delta.deltaY;
slider1.style.transition = "50ms"
slider1.style.right = control.right1 + "px";
slider1.style.top = control.top1 + "px";
slider2.style.transition = "50ms"
slider2.style.right = control.right2 + "px";
slider2.style.top = control.top2 + "px";
slider3.style.transition = "50ms"
slider3.style.right = control.right3 + "px";
slider3.style.top = control.top3 + "px";
slider4.style.transition = "50ms"
slider4.style.right = control.right4 + "px";
slider4.style.top = control.top4 + "px";
}
else{
// Actualizar las coordenadas del objeto
control.right1 += delta.deltaX;
control.top1 += delta.deltaY;
control.right2 -= delta.deltaX;
control.top2 -= delta.deltaY;
control.right3 += (delta.deltaX *0.7);
control.top3 += (delta.deltaY *0.7);
control.right4 -= delta.deltaX;
control.top4 -= delta.deltaY;
slider1.style.transition = "50ms"
slider1.style.right = control.right1 + "px";
slider1.style.top = control.top1 + "px";
slider2.style.transition = "50ms"
slider2.style.right = control.right2 + "px";
slider2.style.top = control.top2 + "px";
slider3.style.transition = "50ms"
slider3.style.right = control.right3 + "px";
slider3.style.top = control.top3 + "px";
slider4.style.transition = "50ms"
slider4.style.right = control.right4 + "px";
slider4.style.top = control.top4 + "px";
}
}
function callback(entries){
entries.forEach(entry =>{
let intersecting = entry.isIntersecting
if (intersecting){
lastScrollTop = window.pageYOffset || document.documentElement.scrollTop;
window.addEventListener("scroll", scrollerEvent)
}
else{
window.removeEventListener("scroll", scrollerEvent);
}
})
}