Make SVG follow cursor using CSS and JS
anomaly3108
Posted on January 9, 2022
In this article, we are going to make an SVG Eye that will follow the mouse pointer with a clean UI and smooth transition. First, As always let's see what are we building.
PREVIEW
HTML
<img src="face-with-rolling-eyes.png" class="image">
<div class="container">
<svg width="100" height="100" class="eye">
<circle cx="50" cy="50" r="50" fill="white" class="eyeball_left" />
<circle cx="50" cy="50" r="20" fill="#0D0D20" class="pupil_left" />
</svg>
<svg width="100" height="100" class="eye">
<circle cx="50" cy="50" r="50" fill="white" class="eyeball_right" />
<circle cx="50" cy="50" r="20" fill="#0D0D20" class="pupil_right" />
</svg>
</div>
We will have an outer div with class .container
. It will have two separate children SVG which will be the eyes of our character.
Inside SVG we create 2 circles one for eyeball and one for pupil.
The img
tag will be the face of the character
I guess now you have an overview of what are we doing. Now let's get into the CSS.
CSS
body{
margin:0;
padding:0;
background: #282631;
display: flex;
width: 100%;
height:100vh;
}
.container{
margin: auto;
}
.image{
position: absolute;
top: 250px;
left: 620px;
z-index: -1;
}
.pupil_left{
position:relative;
}
.pupil_right{
position:relative;
}
Everything above is self-explanatory but If you have any queries then comment down.
JAVASCRIPT
This is where the fun begins. Let's see from the scratch.
First, we need to find elements with an "eyeball_left
" and "pupil_left
" class
let eyeball_left = document.querySelector(".eyeball_left"),
pupil_left = document.querySelector(".pupil_left"),
Now, We will get the radius of the circles to find the center of the circles. The getBoundingClientRect
returns a DOMRect object with eight properties: left, top, right, bottom, x, y, width, height.
eyeArea_left = eyeball_left.getBoundingClientRect(),
pupil_leftArea = pupil_left.getBoundingClientRect(),
R_left = eyeArea_left.width/2,
r_left = pupil_leftArea.width/2,
centerX_left = eyeArea_left.left + R_left,
centerY_left = eyeArea_left.top + R_left;
Copy the same code for right eye. Just change the variable names to ###_right
for right Eye.
let eyeball_right = document.querySelector(".eyeball_right"),
pupil_right = document.querySelector(".pupil_right"),
eyeArea_right = eyeball_right.getBoundingClientRect(),
pupil_rightArea = pupil_right.getBoundingClientRect(),
R_right = eyeArea_right.width/2,
r_right = pupil_rightArea.width/2,
centerX_right = eyeArea_right.left + R_right,
centerY_right = eyeArea_right.top + R_right;
Now, let us create a mouse event. Through which, we will find the distance between the pointer and center of the eyeball. Math.atan2
will return the angle in radians between the two points. By using the formula, we can convert radian to degree.
Using this angle we will position the pupil inside the eyeball
document.addEventListener("mousemove", (e)=>{
let x_left = e.clientX - centerX_left,
y_left = e.clientY - centerY_left,
theta_left = Math.atan2(y_left,x_left),
angle_left = theta_left*180/Math.PI + 360;
Create a same for the right eye
let x_right = e.clientX - centerX_right,
y_right = e.clientY - centerY_right,
theta_right = Math.atan2(y_right,x_right),
angle_right = theta_right*180/Math.PI + 360;
Finally, we will use JS style property to move and rotate the pupil inside the Eye to follow the cursor
pupil_left.style.transform = `translateX(${R_left - r_left +"px"}) rotate(${angle_left + "deg"})`;
pupil_left.style.transformOrigin = `${r_left +"px"} center`;
pupil_right.style.transform = `translateX(${R_right - r_right +"px"}) rotate(${angle_right + "deg"})`;
pupil_right.style.transformOrigin = `${r_right +"px"} center`;
});
Now we have covered all the aspects of this now let's see the full Javascript code.
<script>
let eyeball_left = document.querySelector(".eyeball_left"),
pupil_left = document.querySelector(".pupil_left"),
eyeArea_left = eyeball_left.getBoundingClientRect(),
pupil_leftArea = pupil_left.getBoundingClientRect(),
R_left = eyeArea_left.width/2,
r_left = pupil_leftArea.width/2,
centerX_left = eyeArea_left.left + R_left,
centerY_left = eyeArea_left.top + R_left;
let eyeball_right = document.querySelector(".eyeball_right"),
pupil_right = document.querySelector(".pupil_right"),
eyeArea_right = eyeball_right.getBoundingClientRect(),
pupil_rightArea = pupil_right.getBoundingClientRect(),
R_right = eyeArea_right.width/2,
r_right = pupil_rightArea.width/2,
centerX_right = eyeArea_right.left + R_right,
centerY_right = eyeArea_right.top + R_right;
document.addEventListener("mousemove", (e)=>{
let x_left = e.clientX - centerX_left,
y_left = e.clientY - centerY_left,
theta_left = Math.atan2(y_left,x_left),
angle_left = theta_left*180/Math.PI + 360;
let x_right = e.clientX - centerX_right,
y_right = e.clientY - centerY_right,
theta_right = Math.atan2(y_right,x_right),
angle_right = theta_right*180/Math.PI + 360;
pupil_left.style.transform = `translateX(${R_left - r_left +"px"}) rotate(${angle_left + "deg"})`;
pupil_left.style.transformOrigin = `${r_left +"px"} center`;
pupil_right.style.transform = `translateX(${R_right - r_right +"px"}) rotate(${angle_right + "deg"})`;
pupil_right.style.transformOrigin = `${r_right +"px"} center`;
});
</script>
The final product will look like:-
You can use the following CSS in body
selector to change the cursor by any image
cursor: url("heart.png"), auto;
Wrapping Up
I hope you enjoyed the article, if yes then don't forget to press ❤️. You can also bookmark it for later use. It was fun to make this Project and If you have any queries or suggestions don't hesitate to drop them. See you again.
Posted on January 9, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
February 7, 2022