{"_id":"@aniruddha1806/use-mouse-move","_rev":"2-550e3baf81436829adc7b9e25130e7ff","name":"@aniruddha1806/use-mouse-move","dist-tags":{"latest":"1.0.1"},"versions":{"1.0.0":{"name":"@aniruddha1806/use-mouse-move","version":"1.0.0","keywords":["react","hook","mouse","position","tracking","throttle","debounce"],"author":{"name":"Your Name"},"license":"MIT","_id":"@aniruddha1806/use-mouse-move@1.0.0","maintainers":[{"name":"aniruddha1806","email":"aniruddha.kulkarni1806@gmail.com"}],"dist":{"shasum":"238fa0222bc358c75a614874f29e271d0df11536","tarball":"https://registry.npmjs.org/@aniruddha1806/use-mouse-move/-/use-mouse-move-1.0.0.tgz","fileCount":5,"integrity":"sha512-JEZ7PpXrZUGni/tvuSJV0izoNrXpaFOmADnNZX4nNNLHXLQdkLTzwUGXwPd46RndKdE0X0PNH82qu6Dk+L58ug==","signatures":[{"sig":"MEUCIQCt5/n9WXsTBLnDGRToCqWv/hdjmofO/HyRnoWW0C5cMgIgXLNb3PNc+VFJMOGL+sZ9pzuL++RyG0l7yNd/07Y8gVY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":16719},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","module":"dist/index.esm.js","scripts":{"test":"jest","build":"rollup -c","prepublishOnly":"npm run build"},"_npmUser":{"name":"aniruddha1806","email":"aniruddha.kulkarni1806@gmail.com"},"_npmVersion":"10.9.1","description":"A lightweight React hook for tracking mouse position with throttling and debouncing","directories":{},"_nodeVersion":"20.14.0","_hasShrinkwrap":false,"devDependencies":{"rollup":"^3.25.1","typescript":"^5.1.3","@babel/core":"^7.22.5","@babel/preset-env":"^7.22.5","@babel/preset-react":"^7.22.5","@rollup/plugin-babel":"^6.0.3","@rollup/plugin-terser":"^0.4.3","@rollup/plugin-commonjs":"^25.0.0","rollup-plugin-typescript2":"^0.34.1","@rollup/plugin-node-resolve":"^15.1.0","rollup-plugin-peer-deps-external":"^2.2.4"},"peerDependencies":{"react":">=16.8.0","react-dom":">=16.8.0"},"_npmOperationalInternal":{"tmp":"tmp/use-mouse-move_1.0.0_1744385462482_0.23089620431771718","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@aniruddha1806/use-mouse-move","version":"1.0.1","type":"module","description":"A lightweight React hook for tracking mouse position with throttling and debouncing","main":"dist/index.js","module":"dist/index.esm.js","types":"dist/index.d.ts","scripts":{"build":"rollup -c","test":"jest","prepublishOnly":"npm run build"},"keywords":["react","hook","mouse","position","tracking","throttle","debounce"],"author":{"name":"Your Name"},"license":"MIT","peerDependencies":{"react":">=16.8.0","react-dom":">=16.8.0"},"devDependencies":{"@babel/core":"^7.22.5","@babel/preset-env":"^7.22.5","@babel/preset-react":"^7.22.5","@rollup/plugin-babel":"^6.0.3","@rollup/plugin-commonjs":"^25.0.0","@rollup/plugin-node-resolve":"^15.1.0","@rollup/plugin-terser":"^0.4.3","rollup":"^3.25.1","rollup-plugin-peer-deps-external":"^2.2.4","rollup-plugin-typescript2":"^0.34.1","typescript":"^5.1.3"},"_id":"@aniruddha1806/use-mouse-move@1.0.1","_nodeVersion":"20.14.0","_npmVersion":"10.9.1","dist":{"integrity":"sha512-f/TnsQHgTbbrD6OX5JkccHxYSeZ2pRSCZibPMF33tnqhL05XyeuYm1f4Z1xGqL7JRvSwf9cgFl2X0WyzRIFKEA==","shasum":"173c137d2e4ae8810f1ff1908e91c129c6171f5b","tarball":"https://registry.npmjs.org/@aniruddha1806/use-mouse-move/-/use-mouse-move-1.0.1.tgz","fileCount":6,"unpackedSize":31514,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDDyZiUQliXM5KJIU0wKzYJ8hCk9x7AFkCBgeaIYPxc4QIgQ7OgVGPi7dYK6Bjc6T5FjFMqYu1s7W7JzyIAHy8TaLE="}]},"_npmUser":{"name":"aniruddha1806","email":"aniruddha.kulkarni1806@gmail.com"},"directories":{},"maintainers":[{"name":"aniruddha1806","email":"aniruddha.kulkarni1806@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/use-mouse-move_1.0.1_1749389907575_0.8233844796124716"},"_hasShrinkwrap":false}},"time":{"created":"2025-04-11T15:31:02.373Z","modified":"2025-06-08T13:38:27.970Z","1.0.0":"2025-04-11T15:31:02.650Z","1.0.1":"2025-06-08T13:38:27.777Z"},"author":{"name":"Your Name"},"license":"MIT","keywords":["react","hook","mouse","position","tracking","throttle","debounce"],"description":"A lightweight React hook for tracking mouse position with throttling and debouncing","maintainers":[{"name":"aniruddha1806","email":"aniruddha.kulkarni1806@gmail.com"}],"readme":"# React useMouseMove Hook\r\n\r\nA powerful React hook for tracking mouse position with support for element-specific coordinates, performance optimization through throttling and debouncing, and boundary detection.\r\n\r\n## Installation\r\n\r\n```bash\r\nnpm install @aniruddha1806/use-mouse-move\r\n```\r\n\r\n## Features\r\n\r\n- 🖱️ **Global Mouse Tracking**: Track mouse position across the entire viewport\r\n- 🎯 **Element-Specific Tracking**: Get mouse coordinates relative to any element\r\n- ⚡ **Performance Optimized**: Built-in throttling and debouncing options\r\n- 🔍 **Boundary Detection**: Know when mouse is within element bounds\r\n- 📱 **Responsive**: Works with dynamic element sizes and positions\r\n- 🎨 **Flexible**: Use for hover effects, drag operations, cursor followers\r\n- 🪶 **Lightweight**: Zero dependencies beyond React\r\n- 🔧 **Easy Integration**: Simple API with sensible defaults\r\n\r\n## Quick Start\r\n\r\n```jsx\r\nimport { useMouseMove } from '@aniruddha1806/use-mouse-move';\r\n\r\nfunction App() {\r\n  const { x, y } = useMouseMove();\r\n  \r\n  return (\r\n    <div>\r\n      <h1>Mouse Tracker</h1>\r\n      <p>Mouse position: ({x}, {y})</p>\r\n    </div>\r\n  );\r\n}\r\n```\r\n\r\n## API\r\n\r\n### Parameters\r\n\r\nThe hook accepts an options object with the following properties:\r\n\r\n| Option | Type | Default | Description |\r\n|--------|------|---------|-------------|\r\n| `element` | `RefObject<HTMLElement>` | `null` | Element to track mouse position within |\r\n| `throttle` | `number` | `0` | Throttle updates in milliseconds (0 = disabled) |\r\n| `debounce` | `number` | `0` | Debounce updates in milliseconds (0 = disabled) |\r\n\r\n### Returns\r\n\r\nThe hook returns an object with the following properties:\r\n\r\n| Property | Type | Description |\r\n|----------|------|-------------|\r\n| `x` | `number` | Global mouse X coordinate |\r\n| `y` | `number` | Global mouse Y coordinate |\r\n| `elementX` | `number \\| null` | Mouse X coordinate relative to element |\r\n| `elementY` | `number \\| null` | Mouse Y coordinate relative to element |\r\n| `isInBounds` | `boolean` | Whether mouse is within element boundaries |\r\n\r\n## Examples\r\n\r\n### Basic Global Mouse Tracking\r\n\r\nTrack mouse position across the entire viewport:\r\n\r\n```jsx\r\nimport { useMouseMove } from '@aniruddha1806/use-mouse-move';\r\n\r\nfunction GlobalMouseTracker() {\r\n  const { x, y } = useMouseMove();\r\n  \r\n  return (\r\n    <div style={{ height: '100vh', padding: '20px' }}>\r\n      <h2>Global Mouse Position</h2>\r\n      <p>X: {x}px</p>\r\n      <p>Y: {y}px</p>\r\n      \r\n      {/* Visual indicator */}\r\n      <div\r\n        style={{\r\n          position: 'fixed',\r\n          left: x - 5,\r\n          top: y - 5,\r\n          width: '10px',\r\n          height: '10px',\r\n          backgroundColor: 'red',\r\n          borderRadius: '50%',\r\n          pointerEvents: 'none',\r\n          zIndex: 9999,\r\n        }}\r\n      />\r\n    </div>\r\n  );\r\n}\r\n```\r\n\r\n### Element-Specific Mouse Tracking\r\n\r\nTrack mouse position relative to a specific element:\r\n\r\n```jsx\r\nimport { useRef } from 'react';\r\nimport { useMouseMove } from '@aniruddha1806/use-mouse-move';\r\n\r\nfunction ElementMouseTracker() {\r\n  const boxRef = useRef(null);\r\n  const { x, y, elementX, elementY, isInBounds } = useMouseMove({\r\n    element: boxRef\r\n  });\r\n  \r\n  return (\r\n    <div style={{ padding: '20px' }}>\r\n      <h2>Element Mouse Tracking</h2>\r\n      \r\n      <div\r\n        ref={boxRef}\r\n        style={{\r\n          width: '400px',\r\n          height: '300px',\r\n          border: '2px solid #333',\r\n          backgroundColor: isInBounds ? '#e8f5e8' : '#f5f5f5',\r\n          position: 'relative',\r\n          margin: '20px 0',\r\n        }}\r\n      >\r\n        <div style={{ padding: '10px' }}>\r\n          <p>Global: ({x}, {y})</p>\r\n          <p>Element: ({elementX}, {elementY})</p>\r\n          <p>In bounds: {isInBounds ? 'Yes' : 'No'}</p>\r\n        </div>\r\n        \r\n        {/* Show mouse position within element */}\r\n        {isInBounds && (\r\n          <div\r\n            style={{\r\n              position: 'absolute',\r\n              left: elementX - 5,\r\n              top: elementY - 5,\r\n              width: '10px',\r\n              height: '10px',\r\n              backgroundColor: 'blue',\r\n              borderRadius: '50%',\r\n              pointerEvents: 'none',\r\n            }}\r\n          />\r\n        )}\r\n      </div>\r\n    </div>\r\n  );\r\n}\r\n```\r\n\r\n### Performance Optimization with Throttling\r\n\r\nUse throttling to limit update frequency for better performance:\r\n\r\n```jsx\r\nimport { useMouseMove } from '@aniruddha1806/use-mouse-move';\r\n\r\nfunction ThrottledMouseTracker() {\r\n  // Update position at most every 16ms (~60fps)\r\n  const { x, y } = useMouseMove({ throttle: 16 });\r\n  \r\n  return (\r\n    <div style={{ height: '100vh', padding: '20px' }}>\r\n      <h2>Throttled Mouse Tracking (60fps)</h2>\r\n      <p>Position: ({x}, {y})</p>\r\n      <p>Updates are throttled to ~60fps for smooth performance</p>\r\n      \r\n      {/* Smooth following cursor */}\r\n      <div\r\n        style={{\r\n          position: 'fixed',\r\n          left: x - 25,\r\n          top: y - 25,\r\n          width: '50px',\r\n          height: '50px',\r\n          backgroundColor: 'rgba(0, 123, 255, 0.7)',\r\n          borderRadius: '50%',\r\n          pointerEvents: 'none',\r\n          transition: 'transform 0.1s ease-out',\r\n          transform: 'scale(1)',\r\n        }}\r\n      />\r\n    </div>\r\n  );\r\n}\r\n```\r\n\r\n### Debounced Mouse Tracking\r\n\r\nUse debouncing to delay updates until mouse stops moving:\r\n\r\n```jsx\r\nimport { useState } from 'react';\r\nimport { useMouseMove } from '@aniruddha1806/use-mouse-move';\r\n\r\nfunction DebouncedMouseTracker() {\r\n  const [lastStoppedPosition, setLastStoppedPosition] = useState({ x: 0, y: 0 });\r\n  \r\n  // Update position only after mouse stops moving for 300ms\r\n  const { x, y } = useMouseMove({ debounce: 300 });\r\n  \r\n  // Update stopped position when debounced position changes\r\n  React.useEffect(() => {\r\n    setLastStoppedPosition({ x, y });\r\n  }, [x, y]);\r\n  \r\n  return (\r\n    <div style={{ height: '100vh', padding: '20px' }}>\r\n      <h2>Debounced Mouse Tracking</h2>\r\n      <p>Move your mouse around and stop...</p>\r\n      <p>Last stopped position: ({lastStoppedPosition.x}, {lastStoppedPosition.y})</p>\r\n      \r\n      {/* Show marker where mouse last stopped */}\r\n      <div\r\n        style={{\r\n          position: 'fixed',\r\n          left: lastStoppedPosition.x - 10,\r\n          top: lastStoppedPosition.y - 10,\r\n          width: '20px',\r\n          height: '20px',\r\n          backgroundColor: 'green',\r\n          borderRadius: '50%',\r\n          pointerEvents: 'none',\r\n        }}\r\n      />\r\n    </div>\r\n  );\r\n}\r\n```\r\n\r\n### Interactive Hover Effects\r\n\r\nCreate interactive hover effects using element tracking:\r\n\r\n```jsx\r\nimport { useRef } from 'react';\r\nimport { useMouseMove } from '@aniruddha1806/use-mouse-move';\r\n\r\nfunction InteractiveCard() {\r\n  const cardRef = useRef(null);\r\n  const { elementX, elementY, isInBounds } = useMouseMove({\r\n    element: cardRef,\r\n    throttle: 16\r\n  });\r\n  \r\n  // Calculate rotation based on mouse position\r\n  const getRotation = () => {\r\n    if (!isInBounds || !cardRef.current) return { rotateX: 0, rotateY: 0 };\r\n    \r\n    const { clientWidth, clientHeight } = cardRef.current;\r\n    const centerX = clientWidth / 2;\r\n    const centerY = clientHeight / 2;\r\n    \r\n    const rotateX = ((elementY - centerY) / centerY) * -10;\r\n    const rotateY = ((elementX - centerX) / centerX) * 10;\r\n    \r\n    return { rotateX, rotateY };\r\n  };\r\n  \r\n  const { rotateX, rotateY } = getRotation();\r\n  \r\n  return (\r\n    <div style={{ padding: '50px', display: 'flex', justifyContent: 'center' }}>\r\n      <div\r\n        ref={cardRef}\r\n        style={{\r\n          width: '300px',\r\n          height: '200px',\r\n          backgroundColor: '#fff',\r\n          borderRadius: '12px',\r\n          boxShadow: '0 10px 30px rgba(0,0,0,0.2)',\r\n          display: 'flex',\r\n          alignItems: 'center',\r\n          justifyContent: 'center',\r\n          cursor: 'pointer',\r\n          transform: `perspective(1000px) rotateX(\\${rotateX}deg) rotateY(\\${rotateY}deg) scale(\\${isInBounds ? 1.05 : 1})`,\r\n          transition: isInBounds ? 'none' : 'transform 0.3s ease-out',\r\n        }}\r\n      >\r\n        <div style={{ textAlign: 'center' }}>\r\n          <h3>Interactive Card</h3>\r\n          <p>Hover to see 3D effect</p>\r\n          {isInBounds && (\r\n            <p style={{ fontSize: '12px', color: '#666' }}>\r\n              Mouse: ({Math.round(elementX)}, {Math.round(elementY)})\r\n            </p>\r\n          )}\r\n        </div>\r\n      </div>\r\n    </div>\r\n  );\r\n}\r\n```\r\n\r\n### Cursor Follower\r\n\r\nCreate a custom cursor that follows the mouse:\r\n\r\n```jsx\r\nimport { useMouseMove } from '@aniruddha1806/use-mouse-move';\r\n\r\nfunction CursorFollower() {\r\n  const { x, y } = useMouseMove({ throttle: 8 });\r\n  \r\n  return (\r\n    <div style={{ height: '100vh', cursor: 'none' }}>\r\n      <div style={{ padding: '20px' }}>\r\n        <h2>Custom Cursor Follower</h2>\r\n        <p>Move your mouse around to see the custom cursor</p>\r\n        <button style={{ margin: '10px', padding: '10px 20px' }}>\r\n          Hover me\r\n        </button>\r\n        <button style={{ margin: '10px', padding: '10px 20px' }}>\r\n          And me\r\n        </button>\r\n      </div>\r\n      \r\n      {/* Custom cursor */}\r\n      <div\r\n        style={{\r\n          position: 'fixed',\r\n          left: x,\r\n          top: y,\r\n          width: '20px',\r\n          height: '20px',\r\n          backgroundColor: 'rgba(255, 0, 150, 0.8)',\r\n          borderRadius: '50%',\r\n          pointerEvents: 'none',\r\n          zIndex: 9999,\r\n          transform: 'translate(-50%, -50%)',\r\n          transition: 'transform 0.1s ease-out',\r\n        }}\r\n      />\r\n      \r\n      {/* Cursor trail */}\r\n      <div\r\n        style={{\r\n          position: 'fixed',\r\n          left: x,\r\n          top: y,\r\n          width: '40px',\r\n          height: '40px',\r\n          border: '2px solid rgba(255, 0, 150, 0.3)',\r\n          borderRadius: '50%',\r\n          pointerEvents: 'none',\r\n          zIndex: 9998,\r\n          transform: 'translate(-50%, -50%)',\r\n          transition: 'all 0.2s ease-out',\r\n        }}\r\n      />\r\n    </div>\r\n  );\r\n}\r\n```\r\n\r\n### Drawing Canvas\r\n\r\nUse mouse tracking for drawing applications:\r\n\r\n```jsx\r\nimport { useRef, useState, useEffect } from 'react';\r\nimport { useMouseMove } from '@aniruddha1806/use-mouse-move';\r\n\r\nfunction DrawingCanvas() {\r\n  const canvasRef = useRef(null);\r\n  const [isDrawing, setIsDrawing] = useState(false);\r\n  const [lastPosition, setLastPosition] = useState({ x: 0, y: 0 });\r\n  \r\n  const { elementX, elementY, isInBounds } = useMouseMove({\r\n    element: canvasRef,\r\n    throttle: 8\r\n  });\r\n  \r\n  // Handle drawing\r\n  useEffect(() => {\r\n    if (!isDrawing || !isInBounds || !canvasRef.current) return;\r\n    \r\n    const canvas = canvasRef.current;\r\n    const ctx = canvas.getContext('2d');\r\n    \r\n    ctx.beginPath();\r\n    ctx.moveTo(lastPosition.x, lastPosition.y);\r\n    ctx.lineTo(elementX, elementY);\r\n    ctx.stroke();\r\n    \r\n    setLastPosition({ x: elementX, y: elementY });\r\n  }, [elementX, elementY, isDrawing, isInBounds, lastPosition]);\r\n  \r\n  const startDrawing = (e) => {\r\n    setIsDrawing(true);\r\n    setLastPosition({ x: elementX, y: elementY });\r\n  };\r\n  \r\n  const stopDrawing = () => {\r\n    setIsDrawing(false);\r\n  };\r\n  \r\n  const clearCanvas = () => {\r\n    const canvas = canvasRef.current;\r\n    const ctx = canvas.getContext('2d');\r\n    ctx.clearRect(0, 0, canvas.width, canvas.height);\r\n  };\r\n  \r\n  return (\r\n    <div style={{ padding: '20px' }}>\r\n      <h2>Drawing Canvas</h2>\r\n      <p>Click and drag to draw</p>\r\n      \r\n      <div style={{ marginBottom: '10px' }}>\r\n        <button onClick={clearCanvas}>Clear Canvas</button>\r\n      </div>\r\n      \r\n      <canvas\r\n        ref={canvasRef}\r\n        width={600}\r\n        height={400}\r\n        onMouseDown={startDrawing}\r\n        onMouseUp={stopDrawing}\r\n        onMouseLeave={stopDrawing}\r\n        style={{\r\n          border: '2px solid #333',\r\n          cursor: 'crosshair',\r\n          backgroundColor: 'white',\r\n        }}\r\n      />\r\n      \r\n      <p style={{ marginTop: '10px', fontSize: '14px', color: '#666' }}>\r\n        Mouse: ({Math.round(elementX || 0)}, {Math.round(elementY || 0)}) | \r\n        Drawing: {isDrawing ? 'Yes' : 'No'}\r\n      </p>\r\n    </div>\r\n  );\r\n}\r\n```\r\n\r\n## TypeScript Usage\r\n\r\nThe hook provides full TypeScript support:\r\n\r\n```typescript\r\nimport { useRef } from 'react';\r\nimport { useMouseMove } from '@aniruddha1806/use-mouse-move';\r\n\r\ninterface MousePosition {\r\n  x: number;\r\n  y: number;\r\n  elementX: number | null;\r\n  elementY: number | null;\r\n  isInBounds: boolean;\r\n}\r\n\r\ninterface UseMouseMoveOptions {\r\n  element?: React.RefObject<HTMLElement> | null;\r\n  throttle?: number;\r\n  debounce?: number;\r\n}\r\n\r\nfunction TypedMouseTracker() {\r\n  const elementRef = useRef<HTMLDivElement>(null);\r\n  \r\n  // Hook with typed options\r\n  const options: UseMouseMoveOptions = {\r\n    element: elementRef,\r\n    throttle: 16,\r\n    debounce: 0\r\n  };\r\n  \r\n  // Destructure with proper typing\r\n  const mouseData: MousePosition = useMouseMove(options);\r\n  const { x, y, elementX, elementY, isInBounds } = mouseData;\r\n  \r\n  return (\r\n    <div>\r\n      <div ref={elementRef} style={{ width: 300, height: 200, border: '1px solid #ccc' }}>\r\n        <p>Global: ({x}, {y})</p>\r\n        <p>Element: ({elementX}, {elementY})</p>\r\n        <p>In bounds: {isInBounds.toString()}</p>\r\n      </div>\r\n    </div>\r\n  );\r\n}\r\n\r\n// Custom hook using useMouseMove\r\nfunction useMouseDistance(elementRef: React.RefObject<HTMLElement>) {\r\n  const { elementX, elementY, isInBounds } = useMouseMove({\r\n    element: elementRef,\r\n    throttle: 16\r\n  });\r\n  \r\n  const distance = React.useMemo(() => {\r\n    if (!isInBounds || elementX === null || elementY === null || !elementRef.current) {\r\n      return 0;\r\n    }\r\n    \r\n    const centerX = elementRef.current.clientWidth / 2;\r\n    const centerY = elementRef.current.clientHeight / 2;\r\n    \r\n    return Math.sqrt(\r\n      Math.pow(elementX - centerX, 2) + Math.pow(elementY - centerY, 2)\r\n    );\r\n  }, [elementX, elementY, isInBounds, elementRef]);\r\n  \r\n  return { distance, isInBounds };\r\n}\r\n```\r\n\r\n## Performance Tips\r\n\r\n### 1. Use Throttling for Smooth Animations\r\n\r\nFor smooth 60fps animations, use a 16ms throttle:\r\n\r\n```jsx\r\nconst { x, y } = useMouseMove({ throttle: 16 });\r\n```\r\n\r\n### 2. Use Debouncing for Expensive Operations\r\n\r\nFor operations that don't need real-time updates:\r\n\r\n```jsx\r\nconst { x, y } = useMouseMove({ debounce: 100 });\r\n```\r\n\r\n### 3. Combine with useMemo for Complex Calculations\r\n\r\n```jsx\r\nconst { elementX, elementY } = useMouseMove({ element: ref });\r\n\r\nconst expensiveCalculation = useMemo(() => {\r\n  // Expensive calculation based on mouse position\r\n  return complexFunction(elementX, elementY);\r\n}, [elementX, elementY]);\r\n```\r\n\r\n\r\n\r\n","readmeFilename":"README.md"}