fix: remove DPR scaling from CaptchaCanvas to fix zoomed-in appearance
- Fixed canvas dimensions to 176x52 pixels (no DPR scaling) - All drawing operations now use fixed pixel values - Prevents captcha from appearing zoomed in on high-DPI displays - Characters, lines, and circles are now properly positioned within bounds
This commit is contained in:
parent
d8467d1aeb
commit
4c61bcaf31
1 changed files with 16 additions and 17 deletions
|
|
@ -21,53 +21,52 @@ export default function CaptchaCanvas(props: CaptchaCanvasProps) {
|
|||
|
||||
const width = 176;
|
||||
const height = 52;
|
||||
const dpr = typeof window !== 'undefined' ? Math.max(1, window.devicePixelRatio || 1) : 1;
|
||||
|
||||
// Set canvas resolution first (before any drawing)
|
||||
canvas.width = Math.floor(width * dpr);
|
||||
canvas.height = Math.floor(height * dpr);
|
||||
// Set canvas resolution (fixed at 1x to prevent zoom issues)
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
canvas.style.width = `${width}px`;
|
||||
canvas.style.height = `${height}px`;
|
||||
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
|
||||
ctx.setTransform(1, 0, 0, 1, 0, 0);
|
||||
|
||||
// Clear and fill background
|
||||
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
||||
ctx.clearRect(0, 0, width, height);
|
||||
ctx.fillStyle = '#ffffff';
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||
ctx.fillRect(0, 0, width, height);
|
||||
|
||||
// Draw decorative lines
|
||||
// Draw decorative lines (within bounds)
|
||||
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() * canvas.width, Math.random() * canvas.height);
|
||||
ctx.lineTo(Math.random() * canvas.width, Math.random() * canvas.height);
|
||||
ctx.moveTo(Math.random() * width, Math.random() * height);
|
||||
ctx.lineTo(Math.random() * width, Math.random() * height);
|
||||
ctx.stroke();
|
||||
}
|
||||
|
||||
// Draw decorative circles
|
||||
// Draw decorative circles (within bounds)
|
||||
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() * canvas.width, Math.random() * canvas.height, Math.random() * 1.8 + 0.6, 0, Math.PI * 2);
|
||||
ctx.arc(Math.random() * width, Math.random() * height, Math.random() * 1.8 + 0.6, 0, Math.PI * 2);
|
||||
ctx.fill();
|
||||
}
|
||||
|
||||
// Draw characters
|
||||
// Draw characters (fixed positioning)
|
||||
const chars = String(props.code || '').slice(0, 6).split('');
|
||||
const startX = 16 * dpr;
|
||||
const charGap = 24 * dpr;
|
||||
const startX = 16;
|
||||
const charGap = 24;
|
||||
|
||||
chars.forEach((char, index) => {
|
||||
const x = startX + index * charGap;
|
||||
const y = canvas.height / 2;
|
||||
const y = height / 2;
|
||||
const rotation = 0;
|
||||
|
||||
ctx.save();
|
||||
ctx.translate(x, y);
|
||||
ctx.rotate(rotation);
|
||||
ctx.textBaseline = 'middle';
|
||||
ctx.font = `800 ${22 * dpr}px "Courier New", monospace`;
|
||||
ctx.font = `800 22px "Courier New", monospace`;
|
||||
ctx.fillStyle = index % 2 === 0 ? '#0f172a' : '#c2410c';
|
||||
ctx.lineWidth = 0;
|
||||
ctx.fillText(char, 0, 0);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue