I want to slow down speed of the draggable HTML object to make it kind of lazy dragging.
Is there any way to implement this feature with native HTML/CSS?
Or may be there are some existing JS libraries which have such ability?
Can't find any library with such simple feature..
I've made one possible solution but also not forgot to share ;)
The point is to apply mouse position to the circle on mousemove
event to emulate dragging effect.
Also I've added transition
CSS property to the circle for smooth movement.
The main thing here is to update circle position not continuously right in the mousemove
event listener. But in case with transition
property you should update circle position at some intervals to give CSS transition
time to animate circle displacement smoothly. Otherwise CSS transition
animation will be overloaded by continuous update from mousemeove
event and become glitchy.
var cirlce = document.querySelector('.circle');
function getTranslateX(myElement) {
var style = window.getComputedStyle(myElement);
var matrix = new WebKitCSSMatrix(style.webkitTransform);
return matrix.m41; // 'm41' is translateX position
}
function getTranslateY(myElement) {
var style = window.getComputedStyle(myElement);
var matrix = new WebKitCSSMatrix(style.webkitTransform);
return matrix.m42; // 'm42' is translateY position
}
var mouseDown = false;
var mousePos = {
x: 0,
y: 0,
}
var mouseLastPos = {
x: 0,
y: 0,
}
var circlePos = {
x: getTranslateX(cirlce),
y: getTranslateY(cirlce),
}
window.addEventListener('mouseup', e => {
mouseDown = false;
circlePos = {
x: getTranslateX(cirlce),
y: getTranslateY(cirlce),
}
});
window.addEventListener('mousedown', e => {
mouseDown = true;
mouseLastPos.x = e.clientX;
mouseLastPos.y = e.clientY;
});
window.addEventListener('mousemove', e => {
mousePos.x = e.clientX;
mousePos.y = e.clientY;
if (mouseDown) {
// cirlce.style.transform = 'translateX('+(mousePos.x-mouseLastPos.x+circlePos.x)+'px) translateY('+(mousePos.y-mouseLastPos.y+circlePos.y)+'px)'; // doesn't work with 'transition' CSS property
}
});
// main trick here to make 'transition' work properly
setInterval(() => {
if (mouseDown) {
cirlce.style.transform = 'translateX('+(mousePos.x-mouseLastPos.x+circlePos.x)+'px) translateY('+(mousePos.y-mouseLastPos.y+circlePos.y)+'px)';
}
}, 50);
.circle {
position: absolute;
width: 100px;
height: 100px;
top: 0;
left: 0;
background-color: red;
border: 2px solid black;
border-radius: 50%;
transform: translateX(5px) translateY(5px);
transition: transform 0.3s;
}
<div class="circle"></div>