Docs
Ink Cursor

Ink Cursor

Ink Cursor

Try it on the whole page

Create inkCursor.js file

Copy and paste the following code

import React, { useRef, useEffect } from "react";
 
const useInkCursor = () => {
  const canvasRef = useRef(null);
  const ctxRef = useRef(null);
  const pointerRef = useRef({
    x: null,
    y: null,
  });
  const trailRef = useRef([]);
  const paramsRef = useRef({
    pointsNumber: 40,
    widthFactor: 0.3,
    mouseThreshold: 0.6,
    spring: 0.4,
    friction: 0.5,
  });
 
  useEffect(() => {
      pointerRef.current = {
        x: 0.5 * window.innerWidth,
        y: 0.5 * window.innerHeight,
      };
      const canvas = canvasRef.current;
      const ctx = canvas.getContext("2d");
      ctxRef.current = ctx;
 
      // Initialize trail array
      const trail = new Array(paramsRef.current.pointsNumber).fill(null).map(() => ({
        x: pointerRef.current.x,
        y: pointerRef.current.y,
        dx: 0,
        dy: 0,
      }));
      trailRef.current = trail;
 
      const updateMousePosition = (x, y) => {
        pointerRef.current.x = x;
        pointerRef.current.y = y;
      };
 
      const handleMouseMove = (e) => {
        updateMousePosition(e.clientX, e.clientY);
      };
 
      const handleTouchMove = (e) => {
        updateMousePosition(e.targetTouches[0].clientX, e.targetTouches[0].clientY);
      };
 
      const setupCanvas = () => {
        canvas.width = window.innerWidth;
        canvas.height = window.innerHeight;
      };
 
      const update = (t) => {
        ctx.clearRect(0, 0, canvas.width, canvas.height);
 
        const gradient = ctx.createLinearGradient(0, 0, canvas.width, canvas.height);
        gradient.addColorStop(0, "#833ab4");
        gradient.addColorStop(1, "#fd1d1d");
 
        ctx.strokeStyle = gradient;
 
        trailRef.current.forEach((p, pIdx) => {
          const prev = pIdx === 0 ? pointerRef.current : trailRef.current[pIdx - 1];
          const spring = pIdx === 0 ? 0.4 * paramsRef.current.spring : paramsRef.current.spring;
          p.dx += (prev.x - p.x) * spring;
          p.dy += (prev.y - p.y) * spring;
          p.dx *= paramsRef.current.friction;
          p.dy *= paramsRef.current.friction;
          p.x += p.dx;
          p.y += p.dy;
        });
 
        ctx.lineCap = "round";
        ctx.beginPath();
        ctx.moveTo(trailRef.current[0].x, trailRef.current[0].y);
 
        for (let i = 1; i < trailRef.current.length - 1; i++) {
          const xc = 0.5 * (trailRef.current[i].x + trailRef.current[i + 1].x);
          const yc = 0.5 * (trailRef.current[i].y + trailRef.current[i + 1].y);
 
          ctx.quadraticCurveTo(trailRef.current[i].x, trailRef.current[i].y, xc, yc);
          ctx.lineWidth = paramsRef.current.widthFactor * (paramsRef.current.pointsNumber - i);
          ctx.stroke();
        }
        ctx.lineTo(trailRef.current[trailRef.current.length - 1].x, trailRef.current[trailRef.current.length - 1].y);
        ctx.stroke();
 
        window.requestAnimationFrame(update);
      };
 
      setupCanvas();
      update(0);
 
      window.addEventListener("mousemove", handleMouseMove);
      window.addEventListener("touchmove", handleTouchMove);
      window.addEventListener("resize", setupCanvas);
 
      return () => {
        window.removeEventListener("mousemove", handleMouseMove);
        window.removeEventListener("touchmove", handleTouchMove);
        window.removeEventListener("resize", setupCanvas);
      };
 
  }, []);
 
  return (
    <canvas
      ref={canvasRef}
      className="h-screen w-screen"
    />
  );
};
 
export default useInkCursor;
 

Create New Component

Copy and paste the following code into your project.

components/edil-ozi/ink-cursor.tsx
'use client'
 
import useInkCursor from '@/hooks/inkCursor'
 
const InkCursor = () => {
 
  const inkCursorComponent = useInkCursor();
 
  return (
    <>
      <div className='bg-zinc-100 dark:bg-zinc-900 w-full flex items-center justify-center text-center h-[350px] z-[10]'>
        Try it on the whole page
      </div>
      <div className='fixed top-0 left-0 z-[9]'>
        {inkCursorComponent}
      </div>
    </>
  )
};
export default InkCursor

Credits

RunicFreak