Spaces:
Build error
Build error
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 | |