I am making a cursor which always points to an object.
My transition-duration
unfortunately makes the cursor lag on faster movements. How do I solve this issue without getting rid of the transition duration as it smoothes the movement? Are there any alternatives?
ps. I am a JS (JQuery) newbie so if you have any improvements for my code, please let me know.
jQuery(function($) {
let mousePos = {
x: 0,
y: 0
}
let lastMove = 0;
function onm ouseMove(e) {
mousePos.x = e.pageX;
mousePos.y = e.pageY;
$(".cursor").setAngle(calcAngle(getCenter($(".light")), getCenter($(".cursor"))));
$(".cursor").setPos(e.pageX, e.pageY);
lastMove = Date.now();
}
//gets the center
function getCenter(container) {
let containerCenter = {
x: $(container).offset().left $(container).width() / 2,
y: $(container).offset().top $(container).height() / 2
};
return containerCenter;
}
//calculates an angle between two elements (obj2 is pointing towards obj1)
function calcAngle(obj1, obj2) {
let angle = Math.atan2(obj1.x - obj2.x, -(obj1.y - obj2.y)) * (180 / Math.PI);
return angle;
}
//sets the position
$.fn.setPos = function(x, y) {
this.css({
"left": (x - this.width() / 2) "px",
"top": (y - this.height() / 2) "px",
});
};
//sets the rotation of an element
$.fn.setAngle = function(angle) {
this.css({
"transform": "rotate(" angle "deg)",
"-webkit-transform": "rotate(" angle "deg)"
});
};
addEventListener("mousemove", onm ouseMove);
});
body {
height: 100vh;
background: grey;
overflow: hidden;
}
.light {
position: absolute;
background-color: #fff;
height: 200px;
width: 200px;
border-radius: 50%;
left: 50%;
top: 0;
transform: translate(-50%, -50%);
}
.cursor {
background-color: white;
width: 20px;
height: 20px;
border: 1px solid white;
border-radius: 10%;
position: absolute;
transition-duration: 200ms;
pointer-events: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<body>
<div ></div>
<div ></div>
</body>
CodePudding user response:
I recommend using a canvas in the future for this applications
For now you could use transform
instead of top
and left
let mousePos = {
x: 0,
y: 0
}
let lastMove = 0;
function onm ouseMove(e) {
mousePos.x = e.pageX;
mousePos.y = e.pageY;
angle = calcAngle(getCenter($(".light")), getCenter($(".cursor")));
$(".cursor").setTransform(e.pageX, e.pageY, angle);
lastMove = Date.now();
}
//gets the center
function getCenter(container) {
let containerCenter = {
x: $(container).offset().left $(container).width() / 2,
y: $(container).offset().top $(container).height() / 2
};
return containerCenter;
}
//calculates an angle between two elements (obj2 is pointing towards obj1)
function calcAngle(obj1, obj2) {
let angle = Math.atan2(obj1.x - obj2.x, -(obj1.y - obj2.y)) * (180 / Math.PI);
return angle;
}
//sets transform
$.fn.setTransform = function(x, y, a) {
x = x - this.width()
y = y - this.height()
this.css({
"transform": "translate(" x "px, " y "px) rotate(" a "deg)",
"-webkit-transform": "translate(" x "px, " y "px) rotate(" a "deg)",
});
};
addEventListener("mousemove", onm ouseMove);
body {
height: 100vh;
background: grey;
overflow: hidden;
}
.light {
position: absolute;
background-color: #fff;
height: 200px;
width: 200px;
border-radius: 50%;
left: 50%;
top: 0;
transform: translate(-50%, -50%);
}
.cursor {
background-color: white;
width: 20px;
height: 20px;
border: 1px solid white;
border-radius: 10%;
position: absolute;
transition-duration: 100ms;
transition-timing-function: ease-out;
pointer-events: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<body>
<div ></div>
<div ></div>
</body>