mirror of
				https://github.com/langgenius/dify.git
				synced 2025-10-31 10:53:02 +00:00 
			
		
		
		
	
		
			
	
	
		
			94 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
		
		
			
		
	
	
			94 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
|   | 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 |