UNPKG

@phazr/custom-cursor

Version:

A lightweight and highly customizable React component for creating unique and interactive cursor experiences.

148 lines (143 loc) 5.67 kB
'use client'; 'use strict'; var jsxRuntime = require('react/jsx-runtime'); var react = require('react'); var react$1 = require('motion/react'); const CursorContext = react.createContext(null); const useCursor = () => { const context = react.useContext(CursorContext); if (!context) { throw new Error('useCursor must be used within a CursorProvider'); } return context; }; function CursorProvider({ children, className = '', enableOnTouch = false, }) { const [variant, setVariant] = react.useState('default'); const [customConfig, setCustomConfig] = react.useState(); const [isTouchDevice, setIsTouchDevice] = react.useState(false); react.useEffect(() => { const checkTouchDevice = () => { setIsTouchDevice('ontouchstart' in window || navigator.maxTouchPoints > 0); }; checkTouchDevice(); window.addEventListener('resize', checkTouchDevice); return () => window.removeEventListener('resize', checkTouchDevice); }, []); react.useEffect(() => { if (isTouchDevice && !enableOnTouch) { return; } if (variant !== 'input') { document.body.classList.add('phazr-cursor-none'); } else { document.body.classList.remove('phazr-cursor-none'); } return () => { document.body.classList.remove('phazr-cursor-none'); }; }, [variant, isTouchDevice, enableOnTouch]); const setVariantCallback = react.useCallback((newVariant) => { setVariant(newVariant); }, []); const setCustomConfigCallback = react.useCallback((config) => { setCustomConfig(config); }, []); if (isTouchDevice && !enableOnTouch) { return jsxRuntime.jsx("div", { className: className, children: children }); } return (jsxRuntime.jsx(CursorContext.Provider, { value: { variant, setVariant: setVariantCallback, customConfig, setCustomConfig: setCustomConfigCallback, }, children: jsxRuntime.jsx("div", { className: className, children: children }) })); } function Cursor({ className = '', springConfig = { damping: 28, stiffness: 500 }, }) { const { variant, customConfig } = useCursor(); const [isTouchDevice, setIsTouchDevice] = react.useState(false); const cursorX = react$1.useMotionValue(-100); const cursorY = react$1.useMotionValue(-100); const cursorXSpring = react$1.useSpring(cursorX, springConfig); const cursorYSpring = react$1.useSpring(cursorY, springConfig); react.useEffect(() => { setIsTouchDevice('ontouchstart' in window || navigator.maxTouchPoints > 0); }, []); react.useEffect(() => { if (isTouchDevice) return; const mouseMove = (e) => { cursorX.set(e.clientX); cursorY.set(e.clientY); }; window.addEventListener('mousemove', mouseMove); return () => { window.removeEventListener('mousemove', mouseMove); }; }, [cursorX, cursorY, isTouchDevice]); if (isTouchDevice) { return null; } const cursorVariants = { default: { height: 16, width: 16, backgroundColor: '#fff', mixBlendMode: 'difference', }, link: { height: 64, width: 64, backgroundColor: '#fff', mixBlendMode: 'difference', }, text: { height: 8, width: 8, backgroundColor: '#fff', mixBlendMode: 'difference', }, input: { height: 0, width: 0, opacity: 0, }, sayHi: { height: 90, width: 90, backgroundColor: '#fff', mixBlendMode: 'difference', }, custom: { height: customConfig?.size || 32, width: customConfig?.size || 32, backgroundColor: customConfig?.backgroundColor || '#fff', mixBlendMode: customConfig?.mixBlendMode || 'difference', }, }; const textVariants = { default: { opacity: 0, transition: { duration: 0.1 } }, link: { opacity: 0, transition: { duration: 0.1 } }, text: { opacity: 0, transition: { duration: 0.1 } }, input: { opacity: 0, transition: { duration: 0.1 } }, sayHi: { opacity: 1, transition: { delay: 0.1 } }, custom: { opacity: customConfig?.text ? 1 : 0, transition: { delay: customConfig?.text ? 0.1 : 0 }, }, }; return (jsxRuntime.jsx(react$1.motion.div, { variants: cursorVariants, animate: variant, style: { left: cursorXSpring, top: cursorYSpring, x: '-50%', y: '-50%', }, className: `phazr-cursor-container ${className}`, children: jsxRuntime.jsxs(react$1.motion.div, { variants: textVariants, animate: variant, className: "phazr-cursor-text", style: { color: customConfig?.textColor || '#000', fontSize: customConfig?.fontSize || '16px', fontFamily: customConfig?.fontFamily || 'inherit', }, children: [variant === 'sayHi' && (jsxRuntime.jsxs("div", { className: "phazr-cursor-sayhi", children: [jsxRuntime.jsx("span", { children: "Say" }), jsxRuntime.jsx("span", { children: "Hi" })] })), variant === 'custom' && customConfig?.text && (jsxRuntime.jsx("span", { children: customConfig.text }))] }) })); } exports.Cursor = Cursor; exports.CursorProvider = CursorProvider; exports.useCursor = useCursor; //# sourceMappingURL=index.js.map