Circle on Mouse

Sun Dec 30 2018

In this tutorial we’ll explain the process of how to create simple circle that follow on the mouse cursor, the inspiration for this was came from this website, so i want to experiment how to create it. The demo for this project is available on codepen.

The HTML

Let’s start with the circle element:

<div class=" mouse"  >
  <div class="mouseSVG mouseArrow">
    <svg xmlns="http://www.w3.org/2000/svg" width="2" height="2" viewBox="0 0 15 15" fill="none">
      <rect width="1.60835" height="18.1019" rx="0.804173" transform="translate(13.5194 0.111816) rotate(45)" fill="#ffffff"/>
      <path d="M0 0.75C0 0.335786 0.335786 0 0.75 0H8.75V1.5H0.75C0.335786 1.5 0 1.16421 0 0.75Z" transform="translate(4.89999 0.460022)" fill="#ffffff"/>
      <path d="M0 0.75C0 0.335786 0.335786 0 0.75 0H8.75V1.5H0.75C0.335786 1.5 0 1.16421 0 0.75Z" transform="translate(12.91 9.78998) rotate(-90.7565)" fill="#ffffff"/>
    </svg>
  </div>
</div>

For circle element we want the circle stay small until it hover certain element, we do that by toggling class that scale the circle when it hover the element. Next, we create the card element.

<div class="content__wrapper">
  <div id="content" class="content__item">
    <div class="content-text">
      <div  class="text-1">Finding Perception</div>
      <div  class="text-2">Museum Experience</div>
    </div>
  </div>
</div>

The CSS

Next, we add some styles for the circle and the card. The mouseOnElement class is used to change the style of the circle when it hovers on the card:

.mouseSVG{
  width: 100%;
  height: 100%;
  border-radius: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  transition: all .3s ease;
}
.mouseOnElement{
  transform : scale3d(10,10,1) translate3d(6px,2px,0) !important;
  background : red !important;
  mix-blend-mode: difference !important;
}
.mouseArrow{
  opacity: 0;
}
.mouseOnElement .mouseArrow{
  opacity: 1;
}
.mouse {
  position: absolute;
  width: 10px;
  height: 10px;
  border-radius: 100px;
  background: red;
  top: 50px;
  left: 50px;
  transform: scale3d(1,1,1) translate3d(-5px,-5px,0);
  transform-origin: top;
  mix-blend-mode: soft-light;
  transition: transform .4s, background .1s;
  z-index: 10;
  pointer-events: none;
  cursor: none;
}
.content__wrapper{
	width: 100%;
	display: flex; 
	justify-content: center; 
	align-items: center;
    font-family: 'Montserrat', sans-serif;
}
.content__item{
	width: 500px;
	height: 350px;
	margin : 20px;
	position: relative;
	background-position: center center;
	background-size: cover;
    cursor: pointer;
    background-image : url('https://theshift.tokyo/wp_static/wp-content/uploads/2018/03/fp_thumb-1200x800.jpg');
}
.content-text{
	width: 100%;
	height: 100%;
	display: flex;
	justify-content: center;
	align-items: center;
	flex-direction: column;
}
.text-1{
	color : whitesmoke;
	font-size: 24px;
	font-weight: 700;
	margin-bottom: 16px;
}
.text-2{
	color : whitesmoke;
	font-size: 16px;
	font-weight: 700;
}

The Javascript

The main idea is to when we move the cursor on the screen, the circle will follow it and when the cursor hover on the card element, we adds mouseOnElement and remove it when the cursor leave the element. First, we start move the circle on the screen:

let mouseX = 0,
 mouseY = 0;
let xp = 0, 
yp = 0;
const content = document.querySelector('#content');
const mouse =  document.querySelector('.mouse');

window.addEventListener('mousemove', (e) => {
  mouseX = e.pageX ;
  mouseY = e.pageY ;
});
const cursorMove =  () => {
  window.requestAnimationFrame( () => {
    setInterval(() => {
      xp += (mouseX - xp) / 6;
      yp += (mouseY - yp) / 6;
      mouse.style.left = xp + 'px';
      mouse.style.top = yp + 'px';
   }, 20);
  });
}
cursorMove()

We add event listener to window and put the value to mouseX and mouseY, then create cursorMove function to move the circle on the circle, we also use requestAnimationFrame so animations will be smoother. We use setInterval, xp, and yp to make the circle move slightly slower than the cursor, then we call cursorMove so it will be automatically run when the page is opened. The last step is to toggle scale the circle when it hover the card element:

content.addEventListener("mouseenter", ( event ) => {   
    mouse.classList.add("mouseOnElement");
  }, false);

content.addEventListener("mouseleave", ( event ) =>  {   
    mouse.classList.remove("mouseOnElement");
  }, false);

We add event listener mouseenter and mouseleave to card element then we add function to toggle the class mouseOnElement.

And we are done !, you can check and play around with the code on codepen.