@adoratorio/apollo
v4.0.1
Published
A JS library for custom cursor
Readme
Apollo
An engine to create custom cursor animations, magnetism, and hover effects.
Installation
npm install @adoratorio/apolloUsage
This package is ESM-only. Import it as a module:
import Apollo from '@adoratorio/apollo';
const apollo = new Apollo({
initialPosition: { x: window.innerWidth / 2, y: window.innerHeight / 2 }
});From here, you can instantiate and register plugins to handle the rendering of the cursor or to add functionalities.
import { CSSRender } from '@adoratorio/apollo/plugins';
apollo.registerPlugin(new CSSRender({
cursor: document.querySelector('.apollo__cursor')
}));Shipped Plugins
The following plugins are shipped from the @adoratorio/apollo/plugins entry point:
| Plugin | Description |
| :----- | :---------- |
| CSSRender | Renders the cursor by writing CSS transforms directly on a DOM element. |
| TargetsDetection | Fires callbacks/events when the mouse or cursor enters/leaves designated target elements. |
Configuration
Apollo accepts an options object with the following properties:
| Parameter | Type | Default | Description |
| :-------- | :--: | :-----: | :---------- |
| easing | Easing | { mode: Apollo.EASING.CUBIC, duration: 1000 } | An easing object used to describe the cursor element animation. |
| initialPosition | Vec2 | { x: 0, y: 0 } | Starting position of the cursor element. |
| detectTouch | boolean | false | If touch events count as valid interaction to evaluate a new cursor position. When false touch pointers are ignored entirely. |
| aion | Aion \| null | null | An Aion instance to be used as engine; if left null one will be created automatically. |
| debug | boolean | false | Enable namespaced console.warn diagnostics for recoverable issues (contract violations always throw). Forwarded to the internally created Aion. |
Methods
Plugin Management
// Register a single plugin (returns the assigned ID)
apollo.registerPlugin(plugin: ApolloPlugin, id?: string): string
// Register several plugins at once (returns the assigned IDs)
apollo.registerPlugins(plugins: ApolloPlugin[], ids?: string[]): string[]
// Unregister a plugin by ID
apollo.unregisterPlugin(id: string): boolean
// Retrieve a registered plugin by name
apollo.getPlugin(name: string): ApolloPlugin | undefinedInstance Management
// Starts or stops the mouse tracking per frame
apollo.startMouseTracking();
apollo.stopMouseTracking();
// Tear down the instance and clean up
apollo.destroy();Properties
coords(Vec2): The current smoothed position in screen pixels. Settable.normalizedCoords(Vec2): Smoothed position in normalized values (-1to1).mouse(Vec2): Native mouse pointer position in screen pixels.velocity(Vec2): Absolute per-axis speed of the cursor since the previous frame.direction(Vec2): Movement direction (-1,0or1per axis;0while the cursor is still).trackMouse(boolean): Get or set the current mouse tracking state.
Browser Support & SSR
Apollo listens for pointer events on window and needs requestAnimationFrame. Instantiating it outside of a browser environment throws an error.
TypeScript Support
Apollo is written in TypeScript and exports all necessary types and interfaces (e.g., ApolloOptions, ApolloPlugin, Vec2).
Maintenance and compatibility
See MAINTAINERS.md, CONTRIBUTING.md and CHANGELOG.md. Historical contributor credits are retained. The CI runtime is Node 24; DOM instances are client-only. Imports are SSR-safe. The runtime expects native ES2023 support; TypeScript does not provide browser polyfills. DOM functionality uses requestAnimationFrame, Pointer/Touch Events and observers where applicable. Test the target browser matrix before release.
Nested constructor settings may be partial. An easing duration of zero means
immediate movement; negative or non-finite easing durations are rejected.
respectReducedMotion: true opts in to immediate movement while the system
requests reduced motion. The default remains the existing easing behavior,
and plugin frame hooks continue running even while the instance is still.
When target positions change through transforms or virtual scrolling, call
TargetsDetection.recalculate() after updating the transform, before its next
frame check. Scroll/resize invalidation is automatic; arbitrary transforms are
not DOM resize events.
