| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 | import type { FC } from 'react'import { useCallback, useEffect, useRef } from 'react'type GridMaskProps = {  children: React.ReactNode  wrapperClassName?: string  canvasClassName?: string  gradientClassName?: string}const GridMask: FC<GridMaskProps> = ({  children,  wrapperClassName,  canvasClassName,  gradientClassName,}) => {  const canvasRef = useRef<HTMLCanvasElement | null>(null)  const ctxRef = useRef<CanvasRenderingContext2D | null>(null)  const initCanvas = () => {    const dpr = window.devicePixelRatio || 1    if (canvasRef.current) {      const { width: cssWidth, height: cssHeight } = canvasRef.current?.getBoundingClientRect()      canvasRef.current.width = dpr * cssWidth      canvasRef.current.height = dpr * cssHeight      const ctx = canvasRef.current.getContext('2d')      if (ctx) {        ctx.scale(dpr, dpr)        ctx.strokeStyle = '#D1E0FF'        ctxRef.current = ctx      }    }  }  const drawRecord = useCallback(() => {    const canvas = canvasRef.current!    const ctx = ctxRef.current!    const rowNumber = parseInt(`${canvas.width / 24}`)    const colNumber = parseInt(`${canvas.height / 24}`)    ctx.clearRect(0, 0, canvas.width, canvas.height)    ctx.beginPath()    for (let i = 0; i < rowNumber; i++) {      for (let j = 0; j < colNumber; j++) {        const x = i * 24        const y = j * 24        if (j === 0) {          ctx.moveTo(x, y + 2)          ctx.arc(x + 2, y + 2, 2, Math.PI, Math.PI * 1.5)          ctx.lineTo(x + 22, y)          ctx.arc(x + 22, y + 2, 2, Math.PI * 1.5, Math.PI * 2)          ctx.lineTo(x + 24, y + 22)          ctx.arc(x + 22, y + 22, 2, 0, Math.PI * 0.5)          ctx.lineTo(x + 2, y + 24)          ctx.arc(x + 2, y + 22, 2, Math.PI * 0.5, Math.PI)        }        else {          ctx.moveTo(x + 2, y)          ctx.arc(x + 2, y + 2, 2, Math.PI * 1.5, Math.PI, true)          ctx.lineTo(x, y + 22)          ctx.arc(x + 2, y + 22, 2, Math.PI, Math.PI * 0.5, true)          ctx.lineTo(x + 22, y + 24)          ctx.arc(x + 22, y + 22, 2, Math.PI * 0.5, 0, true)          ctx.lineTo(x + 24, y + 2)          ctx.arc(x + 22, y + 2, 2, 0, Math.PI * 1.5, true)        }      }    }    ctx.stroke()    ctx.closePath()  }, [])  const handleStartDraw = () => {    if (canvasRef.current && ctxRef.current)      drawRecord()  }  useEffect(() => {    initCanvas()    handleStartDraw()  }, [])  return (    <div className={`relative bg-white ${wrapperClassName}`}>      <canvas ref={canvasRef} className={`absolute inset-0 w-full h-full ${canvasClassName}`} />      <div className={`absolute w-full h-full z-[1] bg-gradient-to-b from-white/80 to-white rounded-lg ${gradientClassName}`} />      <div className='relative z-[2]'>{children}</div>    </div>  )}export default GridMask
 |