I'm working on a little thing where an image will follow the mouse once hover on its (in this case) parent element. Could be whatever element. When testing, it works on the first data-tail-list
, but when hover on second data-tail-list
or third or however many i choose to have in my markup, the image that follows the cursor gets an offset, which increases depending on how far from the browsers top the current hovered data-tail-list
is. What am i doing wrong here?
Markup:
<div class="list w-full h-16 bg-white mb-8" data-tail-list>
<div class="absolute pointer-events-none w-64 h-96 max-w-full opacity-0 inset-0" data-tail-wrap>
<div class="absolute w-full h-full inset-0" data-tail-item>
<img src="./dist/img/test1.jpg">
</div>
</div>
</div>
<div class="list w-full h-16 bg-white mb-8" data-tail-list>
<div class="absolute pointer-events-none w-64 h-96 max-w-full opacity-0 inset-0" data-tail-wrap>
<div class="absolute w-full h-full inset-0" data-tail-item>
<img src="./dist/img/test2.jpg">
</div>
</div>
</div>
JS:
import gsap from 'gsap'
export default class Tail {
constructor() {
const lists = [...document.querySelectorAll('[data-tail-list]')]
lists.forEach((el) => {
el.addEventListener('mouseenter', this.onEnter)
el.addEventListener('mouseleave', this.onLeave)
el.addEventListener('mousemove', this.onMove)
})
}
onEnter(e) {
const el = e.currentTarget.querySelectorAll('[data-tail-wrap]')
gsap.to(el, {
opacity: 1
})
}
onMove(e) {
const el = e.currentTarget.querySelectorAll('[data-tail-item]')
gsap.to(el,{
x:e.clientX,
y:e.pageY - e.currentTarget.getBoundingClientRect().top - e.currentTarget.querySelector('[data-tail-wrap]').offsetHeight/2
})
}
onLeave(e) {
const el = e.currentTarget.querySelector('[data-tail-wrap]')
gsap.to(el, {
opacity: 0
})
}
}
@Math on comments :
Ok, do you mind providing some code?
Would really appreciate it!
Since you insist...
Here is only a simple example of moving a Dom element based on the delta X and Y of the mouse movement reported on the moved element.
const myDiv = document.querySelector('#my-div');
myDiv.mov = { x: 0, y: 0, mx:0, my:0 };
myDiv.onmousedown =({clientX:x,clientY:y})=> // on element mouse down
{
myDiv.classList.add('onMov');
Object.assign( myDiv.mov, {x,y}); // get mouse position
myDiv.mov.x -= myDiv.mov.mx; // prepare X delta
myDiv.mov.y -= myDiv.mov.my; // prepare Y delta
}
window.onmouseup =_=> // end of moving for any mouse up
{
myDiv.classList.remove('onMov')
}
window.addEventListener('mousemove', ({clientX:x,clientY:y}) =>
{
if (myDiv.classList.contains('onMov') && x > 0 && y > 0 )
{
myDiv.mov.mx = x - myDiv.mov.x; // report mouse delta X
myDiv.mov.my = y - myDiv.mov.y; // report mouse delta y
myDiv.style.setProperty('--movXY', `${myDiv.mov.mx}px, ${myDiv.mov.my}px`);
}
})
#my-div {
--movXY : 0px,0px;
background : dodgerblue;
border : 1px solid #d3d3d3;
height : 50px;
width : 50px;
margin : 30px;
cursor : grab;
transform : translate(var(--movXY));
}
#my-div.onMov {
cursor : grabbing;
}
<div id="my-div"></div>