Custom Cursor Using React Js
In this article, We will create a Custom Cursor using React JS. Our project aims to develop a unique cursor that will replace the standard mouse pointer with a personalized design. This innovative cursor will adapt its appearance according to the user’s interactions.
Preview of final output: Let us have a look at how the final output will look like.
Prerequisites :
Approach:
- The component’s state, including cursor position (cursorX and cursorY), device type, and user clicking status , can be effectively managed using the useState method. This allows for efficient handling of these crucial elements
- The function known as ‘isTouchDevice’ performs the important task of determining whether the user’s device possesses touch capabilities. This functionality helps in differentiating between mouse and touch events, aiding in better interaction and user
- The movement of the cursor is tracked by the move function. It updates the position of the custom cursor and handles touch events.
- ‘handleMouseDown’ and ‘handleMouseUp’ functions manage the clicking state.
- The useEffect hook serves the purpose of incorporating and removing event listeners for both mouse and touch events. Its functionality ensures that the cursor’s position is continuously updated.
- The component renders custom cursor elements and applies styles to enhance the appearance, borders, and interactions based on user actions.
Steps to Create the project:
Step 1: Create a react application by using this command
npx create-react-app custom-cursor-app
Step 2: After creating your project folder, i.e. custom-cursor-app, use the following command to navigate to it:
cd custom-cursor-app
Project Structure:
The updated dependencies in package.json file will look like:
"dependencies": {
"react": "18.2.0",
"react-dom": "18.2.0",
},
"devDependencies": {
"react-scripts": "latest"
}
Example: Write the below mentioned code in App.js file in the src directory
Javascript
import React, { useEffect, useState } from 'react' ; function App() { const [cursorX, setCursorX] = useState(0); const [cursorY, setCursorY] = useState(0); const [deviceType, setDeviceType] = useState( '' ); const [isClicking, setIsClicking] = useState( false ); const [buttonHovered, setButtonHovered] = useState( false ); // check if it is a touch device const isTouchDevice = () => { try { document.createEvent( 'TouchEvent' ); setDeviceType( 'touch' ); return true ; } catch (e) { setDeviceType( 'mouse' ); return false ; } }; const move = (e) => { const touchEvent = e.touches ? e.touches[0] : null ; const x = !isTouchDevice() ? e.clientX : touchEvent?.clientX || 0; const y = !isTouchDevice() ? e.clientY : touchEvent?.clientY || 0; setCursorX(x); setCursorY(y); // Set the cursor border's position directly const cursorBorder = document.getElementById('cursor-border '); if (cursorBorder) { cursorBorder.style.left = `${x}px`; cursorBorder.style.top = `${y}px`; } }; const handleMouseDown = () => { setIsClicking(true); }; const handleMouseUp = () => { setIsClicking(false); }; const handleButtonHover = (hovered) => { setButtonHovered(hovered); }; useEffect(() => { document.addEventListener(' mousemove ', move); document.addEventListener(' touchmove ', move); document.addEventListener(' mousedown ', handleMouseDown); document.addEventListener(' mouseup ', handleMouseUp); return () => { document.removeEventListener(' mousemove ', move); document.removeEventListener(' touchmove ', move); document.removeEventListener(' mousedown ', handleMouseDown); document.removeEventListener(' mouseup ', handleMouseUp); }; }, []); return ( <div> <style> {` * { margin: 0; cursor: none; } body { background-color: #0984e3; height: 100vh; overflow: hidden; display: flex; justify-content: center; align-items: center; } #cursor { position: absolute; background-color: ${isClicking ? ' crimson ' : ' crimson '}; height: 10px; width: 10px; border-radius: 50%; transform: translate(-50%, -50%); pointer-events: none; transition: background-color 0.2s ease; } #cursor-border { position: absolute; width: 50px; height: 50px; background-color: transparent; border: 3px solid ${buttonHovered ? ' red ' : ' #fff'}; border-radius: 50%; transform: translate(-50%, -50%); pointer-events: none; transition: all 0.2s ease-out; } `} </style> <div id= "cursor" style={{ left: `${cursorX}px`, top: `${cursorY}px` }} ></div> <div id= "cursor-border" ></div> <button onMouseEnter={() => handleButtonHover( true )} onMouseLeave={() => handleButtonHover( false )} style={{ backgroundColor: buttonHovered ? 'green ' : ' transparent ', color: ' white ', padding: ' 10px 20px ', border: ' 2px solid white ', borderRadius: ' 5px ', cursor: ' pointer', }} > w3wiki </button> </div> ); } export default App; |
Steps to run the Application:
Step 1: Type the following command in the terminal:
npm start
Step 2: Type the following URL in the browser:
http://localhost:3000/
Output: