mirror of
				https://github.com/langgenius/dify.git
				synced 2025-10-31 02:42:59 +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
 | 
