import { createEffect } from 'solid-js'; type CaptchaCanvasProps = { code: string; class?: string; }; export default function CaptchaCanvas(props: CaptchaCanvasProps) { let canvasRef: HTMLCanvasElement | undefined; createEffect(() => { const canvas = canvasRef; if (!canvas) return; const ctx = canvas.getContext('2d'); if (!ctx) return; const width = 176; const height = 52; const dpr = typeof window !== 'undefined' ? Math.max(1, window.devicePixelRatio || 1) : 1; canvas.style.width = `${width}px`; canvas.style.height = `${height}px`; canvas.width = Math.floor(width * dpr); canvas.height = Math.floor(height * dpr); ctx.setTransform(dpr, 0, 0, dpr, 0, 0); // Clear and fill background ctx.clearRect(0, 0, width, height); ctx.fillStyle = '#ffffff'; ctx.fillRect(0, 0, width, height); // Draw decorative lines for (let i = 0; i < 2; i += 1) { ctx.strokeStyle = i % 2 === 0 ? 'rgba(253,98,22,0.16)' : 'rgba(27,36,64,0.14)'; ctx.lineWidth = 1; ctx.beginPath(); ctx.moveTo(Math.random() * width, Math.random() * height); ctx.lineTo(Math.random() * width, Math.random() * height); ctx.stroke(); } // Draw decorative circles for (let i = 0; i < 3; i += 1) { ctx.fillStyle = i % 2 === 0 ? 'rgba(253,98,22,0.10)' : 'rgba(27,36,64,0.09)'; ctx.beginPath(); ctx.arc(Math.random() * width, Math.random() * height, Math.random() * 1.8 + 0.6, 0, Math.PI * 2); ctx.fill(); } // Draw characters const chars = String(props.code || '').slice(0, 6).split(''); const startX = 16; const charGap = 24; chars.forEach((char, index) => { const x = startX + index * charGap; const y = height / 2 + 1; const rotation = 0; ctx.save(); ctx.translate(x, y); ctx.rotate(rotation); ctx.textBaseline = 'middle'; ctx.font = '800 22px "Courier New", monospace'; ctx.fillStyle = index % 2 === 0 ? '#0f172a' : '#c2410c'; ctx.lineWidth = 0; ctx.fillText(char, 0, 0); ctx.restore(); }); }); return ( event.preventDefault()} class={props.class} /> ); }