use-move-note.ts


Overview

The use-move-note.ts file defines a custom React hook named useMoveNote. This hook facilitates the dynamic positioning and visibility control of an SVG element (typically used as a note or tooltip) relative to the user's mouse cursor. It leverages the useMouse hook from the ahooks library to track mouse coordinates and React's state and refs to manage the visibility and position of the SVG element.

This hook is particularly useful in UI scenarios where a floating note, tooltip, or helper graphic needs to follow the mouse cursor smoothly, appearing or disappearing based on user interaction or application state.


Detailed Description of useMoveNote Hook

Function Signature

function useMoveNote(): {
  ref: React.RefObject<SVGSVGElement>;
  showImage: () => void;
  hideImage: () => void;
  mouse: { clientX: number; clientY: number; };
  imgVisible: boolean;
}

Purpose


Internal Logic and Implementation Details

  1. Ref (ref)
    A React ref attached to an SVG element (SVGSVGElement). This ref is used to directly manipulate the SVG's CSS top and left properties to position it near the cursor.

  2. Mouse Position (mouse)
    Obtained from the useMouse hook (from ahooks), which provides the current mouse coordinates (clientX, clientY) relative to the viewport.

  3. Visibility State (imgVisible)
    A boolean state flag that controls whether the SVG element is visible or hidden.

  4. Visibility Control Functions

    • toggleVisible(visible: boolean): Sets imgVisible to the given boolean.

    • showImage(): Calls toggleVisible(true) to show the SVG.

    • hideImage(): Calls toggleVisible(false) to hide the SVG.

  5. Position Update Effect
    A useEffect hook watches changes in mouse coordinates (mouse.clientX, mouse.clientY). When the mouse moves:

    • The SVG element's style.top is set to mouse.clientY - 70 pixels.

    • The SVG element's style.left is set to mouse.clientX + 10 pixels.

    This offset positions the SVG slightly above and to the right of the cursor to avoid obstructing the pointer.


Returned Object

The hook returns an object containing:

Property

Type

Description

ref

React.RefObject<SVGSVGElement>

Ref to be assigned to the SVG element to control position

showImage

() => void

Function to make the SVG element visible

hideImage

() => void

Function to hide the SVG element

mouse

{ clientX: number; clientY: number; }

Current mouse coordinates

imgVisible

boolean

Current visibility state of the SVG element


Usage Example

import React from 'react';
import { useMoveNote } from './use-move-note';

export function MoveNoteExample() {
  const { ref, showImage, hideImage, imgVisible } = useMoveNote();

  return (
    <>
      <button
        onMouseEnter={showImage}
        onMouseLeave={hideImage}
      >
        Hover me
      </button>

      {imgVisible && (
        <svg
          ref={ref}
          style={{
            position: 'fixed',
            pointerEvents: 'none',
            transition: 'top 0.1s, left 0.1s',
            width: '100px',
            height: '50px',
            backgroundColor: 'rgba(0,0,0,0.7)',
            color: 'white',
          }}
        >
          <text x="10" y="20">Note follows cursor</text>
        </svg>
      )}
    </>
  );
}

In this example:


Interaction with Other Parts of the Application


Important Implementation Notes


Mermaid Diagram: Flowchart of useMoveNote Hook

flowchart TD
    A[useMoveNote Hook] --> B[Initialize ref (SVGSVGElement)]
    A --> C[Track mouse position using useMouse]
    A --> D[State: imgVisible (boolean)]
    A --> E[Define toggleVisible(visible)]
    E --> F[showImage() calls toggleVisible(true)]
    E --> G[hideImage() calls toggleVisible(false)]
    C --> H[useEffect: on mouse movement]
    H --> I[Update ref.current.style.top and left]
    A --> J[Return { ref, showImage, hideImage, mouse, imgVisible }]

Summary

The useMoveNote hook is a streamlined utility for React applications to display and position an SVG note relative to the user's mouse cursor. It abstracts the management of mouse tracking, element positioning, and visibility toggling into a reusable hook, enhancing UI interactivity with minimal setup. It is designed for easy integration with components that require floating annotations, tooltips, or helper visuals that follow the cursor dynamically.