When mousemove() it only gets the position of first item. Now they are all overlapping. How can I improve this?
https://codepen.io/penny289/pen/JjJzYbv
CodePudding user response:
It does not get the coordinates of the first image only. Rather, you seem to have several problems:
- You are dividing by 100, presumably because you are working with percentages, but unless your screen is 100 pixels wide that is obviously wrong.
- .offset() does return an offset relative to the document, but you are positioning your items relative to your container
- You are trying to dynamically grab the offset every time, but if you go for this approach you would need to know what part of that offset is from the previous time you called this function. Otherwise you start accumulating the x and y position of your MouseEvent and quickly move the entire thing off the screen.
There is no reason for you to use percentages, so just work with absolute pixels and simplify your code.
Then store the initial offset with .data(..)
so you don't have to subtract your previous mouse position and keep track of that every single time. Since you want to have the offset relative to the container (because your css renders it relative to the container), subtract the container offset from your image offset.
Now you can make the images move with your mouse by adding your mouse pageX/pageY.
Besides that, you should use a debounce (does not work in stacksnippets) and window.requestAnimationFrame
so your cpu does not melt trying to draw something for every pixel your mouse moves, but rather only when it is ready to draw a single frame.
$(window).mousemove(function(evt){
//_.debounce(() => {
window.requestAnimationFrame(() => {
const containerOffsetX = $('.container').offset().left;
const containerOffsetY = $('.container').offset().top;
$('.img-box').each(function(elem, i){
let imageOffsetX = $(this).data('offsetX');
if (!imageOffsetX) {
imageOffsetX = $(this).offset().left - containerOffsetX;
$(this).data('offsetX', imageOffsetX);
}
let imageOffsetY = $(this).data('offsetY');
if (!imageOffsetY) {
imageOffsetY = $(this).offset().top - containerOffsetY;
$(this).data('offsetY', imageOffsetY);
}
const mouseOffsetX = evt.pageX;
const mouseOffsetY = evt.pageY;
const newPositionX = imageOffsetX mouseOffsetX;
const newPositionY = imageOffsetY mouseOffsetY;
$(this).css("left", `${newPositionX}px`)
.css("top", `${newPositionY}px`)
});
});
//}, 10);
});
body{
display:flex;
align-items:center;
justify-content:center;
}
.container{
width:70vw;
height:500px;
position:relative;
}
.img-box{
position:absolute;
}
.img-box img{
width:300px;
height:200px;
/* transform:translate(-50%); */
}
.img-box.box-1{
top:10%;
}
.img-box.box-2{
left:20%;
top:80%;
}
.img-box.box-3{
top:50%;
left:50%;
}
.img-box.box-4{
top:10%;
left:90%
}
.img-box.box-5{
left:90%;
top:70%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js" integrity="sha512-WFN04846sdKMIP5LKNphMaWzU7YpMyCU245etK3g/2ARYbPK9Ub18eG ljU96qKRCWh quCY7yefSmlkQw1ANQ==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<div class="container">
<div class="img-box box-1">
<img src="https://images.unsplash.com/photo-1632012643163-c9c4fbbd9f05?crop=entropy&cs=srgb&fm=jpg&ixid=MnwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHx8MTYzMjk4MzEwNg&ixlib=rb-1.2.1&q=85">
</div>
<div class="img-box box-2">
<img src="https://images.unsplash.com/photo-1632778931175-128809d8facc?crop=entropy&cs=srgb&fm=jpg&ixid=MnwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHx8MTYzMjk4MzE2MQ&ixlib=rb-1.2.1&q=85">
</div>
<div class="img-box box-3">
<img src="https://images.unsplash.com/photo-1594734044877-2ebba0c14720?crop=entropy&cs=srgb&fm=jpg&ixid=MnwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHx8MTYzMjk4MzIwMg&ixlib=rb-1.2.1&q=85">
</div>
<div class="img-box box-4">
<img src="https://images.unsplash.com/photo-1630231211819-a131d7538a41?crop=entropy&cs=srgb&fm=jpg&ixid=MnwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHx8MTYzMjk4MzIxNQ&ixlib=rb-1.2.1&q=85">
</div>
<div class="img-box box-5">
<img src="https://images.unsplash.com/photo-1632073591482-0d69552e07df?crop=entropy&cs=srgb&fm=jpg&ixid=MnwxNDU4OXwwfDF8cmFuZG9tfHx8fHx8fHx8MTYzMjk4MzI1NA&ixlib=rb-1.2.1&q=85">
</div>
</div>