Elastic Custom Cursor in Vanilla JavaScript

Elastic Custom Cursor in Vanilla JavaScript
Code Snippet:Elastic Custom Cursor Following Mouse (Squeeze and Rotate) w/ JavaScript
Author: Denis Gusev
Published: March 23, 2024
Last Updated: March 23, 2024
Downloads: 133
License: MIT
Edit Code online: View on CodePen
Read More

This code creates an elastic custom cursor in vanilla JavaScript. It follows mouse movements smoothly. It helps enhance user experience on websites.

You can use this code on your website to create a visually appealing and interactive cursor. It adds a unique touch to your site, making it more engaging for visitors. Additionally, it improves user experience by providing smooth and dynamic cursor movements.

How to Create Elastic Custom Cursor in Vanilla JavaScript

1. Start by creating a basic HTML structure. For this tutorial, you only need a single <div> element with a class of “circle” to represent the cursor.

<div class="circle"></div>

2. Define the appearance and behavior of the cursor using CSS. The provided CSS ensures the cursor is circular and positioned correctly.

* {
  box-sizing: border-box;
  padding: 0;
  margin: 0;
}

body{
  min-height: 100lvh;
  background-color: #050908;
}

.circle {
  --circle-size: 40px;
  position: fixed;
  height: var(--circle-size);
  width: var(--circle-size);
  border: 1px solid white;
  border-radius: 100%;
  top: calc(var(--circle-size) / 2 * -1);
  left: calc(var(--circle-size) / 2 * -1);
  pointer-events: none;
}

3. Now, let’s make the cursor dynamic with JavaScript. This script tracks mouse movements and applies transformations to the cursor for smooth animation.

/**
 * YouTube Tutorial:
 * https://youtu.be/wG_5453Vq98
 */

console.clear();

// Select the circle element
const circleElement = document.querySelector('.circle');

// Create objects to track mouse position and custom cursor position
const mouse = { x: 0, y: 0 }; // Track current mouse position
const previousMouse = { x: 0, y: 0 } // Store the previous mouse position
const circle = { x: 0, y: 0 }; // Track the circle position

// Initialize variables to track scaling and rotation
let currentScale = 0; // Track current scale value
let currentAngle = 0; // Track current angle value

// Update mouse position on the 'mousemove' event
window.addEventListener('mousemove', (e) => {
  mouse.x = e.x;
  mouse.y = e.y;
});

// Smoothing factor for cursor movement speed (0 = smoother, 1 = instant)
const speed = 0.17;

// Start animation
const tick = () => {
  // MOVE
  // Calculate circle movement based on mouse position and smoothing
  circle.x += (mouse.x - circle.x) * speed;
  circle.y += (mouse.y - circle.y) * speed;
  // Create a transformation string for cursor translation
  const translateTransform = `translate(${circle.x}px, ${circle.y}px)`;

  // SQUEEZE
  // 1. Calculate the change in mouse position (deltaMouse)
  const deltaMouseX = mouse.x - previousMouse.x;
  const deltaMouseY = mouse.y - previousMouse.y;
  // Update previous mouse position for the next frame
  previousMouse.x = mouse.x;
  previousMouse.y = mouse.y;
  // 2. Calculate mouse velocity using Pythagorean theorem and adjust speed
  const mouseVelocity = Math.min(Math.sqrt(deltaMouseX**2 + deltaMouseY**2) * 4, 150); 
  // 3. Convert mouse velocity to a value in the range [0, 0.5]
  const scaleValue = (mouseVelocity / 150) * 0.5;
  // 4. Smoothly update the current scale
  currentScale += (scaleValue - currentScale) * speed;
  // 5. Create a transformation string for scaling
  const scaleTransform = `scale(${1 + currentScale}, ${1 - currentScale})`;

  // ROTATE
  // 1. Calculate the angle using the atan2 function
  const angle = Math.atan2(deltaMouseY, deltaMouseX) * 180 / Math.PI;
  // 2. Check for a threshold to reduce shakiness at low mouse velocity
  if (mouseVelocity > 20) {
    currentAngle = angle;
  }
  // 3. Create a transformation string for rotation
  const rotateTransform = `rotate(${currentAngle}deg)`;

  // Apply all transformations to the circle element in a specific order: translate -> rotate -> scale
  circleElement.style.transform = `${translateTransform} ${rotateTransform} ${scaleTransform}`;

  // Request the next frame to continue the animation
  window.requestAnimationFrame(tick);
}

// Start the animation loop
tick();

Finally, integrate the JavaScript code into your HTML file, and you’re ready to go! Feel free to further customize the cursor’s behavior and appearance to suit your website’s design and requirements.

That’s it! You’ve successfully created an elastic custom cursor on your website. Experiment with different properties and add your creative touch to enhance user interaction on your website.

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

About CodeHim

Free Web Design Code & Scripts - CodeHim is one of the BEST developer websites that provide web designers and developers with a simple way to preview and download a variety of free code & scripts. All codes published on CodeHim are open source, distributed under OSD-compliant license which grants all the rights to use, study, change and share the software in modified and unmodified form. Before publishing, we test and review each code snippet to avoid errors, but we cannot warrant the full correctness of all content. All trademarks, trade names, logos, and icons are the property of their respective owners... find out more...

Please Rel0ad/PressF5 this page if you can't click the download/preview link

X