Custom Pointer
Replace the default cursor with a beautiful, themed pointer that transforms on interactions. Includes right-click circle animation and press effects.
Live Customization
✨ Changes apply to the real cursor!
Move your mouse around to see the customized pointer. Right-click anywhere to see the circle animation.
Preset Themes
Pointer Icon
Colors
Pointer Color
Circle (auto-matched)
Filled Background
Fill: #3b82f6 @ 15% opacity
Sizes
Current Configuration
{
colors: {
pointerColor: "#3b82f6",
circleColor: "rgba(59, 130, 246, 0.4)",
},
sizes: {
pointerSize: 24,
circleSize: 44,
},
pointerIcon: <Default
fill="rgba(59, 130, 246, 0.15)"
stroke="#3b82f6"
/>
}What You Get
- Custom themed cursor that follows mouse movement
- Smooth right-click animation with expanding circle
- Press effect when clicking (scaled pointer + faint circle)
- Menu-aware: shows pointer over menus, circle elsewhere when menu open
- High z-index to appear above all UI elements
- Respects prefers-reduced-motion for accessibility
- Direct DOM manipulation for 60fps performance
- Dynamic theme updates via usePointer hook
Implementation
1. Install the Package
npm install @ewjdev/anyclick-pointer# oryarn add @ewjdev/anyclick-pointer2. Basic Setup with PointerProvider
app/providers.tsx
'use client';
import { PointerProvider } from '@ewjdev/anyclick-pointer';
export function Providers({ children }: { children: React.ReactNode }) { return ( <PointerProvider> {children} </PointerProvider> );}3. Wrap Your App
app/layout.tsx
import { Providers } from './providers';
export default function RootLayout({ children }: { children: React.ReactNode }) { return ( <html lang="en"> <body> <Providers>{children}</Providers> </body> </html> );}Custom Theme
Customize colors, sizes, and even replace the pointer icon. Use fill="none" for transparent background or a semi-transparent color for filled:
app/providers.tsx
import { PointerProvider } from '@ewjdev/anyclick-pointer';import { Default } from 'lucide-react';
export function Providers({ children }: { children: React.ReactNode }) { return ( <PointerProvider theme={{ colors: { pointerColor: '#3b82f6', circleColor: 'rgba(59, 130, 246, 0.4)', circleBorderColor: '#3b82f699', }, sizes: { pointerSize: 24, circleSize: 44, circleBorderWidth: 2, }, // fill="none" for transparent, or use rgba for semi-transparent fill pointerIcon: <Default size={24} fill="rgba(59, 130, 246, 0.15)" stroke="#3b82f6" />, }} config={{ visibility: 'always', hideDefaultCursor: true, zIndex: 10001, }} > {children} </PointerProvider> );}Dynamic Theme Updates
Update the pointer theme at runtime using the usePointer hook:
import { usePointer } from '@ewjdev/anyclick-pointer';import { Crosshair } from 'lucide-react';
function ThemeSwitcher() { const { setTheme, setInteractionState } = usePointer();
const applyDarkTheme = () => { setTheme({ colors: { pointerColor: '#8b5cf6', circleColor: 'rgba(139, 92, 246, 0.4)', }, sizes: { pointerSize: 28, circleSize: 50, }, pointerIcon: <Crosshair size={28} fill="white" stroke="#8b5cf6" />, }); };
const triggerCircle = () => { setInteractionState('rightClick'); };
return ( <div> <button onClick={applyDarkTheme}>Apply Dark Theme</button> <button onClick={triggerCircle}>Show Circle</button> </div> );}Integration with FeedbackProvider
Combine with the feedback system for a complete experience:
app/providers.tsx
'use client';
import { FeedbackProvider } from '@ewjdev/anyclick-react';import { PointerProvider } from '@ewjdev/anyclick-pointer';import { createHttpAdapter } from '@ewjdev/anyclick-github';
const adapter = createHttpAdapter({ endpoint: '/api/feedback' });
export function Providers({ children }: { children: React.ReactNode }) { return ( <FeedbackProvider adapter={adapter}> <PointerProvider theme={{ colors: { pointerColor: '#3b82f6', circleColor: 'rgba(59, 130, 246, 0.4)', }, }} config={{ visibility: 'always', hideDefaultCursor: true, }} > {children} </PointerProvider> </FeedbackProvider> );}Configuration Reference
Theme Options
| Property | Default | Description |
|---|---|---|
| colors.pointerColor | currentColor | Pointer icon color |
| colors.circleColor | rgba(59, 130, 246, 0.4) | Circle background |
| sizes.pointerSize | 24 | Pointer icon size (px) |
| sizes.circleSize | 44 | Circle size (px) |
| pointerIcon | MousePointer2 | Custom icon component |
Hook Methods
| Method | Description |
|---|---|
| setTheme(theme) | Update theme colors, sizes, and icon |
| setConfig(config) | Update behavior config |
| setEnabled(bool) | Enable/disable the pointer |
| setInteractionState(state) | Trigger states: 'normal' | 'rightClick' | 'pressing' |
Your changes are live!
The customizations you made above are applied to the actual pointer on this page. Navigate to other pages to see your theme persist, or refresh to reset.
Basic Setup Example