In this blog, I will be showing you how to make a mouse-tracking eye component using Vue 3, VueUse and a sprinkle of CSS. This eye-catching component will make a quirky addition to your future projects.
Firstly let's break the eyes, my name is Taliesin, and I work at Pixelhop. I made this for our Halloween special project we at Pixelhop made called trick-or-treat.
If you would like to get your eyes on the whole code example, please find it here.
Readers are recommended to have a basic understanding of Vue 3 using the composition API, also not recommended for anyone with Ommetaphobia or if you have anything against terrible eye puns. So if we see eye to eye, let's crack on.
So, to summer-eyes, for this to work, we will need to have an SVG of an eye with the pupil to one side. We are then just going to set the transform rotate property to point the pupil in the direction of the mouse as it moves.
If you already have a project and an eye SVG ready, you can roll your eyes on to the next section. But if you're like the alien called Alen and missing an eye, here I will just be setting up a basic Vue 3 project and setting the foundation of what we are making.
So first, we want to set up a basic Vue 3 project. The easiest way to do this is using npx and the Vue CLI by running the following command.
npx @vue/cli create mouse-tracking-eye
Select the default vue 3 preset
Choose your dependancies manager (I'm using npm)
cd into the folder and install the dependancies
cd mouse-tracking-eye/ &&npm i
We can now remove all the bits the vue cli gives us that we don't need. First, remove the components and assets folders. Then in the App.vue, we should remove all the base stuff it gives us. You are just left with the template, script and style tag.
I am using the <script setup> syntax, which you can read about here and typescript because why not.
Eye eye, now we got those imported, we can start using them. The first two we will use are useMouse and useWindowSize.
useMouse returns the x and y of the mouse position, and useWindowSize returns... You guessed it, the window size width and height.
So just under the import, add the following:
We also want to set the eye's location when the screen size is changed because depending on where it is this might move the eye. To achieve this we can use the debounceWatch
To summarise whats happening here; we are watching for a change in the window height and width then running a debounce function when it does.
So if you got an eye for this sort of thing, then you'll be able to understand it, but if you're like a blind Bambi and have no-eye-deer. Don't worry; I'll give a quick summary of what's happening;
Firstly, we define the ref rotationDegrees which will be the number of degrees we need to rotate our eye. Next, we are using the throttledWatch function to watch the mouse location, then set the rotationDegrees.
First, it gets the radianDegrees using the Math.atan2 function; read more here. Basically, it receives the radian between the eye location and the mouse. I am using the top and right locations of the eye, but depending on where your eye's pupil is pointing, you may need to use a different location. Then we convert the radian into degrees we can use to rotate the eye.
This function is then throttled to 60 times per second as we don't need to run this more than that as most screens only run a 60 hertz anyway.
Now all we need to do is set the transform rotate property to the SVG and you'll really be turning some eyes.
Side note: You may need to do what I did by adding or subtracting a few degrees if your eye is not pointing precisely left or right.
Because we are getting the eye location on mounted and screen size change, you can place your eye anywhere on the screen, and it will still work.
I hope you enjoyed this mini tutorial, and it helps you create some fun projects. Feel free to send us your creations. I would love to eye them up. You can find our contact details at https://www.pixelhop.io/contact/.