Use Mouse Vector

PreviousNext

A hook component.

Docs
fancyhook

Preview

Loading preview…
hooks/use-mouse-vector.ts
import { RefObject, useEffect, useState } from "react"

export const useMouseVector = (
  containerRef?: RefObject<HTMLElement | SVGElement | null>
) => {
  const [position, setPosition] = useState({ x: 0, y: 0 })
  const [vector, setVector] = useState({ dx: 0, dy: 0 })

  useEffect(() => {
    let lastPosition = { x: 0, y: 0 }

    const updatePosition = (x: number, y: number) => {
      let newX, newY

      if (containerRef && containerRef.current) {
        const rect = containerRef.current.getBoundingClientRect()
        newX = x - rect.left
        newY = y - rect.top
      } else {
        newX = x
        newY = y
      }

      // Calculate the movement vector
      const dx = newX - lastPosition.x
      const dy = newY - lastPosition.y

      setVector({ dx, dy })
      setPosition({ x: newX, y: newY })
      lastPosition = { x: newX, y: newY }
    }

    const handleMouseMove = (ev: MouseEvent) => {
      updatePosition(ev.clientX, ev.clientY)
    }

    const handleTouchMove = (ev: TouchEvent) => {
      const touch = ev.touches[0]
      updatePosition(touch.clientX, touch.clientY)
    }

    // Listen for both mouse and touch events
    window.addEventListener("mousemove", handleMouseMove)
    window.addEventListener("touchmove", handleTouchMove)

    return () => {
      window.removeEventListener("mousemove", handleMouseMove)
      window.removeEventListener("touchmove", handleTouchMove)
    }
  }, [containerRef])

  return { position, vector }
}

Installation

npx shadcn@latest add @fancy/use-mouse-vector

Usage

import { UseMouseVector } from "@/hooks/use-mouse-vector"
const value = UseMouseVector()