If you ever need to implement dragging or to move something along with the mouse, here's how you do it:
requestAnimationFrame
. Lodash's throttle
method with no wait
parameter will do this. If you don't throttle, your event will fire faster than the screen can even refresh, and you'll waste CPU cycles and the smoothness of the movement.Here's a basic example of tracking mouse movements using the Composition API. I didn't include throttling in order to keep things clearer:
// In your setup() functionwindow.addEventListener("mousemove", (e) => {// Only move the element when we're holding down the mouseif (dragging.value) {// Calculate how far the mouse moved since the last// time we checkedconst diffX = e.clientX - mouseX.value;const diffY = e.clientY - mouseY.value;// Move the element exactly how far the mouse movedx.value += diffX;y.value += diffY;}// Always keep track of where the mouse ismouseX.value = e.clientX;mouseY.value = e.clientY;});
Here's the full example. You can check out a working demo here:
<template><div class="drag-container"><imgalt="Vue logo"src="./assets/logo.png":style="{left: `${x}px`,top: `${y}px`,cursor: dragging ? 'grabbing' : 'grab',}"draggable="false"@mousedown="dragging = true"/></div></template>
<script setup>import { ref } from "vue";const dragging = ref(false);const mouseX = ref(0);const mouseY = ref(0);const x = ref(100);const y = ref(100);window.addEventListener("mousemove", (e) => {if (dragging.value) {const diffX = e.clientX - mouseX.value;const diffY = e.clientY - mouseY.value;x.value += diffX;y.value += diffY;}mouseX.value = e.clientX;mouseY.value = e.clientY;});window.addEventListener("mouseup", () => {dragging.value = false;});</script>