How to make target ref move with the mouse inside a composable in Vue 3

136 views Asked by At

I'm trying to make a composable in Vue 3 with Nuxt and VueUse that will make any component follow the mouse cursor. I have the following composable:

export function useStickToMouse(target) {
  onMounted(() => {
    const {elementX, elementY} = useMouseInElement(target);
    function moveTarget(event:MouseEvent) {
      target.value.style.left = `${elementX.value}px`;
      target.value.style.top = `${elementY.value}px`;
    }
    useEventListener(window, 'mousemove', moveTarget)
  });
}

Here is te follow-mouse-wrapper component:

<template>
  <div ref="target">
    <slot></slot>
  </div>
</template>


<script setup>

const target = ref(null);
useStickToMouse(target)
  
</script>

So I can use something like this:

<follow-mouse-wrapper>
  <component-to-move></component-to-move>
</follow-mouse-wrapper>

Changing the style attribute doesn't move the element, but using anime.js does, but it does some strange things:

//Composable using anime.js
export function useStickToMouse(target) {

  onMounted(() => {
    const {elementX, elementY} = useMouseInElement(target);

    function moveTarget(event:MouseEvent) {
      useAnime({
        targets: target.value,
        translateX: elementX.value,
        translateY: elementY.value
      })
        
    }
    
    useEventListener(window, 'mousemove', moveTarget)
  });

}

What's the best way to get the element to follow the cursor?

1

There are 1 answers

1
Ellrohir On BEST ANSWER

VueUse useMouse and bind the values via CSS v-bind:

<template>
  <div>
    <div class="mouse-follower" />
  </div>
</template>

<script setup>
const { x, y } = useMouse();
</script>

<style scoped>
.mouse-follower {
  position: absolute;
  width: 50px;
  height: 50px;
  background-color: red;
  top: v-bind('y + "px"');
  left: v-bind('x + "px"');
}
</style>

You need to npm i -D @vueuse/nuxt @vueuse/core and add modules: ['@vueuse/nuxt'] into defineNuxtConfig to get VueUse working.

Demo: https://stackblitz.com/edit/github-wwyemm?file=app.vue