A lightweight custom cursor with hover, magnetic and morph interactions.
Cursor Motion replaces the default desktop cursor with a smooth animated cursor that supports multiple interaction modes.
- Lightweight and dependency-free
- Desktop-focused custom cursor
- Smooth cursor movement
- Default hover state
- Magnetic cursor effect
- Morph cursor effect
- Magnetic + morph effect
- Optional text labels
- Custom element selector
- Event delegation
- Dynamic DOM support
destroy()method- Automatically disabled on touch and coarse pointer devices
Cursor Motion is not published on the npm registry. The package named
cursor-motion on npm is a different project.
Install this repository directly from GitHub:
npm install github:sairo-cyber/cursor-motionImport the JavaScript module and the CSS file with a bundler such as Vite, Webpack or Parcel:
import { createCursor } from "cursor-motion";
import "cursor-motion/style.css";
createCursor();import { createCursor } from "cursor-motion";
import "cursor-motion/style.css";
const cursor = createCursor();Cursor Motion supports four different interaction modes.
Links and buttons automatically use the default hover effect.
<a href="#">
Default link
</a>
<button>
Default button
</button>Add data-cursor="magnetic" to pull the cursor toward the element.
<button data-cursor="magnetic">
Magnetic
</button>Add data-cursor="morph" to make the cursor grow and morph to the size of the element.
<button data-cursor="morph">
Morph
</button>You can also display a label inside the cursor:
<button
data-cursor="morph"
data-cursor-text="Open"
>
Morph
</button>Combine both effects with data-cursor="magnetic-morph".
<a
href="#"
data-cursor="magnetic-morph"
data-cursor-text="Open"
>
Open
</a>By default, Cursor Motion activates on:
[data-cursor], a, button
You can provide your own selector with the selector option.
const cursor = createCursor({
selector: "[data-cursor], a, button, .cursor-target"
});For example:
<div class="cursor-target">
Custom target
</div>This allows you to use Cursor Motion with custom interactive elements.
createCursor() returns an object with a destroy() method.
const cursor = createCursor();
cursor.destroy();This removes the cursor, event listeners and MutationObserver created by Cursor Motion.
The cursor can also be created again afterwards:
const cursor = createCursor();
cursor.destroy();
const newCursor = createCursor();Cursor Motion is designed for desktop devices with a fine pointer.
It automatically disables itself when:
- hover is not supported
- the primary pointer is coarse
Touch and mobile devices are intentionally not supported.
Cursor Motion does not inject the cursor styles automatically.
Import the stylesheet alongside the JavaScript:
import "cursor-motion/style.css";The stylesheet contains the default cursor appearance and interaction states.
The cursor appearance can be customized through the CSS classes provided by the package.
Main cursor:
.cursor
Hidden state:
.cursor.is-hidden
Default hover state:
.cursor.is-hovering
Magnetic state:
.cursor.is-magnetic
Morph state:
.cursor.is-morph
Cursor label:
.cursor-label
The morph border radius is controlled by the CSS custom property:
--cursor-radius
Available values:
magneticmorphmagnetic-morph
Example:
<button data-cursor="magnetic">
Magnetic
</button>Adds a text label inside morph modes.
Example:
<button
data-cursor="morph"
data-cursor-text="Open"
>
Open
</button>Cursor Motion creates a single cursor element and tracks mouse movement using requestAnimationFrame.
Interactive elements are detected through event delegation, which means elements added dynamically to the page can also work without additional initialization.
Magnetic elements pull the cursor toward their center.
Morph elements resize the cursor to match the dimensions of the target element.
Magnetic-morph elements combine both behaviors.
This example requires a bundler that resolves package imports.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Cursor Motion</title>
</head>
<body>
<button>Default</button>
<button data-cursor="magnetic">
Magnetic
</button>
<button
data-cursor="morph"
data-cursor-text="Open"
>
Morph
</button>
<a
href="#"
data-cursor="magnetic-morph"
data-cursor-text="Open"
>
Magnetic Morph
</a>
<script type="module">
import { createCursor } from "cursor-motion";
import "cursor-motion/style.css";
createCursor();
</script>
</body>
</html>Try Cursor Motion directly in your browser:
GitHub repository:
github.com/sairo-cyber/cursor-motion
Report issues or request features:
This project is licensed under the MIT License.
See the LICENSE file for the complete license text.
Made by sairo-cyber.