Implementing Custom Captcha Generation with HTML Canvas
HTML structure for the captcha input and canvas element:
html
CSS styling for layout and visual presentation:
css .captcha-wrapper { display: flex; align-items: center; gap: 10px; }
.captcha-field { flex: 1; padding: 8px 12px; border: 1px solid #ccc; border-radius: 4px; font-size: 16px; }
#verification-canvas { border: 1px solid #ddd; border-radius: 4px; cursor: pointer; }
JavaScript logic for rendering randomized characters and noise on the canvas:
javascript const CHAR_POOL = 'ABCDEFGHJKMNPQRSTWXYZ23456789'.split(''); const CAPTCHA_LENGTH = 4;
functon generateCaptcha(captchaHolder) { const canvasEl = document.getElementById('verification-canvas'); const ctx = canvasEl.getContext('2d'); const width = canvasEl.width; const height = canvasEl.height;
ctx.clearRect(0, 0, width, height); captchaHolder.length = 0;
for (let i = 0; i < CAPTCHA_LENGTH; i++) { const char = CHAR_POOL[Math.floor(Math.random() * CHAR_POOL.length)]; captchaHolder.push(char.toLowerCase());
ctx.save();
const xPos = 15 + i * 25;
const yPos = 25 + Math.random() * 10;
const rotation = (Math.random() - 0.5) * 0.6;
ctx.translate(xPos, yPos);
ctx.rotate(rotation);
ctx.font = 'bold 24px Arial';
ctx.fillStyle = getRandomRgb();
ctx.fillText(char, 0, 0);
ctx.restore();
}
for (let i = 0; i < 6; i++) { ctx.beginPath(); ctx.strokeStyle = getRandomRgb(); ctx.moveTo(Math.random() * width, Math.random() * height); ctx.lineTo(Math.random() * width, Math.random() * height); ctx.stroke(); }
for (let i = 0; i < 40; i++) { ctx.beginPath(); ctx.fillStyle = getRandomRgb(); const dotX = Math.random() * width; const dotY = Math.random() * height; ctx.arc(dotX, dotY, 1, 0, 2 * Math.PI); ctx.fill(); } }
functon getRandomRgb() {
const r = Math.floor(Math.random() * 256);
const g = Math.floor(Math.random() * 256);
const b = Math.floor(Math.random() * 256);
return rgb(${r}, ${g}, ${b});
}