I'm trying to 'transform' elements, img here when the mouse moves on the page. I have integrated a vanilla code to create this effect and thought I understoond it but it seems I was wrong. The element from the code snippet is the orange square (3.png), but I want to apply this effect on the human pic (2.png) behind aswell and can't figure out how. (here's the full code as I don't rly know what's messed up except for my whole architecture prbly: https://github.com/KPq66dw8L/b-code-fiverr)
<section class="container bot-container-img">
<img class="layer closeUp" src="images/1.png" data-speeed="2" alt="">
<img class="layer ellipse2" src="images/2.png" data-speeed="-5" alt="">
<img class="layer" src="images/images/3.png" data-speed="2" alt="">
</section>
CSS:
.bot-container-img {
grid-row-start: 3;
grid-column-start: 1;
grid-column-end: 3;
width: 100%;
height: 100%;
}
section {
position: relative;
width: 100%;
height: 100%;
overflow: hidden;
display: flex;
align-items: flex-end;
justify-content: flex-start;
}
section img {
position: absolute;
object-fit: cover;
width: 100%;
height: 100%;
}
JS:
document.addEventListener("mousemove", parallax);
function parallax(e){
this.querySelectorAll('.layer').forEach(layer => {
const speed = layer.getAttribute('data-speed')
const x = (window.innerWidth - e.pageX*speed)/100
const y = (window.innerHeight - e.pageY*speed)/100
layer.style.transform = `translateX(${x}px) translateY(${y}px)`
})
}
There were a few minor errors I corrected:
data-speeed="2"
corrected to data-speed="2"
getBoundingClientRect()
over window.innerWidth
/ window.innerHeight
left
, top
, width
, height
, and negative margin-left
and margin-top
- this allows the transform.translate
property to translate them relative to their centersapplyParallax
function, in case you wish to apply it to multiple section
elementsI also had to make some changes to get this to work with stackoverflow's snippet system:
<img>
I used <div class="img"></div>
, with css to colour different div.img
elements distinctlydiv.img
elements to make the effect more visible in the small windowdata-speed
to make the effect more obvioushtml
and body
elements fill the whole viewport (and the section
element fills the whole body
element)let applyParallax = section => {
section.addEventListener('mousemove', e => {
let { width, height } = section.getBoundingClientRect();
let offX = e.pageX - (width * 0.5);
let offY = e.pageY - (height * 0.5);
for (let layer of document.querySelectorAll('.img')) {
const speed = layer.getAttribute('data-speed')
const x = (offX * speed) / 100;
const y = (offY * speed) / 100;
layer.style.transform = `translateX(${x}px) translateY(${y}px)`
}
});
section.addEventListener('mouseleave', e => {
for (let layer of document.querySelectorAll('.img')) {
layer.style.transform = `translateX(0px) translateY(0px)`
}
});
};
applyParallax(document.querySelector('section'));
html, body { position: absolute; left: 0; top: 0; right: 0; bottom: 0; overflow: hidden; }
section {
position: relative;
width: 100%;
height: 100%;
overflow: hidden;
display: flex;
align-items: flex-end;
justify-content: flex-start;
}
section > .img {
position: absolute;
left: 50%; top: 50%;
width: 120px; height: 120px;
margin-left: -60px; margin-top: -60px;
}
section > .img.r { background-color: rgba(200, 0, 0, 0.5); }
section > .img.g { background-color: rgba(0, 200, 0, 0.4); }
section > .img.b { background-color: rgba(0, 0, 200, 0.3); }
<section class="container bot-container-img">
<div class="img r" data-speed="22"></div>
<div class="img g" data-speed="-5"></div>
<div class="img b" data-speed="32"></div>
</section>