UNPKG

kwikid-components-react

Version:

KwikID's Component Library in React

530 lines (482 loc) 18.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getCaptchaLetterSpacing = exports.generateCaptchaText = exports.drawStandardCaptcha = exports.drawSimplifiedCaptcha = exports.drawNoisyCaptcha = exports.drawDistortedCaptcha = exports.drawCaptchaOnCanvas = void 0; var _Captcha = require("./Captcha.definition"); const generateRandomChar = (min, max) => String.fromCharCode(Math.floor(Math.random() * (max - min + 1) + min)); const generateCaptchaText = characterSize => { let captcha = ""; for (let i = 0; i < characterSize; i++) { const charGenerators = [() => generateRandomChar(65, 90), // Uppercase letters () => generateRandomChar(97, 122), // Lowercase letters () => generateRandomChar(48, 57) // Numbers ]; const randomIndex = Math.floor(Math.random() * charGenerators.length); captcha += charGenerators[randomIndex](); } return captcha.split("").sort(() => Math.random() - 0.5).join(""); }; /** * Draw simplified captcha - basic text rendering */ exports.generateCaptchaText = generateCaptchaText; const drawSimplifiedCaptcha = (ctx, captcha, size) => { let xInitialSpacing; let characterYSpacing; let canvasWidth; let canvasHeight; switch (size) { case _Captcha.IKwikUICaptchaSize.S: canvasWidth = 120; canvasHeight = 30; xInitialSpacing = 10; characterYSpacing = canvasHeight - 5; break; case _Captcha.IKwikUICaptchaSize.L: canvasWidth = 300; canvasHeight = 75; xInitialSpacing = 20; characterYSpacing = canvasHeight - 20; break; default: canvasWidth = 200; canvasHeight = 50; xInitialSpacing = 15; characterYSpacing = canvasHeight - 10; break; } // Set canvas dimensions ctx.canvas.width = canvasWidth; ctx.canvas.height = canvasHeight; ctx.clearRect(0, 0, canvasWidth, canvasHeight); const fontSize = Math.min(canvasWidth / (captcha.length + 1), canvasHeight * 0.6); const textColors = ["rgb(0, 0, 0)", "rgb(80, 80, 80)", "rgb(160, 160, 160)"]; ctx.font = "".concat(fontSize, "px Manrope Mono"); for (let i = 0; i < captcha.length; i++) { ctx.fillStyle = textColors[Math.floor(Math.random() * textColors.length)]; ctx.fillText(captcha[i], xInitialSpacing + i * fontSize, characterYSpacing, fontSize); } }; /** * Draw standard captcha - with light background and slight character rotation */ exports.drawSimplifiedCaptcha = drawSimplifiedCaptcha; const drawStandardCaptcha = (ctx, captcha, size) => { let xInitialSpacing; let characterYSpacing; let canvasWidth; let canvasHeight; switch (size) { case _Captcha.IKwikUICaptchaSize.S: canvasWidth = 120; canvasHeight = 30; xInitialSpacing = 10; characterYSpacing = canvasHeight - 5; break; case _Captcha.IKwikUICaptchaSize.L: canvasWidth = 300; canvasHeight = 75; xInitialSpacing = 20; characterYSpacing = canvasHeight - 20; break; default: canvasWidth = 200; canvasHeight = 50; xInitialSpacing = 15; characterYSpacing = canvasHeight - 10; break; } // Set canvas dimensions ctx.canvas.width = canvasWidth; ctx.canvas.height = canvasHeight; ctx.clearRect(0, 0, canvasWidth, canvasHeight); // Fill background with complex gradient const gradient = ctx.createRadialGradient(canvasWidth / 2, canvasHeight / 2, 5, canvasWidth / 2, canvasHeight / 2, canvasWidth / 1.5); gradient.addColorStop(0, 'rgb(245, 245, 245)'); gradient.addColorStop(0.5, 'rgb(235, 235, 235)'); gradient.addColorStop(1, 'rgb(225, 225, 225)'); ctx.fillStyle = gradient; ctx.fillRect(0, 0, canvasWidth, canvasHeight); // Add varied pattern background for (let i = 0; i < canvasWidth; i += 3) { for (let j = 0; j < canvasHeight; j += 3) { if (Math.random() > 0.75) { const grayValue = Math.floor(Math.random() * 30) + 200; const opacity = 0.1 + Math.random() * 0.4; ctx.fillStyle = "rgba(".concat(grayValue, ", ").concat(grayValue, ", ").concat(grayValue, ", ").concat(opacity, ")"); ctx.fillRect(i, j, Math.random() * 2 + 1, Math.random() * 2 + 1); } } } // Add noise pattern overlays for (let i = 0; i < 300; i++) { const x = Math.random() * canvasWidth; const y = Math.random() * canvasHeight; const size = Math.random() * 1.5; const opacity = 0.05 + Math.random() * 0.15; const grayValue = Math.floor(Math.random() * 100) + 100; ctx.beginPath(); ctx.fillStyle = "rgba(".concat(grayValue, ", ").concat(grayValue, ", ").concat(grayValue, ", ").concat(opacity, ")"); if (Math.random() > 0.5) { ctx.arc(x, y, size, 0, Math.PI * 2); } else { ctx.rect(x, y, size, size); } ctx.fill(); } // Add curved intersecting lines for (let i = 0; i < 10; i++) { ctx.beginPath(); const startX = Math.random() * canvasWidth; const startY = Math.random() * canvasHeight; const cp1x = Math.random() * canvasWidth; const cp1y = Math.random() * canvasHeight; const cp2x = Math.random() * canvasWidth; const cp2y = Math.random() * canvasHeight; const endX = Math.random() * canvasWidth; const endY = Math.random() * canvasHeight; ctx.moveTo(startX, startY); ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, endX, endY); const grayValue = Math.floor(Math.random() * 70) + 170; const opacity = 0.1 + Math.random() * 0.2; ctx.strokeStyle = "rgba(".concat(grayValue, ", ").concat(grayValue, ", ").concat(grayValue, ", ").concat(opacity, ")"); ctx.lineWidth = 0.5 + Math.random() * 0.5; ctx.stroke(); } // Add background grid patterns for (let i = 0; i < canvasWidth; i += 10) { ctx.beginPath(); ctx.moveTo(i, 0); ctx.lineTo(i, canvasHeight); const opacity = 0.02 + Math.random() * 0.05; ctx.strokeStyle = "rgba(100, 100, 100, ".concat(opacity, ")"); ctx.lineWidth = 0.5; ctx.stroke(); } for (let i = 0; i < canvasHeight; i += 10) { ctx.beginPath(); ctx.moveTo(0, i); ctx.lineTo(canvasWidth, i); const opacity = 0.02 + Math.random() * 0.05; ctx.strokeStyle = "rgba(100, 100, 100, ".concat(opacity, ")"); ctx.lineWidth = 0.5; ctx.stroke(); } const fontSize = Math.min(canvasWidth / (captcha.length + 1), canvasHeight * 0.6); // Grayscale text colors with varying intensities and opacity const textColors = ["rgba(20, 20, 20, 0.9)", // Near black, slight transparency "rgba(40, 40, 40, 0.85)", // Very dark gray with transparency "rgba(60, 60, 60, 0.95)", // Dark gray, more opaque "rgba(0, 0, 0, 0.8)" // Black with transparency ]; // Font variations const fontVariations = ["".concat(fontSize, "px Manrope Mono"), "bold ".concat(fontSize, "px Manrope Mono"), "italic ".concat(fontSize, "px Manrope Mono"), "".concat(fontSize - 1, "px Manrope Mono")]; // Calculate total width of text to center it const totalTextWidth = fontSize * captcha.length; const startX = (canvasWidth - totalTextWidth) / 2; // Draw slight shadow versions of the text first for (let i = 0; i < captcha.length; i++) { ctx.save(); const charX = startX + i * fontSize; ctx.translate(charX, characterYSpacing); const shadowOpacity = 0.1 + Math.random() * 0.2; ctx.fillStyle = "rgba(150, 150, 150, ".concat(shadowOpacity, ")"); ctx.font = fontVariations[Math.floor(Math.random() * fontVariations.length)]; // Offset shadow const shadowOffsetX = (Math.random() - 0.5) * 3; const shadowOffsetY = (Math.random() - 0.5) * 3; ctx.fillText(captcha[i], shadowOffsetX, shadowOffsetY, fontSize); ctx.restore(); } // Draw main text characters with variations for (let i = 0; i < captcha.length; i++) { ctx.save(); const charX = startX + i * fontSize; ctx.translate(charX, characterYSpacing); // More pronounced rotation const rotation = (Math.random() - 0.5) * 0.25; ctx.rotate(rotation); // Add shadow for depth ctx.shadowColor = 'rgba(0, 0, 0, 0.2)'; ctx.shadowBlur = 1 + Math.random() * 2; ctx.shadowOffsetX = 0.5 + Math.random() * 1; ctx.shadowOffsetY = 0.5 + Math.random() * 1; ctx.fillStyle = textColors[Math.floor(Math.random() * textColors.length)]; // Random font for each character ctx.font = fontVariations[Math.floor(Math.random() * fontVariations.length)]; // Varied character distortion const scaleX = 0.85 + Math.random() * 0.3; const scaleY = 0.85 + Math.random() * 0.3; ctx.scale(scaleX, scaleY); // Apply skew for more distortion const skewX = (Math.random() - 0.5) * 0.4; const skewY = (Math.random() - 0.5) * 0.2; ctx.transform(1, skewY, skewX, 1, 0, 0); // Draw the character ctx.fillText(captcha[i], 0, 0, fontSize); // Sometimes draw a second time with slight offset for bold effect if (Math.random() > 0.6) { ctx.fillText(captcha[i], 0.5, 0.5, fontSize); } ctx.restore(); } // Add a few overlapping elements on top for (let i = 0; i < 5; i++) { ctx.beginPath(); const startX = Math.random() * canvasWidth; const startY = Math.random() * canvasHeight; const endX = startX + (Math.random() - 0.5) * 80; const endY = startY + (Math.random() - 0.5) * 30; ctx.moveTo(startX, startY); ctx.lineTo(endX, endY); const opacity = 0.05 + Math.random() * 0.15; ctx.strokeStyle = "rgba(50, 50, 50, ".concat(opacity, ")"); ctx.lineWidth = 0.5 + Math.random() * 1; ctx.stroke(); } }; /** * Draw noisy captcha - with background noise and lines */ exports.drawStandardCaptcha = drawStandardCaptcha; const drawNoisyCaptcha = (ctx, captcha, size) => { let xInitialSpacing; let characterYSpacing; let canvasWidth; let canvasHeight; switch (size) { case _Captcha.IKwikUICaptchaSize.S: canvasWidth = 120; canvasHeight = 30; xInitialSpacing = 10; characterYSpacing = canvasHeight - 5; break; case _Captcha.IKwikUICaptchaSize.L: canvasWidth = 300; canvasHeight = 75; xInitialSpacing = 20; characterYSpacing = canvasHeight - 20; break; default: canvasWidth = 200; canvasHeight = 50; xInitialSpacing = 15; characterYSpacing = canvasHeight - 10; break; } // Set canvas dimensions ctx.canvas.width = canvasWidth; ctx.canvas.height = canvasHeight; ctx.clearRect(0, 0, canvasWidth, canvasHeight); // Fill background with light gray ctx.fillStyle = 'rgb(240, 240, 240)'; ctx.fillRect(0, 0, canvasWidth, canvasHeight); // Add grayscale noise patterns (lighter gray) for (let i = 0; i < 600; i++) { const grayValue = Math.floor(Math.random() * 100) + 150; // Light to medium gray ctx.fillStyle = "rgb(".concat(grayValue, ", ").concat(grayValue, ", ").concat(grayValue, ")"); ctx.fillRect(Math.random() * canvasWidth, Math.random() * canvasHeight, Math.random() * 2, Math.random() * 2); } // Add many black/dark dots to confuse OCR for (let i = 0; i < 1000; i++) { const size = Math.random() * 1.5; const x = Math.random() * canvasWidth; const y = Math.random() * canvasHeight; // Vary the darkness of dots to create more noise const darkness = Math.floor(Math.random() * 50); ctx.fillStyle = "rgb(".concat(darkness, ", ").concat(darkness, ", ").concat(darkness, ")"); // Use different shapes for dots to increase complexity if (Math.random() > 0.7) { // Circular dots ctx.beginPath(); ctx.arc(x, y, size, 0, Math.PI * 2); ctx.fill(); } else { // Square dots ctx.fillRect(x, y, size, size); } } const fontSize = Math.min(canvasWidth / (captcha.length + 1), canvasHeight * 0.6); const textColors = ["rgb(0, 0, 0)", // Black "rgb(20, 20, 20)", // Near black "rgb(40, 40, 40)", // Very dark gray "rgb(60, 60, 60)" // Dark gray ]; ctx.font = "bold ".concat(fontSize, "px Manrope Mono"); // Calculate total width to center text const totalTextWidth = fontSize * captcha.length; const startX = (canvasWidth - totalTextWidth) / 2; // Draw text with bold effect to stand out from noise for (let i = 0; i < captcha.length; i++) { ctx.save(); const charX = startX + i * fontSize; ctx.translate(charX, characterYSpacing); // Medium rotation for each character const rotation = (Math.random() - 0.5) * 0.2; ctx.rotate(rotation); // Add slight shadow for better visibility against noise ctx.shadowColor = 'rgba(255, 255, 255, 0.5)'; ctx.shadowBlur = 2; ctx.shadowOffsetX = 0; ctx.shadowOffsetY = 0; ctx.fillStyle = textColors[Math.floor(Math.random() * textColors.length)]; // Draw character with offset for bold effect ctx.fillText(captcha[i], 0, 0, fontSize); ctx.fillText(captcha[i], 0.5, 0.5, fontSize); ctx.restore(); } // Add random crossing lines for (let i = 0; i < 8; i++) { ctx.beginPath(); const startX = Math.random() * canvasWidth; const startY = Math.random() * canvasHeight; const endX = startX + (Math.random() - 0.5) * 80; const endY = startY + (Math.random() - 0.5) * 80; ctx.moveTo(startX, startY); ctx.lineTo(endX, endY); const grayValue = Math.floor(Math.random() * 80) + 20; // Dark to very dark gray ctx.strokeStyle = "rgb(".concat(grayValue, ", ").concat(grayValue, ", ").concat(grayValue, ")"); ctx.lineWidth = Math.random() * 1 + 0.5; ctx.stroke(); } }; /** * Draw distorted captcha - with wave effects and transform distortions */ exports.drawNoisyCaptcha = drawNoisyCaptcha; const drawDistortedCaptcha = (ctx, captcha, size) => { let xInitialSpacing; let characterYSpacing; let canvasWidth; let canvasHeight; switch (size) { case _Captcha.IKwikUICaptchaSize.S: canvasWidth = 120; canvasHeight = 30; xInitialSpacing = 10; characterYSpacing = canvasHeight - 5; break; case _Captcha.IKwikUICaptchaSize.L: canvasWidth = 300; canvasHeight = 75; xInitialSpacing = 20; characterYSpacing = canvasHeight - 20; break; default: canvasWidth = 200; canvasHeight = 50; xInitialSpacing = 15; characterYSpacing = canvasHeight - 10; break; } // Set canvas dimensions ctx.canvas.width = canvasWidth; ctx.canvas.height = canvasHeight; ctx.clearRect(0, 0, canvasWidth, canvasHeight); // Fill background with light gray ctx.fillStyle = 'rgb(240, 240, 240)'; ctx.fillRect(0, 0, canvasWidth, canvasHeight); // Add grayscale noise patterns for (let i = 0; i < 100; i++) { const grayValue = Math.floor(Math.random() * 100) + 150; ctx.fillStyle = "rgb(".concat(grayValue, ", ").concat(grayValue, ", ").concat(grayValue, ")"); ctx.fillRect(Math.random() * canvasWidth, Math.random() * canvasHeight, Math.random() * 2, Math.random() * 2); } const fontSize = Math.min(canvasWidth / (captcha.length + 1), canvasHeight * 0.6); const textColors = ["rgb(0, 0, 0)", // Black "rgb(40, 40, 40)", // Very dark gray "rgb(80, 80, 80)", // Dark gray "rgb(120, 120, 120)", // Medium gray "rgb(160, 160, 160)" // Light gray ]; ctx.font = "".concat(fontSize, "px Manrope Mono"); // Calculate total width to center text const totalTextWidth = fontSize * captcha.length; const startX = (canvasWidth - totalTextWidth) / 2; for (let i = 0; i < captcha.length; i++) { ctx.save(); const charX = startX + i * fontSize; ctx.translate(charX, characterYSpacing); // Strong rotation for each character const rotation = (Math.random() - 0.5) * 0.3; ctx.rotate(rotation); // Add shadow for depth ctx.shadowColor = 'rgba(0, 0, 0, 0.2)'; ctx.shadowBlur = 1; ctx.shadowOffsetX = 1; ctx.shadowOffsetY = 1; ctx.fillStyle = textColors[Math.floor(Math.random() * textColors.length)]; // Add distortion const distortion = (Math.random() - 0.5) * 2; ctx.transform(1, distortion, 0, 1, 0, 0); // Draw character with slight offset for bold effect ctx.fillText(captcha[i], 0, 0, fontSize); ctx.fillText(captcha[i], 1, 1, fontSize); ctx.restore(); } // Add wave distortion for (let i = 0; i < canvasHeight; i += 2) { const wave = Math.sin(i / 10) * 2; ctx.beginPath(); ctx.moveTo(0, i); ctx.lineTo(canvasWidth, i); ctx.strokeStyle = "rgba(0, 0, 0, ".concat(Math.random() * 0.1, ")"); ctx.lineWidth = 1; ctx.stroke(); } // Add crossing lines for (let i = 0; i < 5; i++) { ctx.beginPath(); const startX = Math.random() * canvasWidth; const startY = Math.random() * canvasHeight; const endX = startX + (Math.random() - 0.5) * 70; const endY = startY + (Math.random() - 0.5) * 70; ctx.moveTo(startX, startY); ctx.lineTo(endX, endY); const grayValue = Math.floor(Math.random() * 100) + 100; ctx.strokeStyle = "rgb(".concat(grayValue, ", ").concat(grayValue, ", ").concat(grayValue, ")"); ctx.lineWidth = Math.random() * 1.5; ctx.stroke(); } }; /** * Draw captcha on canvas based on variant */ exports.drawDistortedCaptcha = drawDistortedCaptcha; const drawCaptchaOnCanvas = function (ctx, captcha, size) { let variant = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : _Captcha.IKwikUICaptchaVariant.SIMPLIFIED; if (!ctx) return; switch (variant) { case _Captcha.IKwikUICaptchaVariant.SIMPLIFIED: drawSimplifiedCaptcha(ctx, captcha, size); break; case _Captcha.IKwikUICaptchaVariant.STANDARD: drawStandardCaptcha(ctx, captcha, size); break; case _Captcha.IKwikUICaptchaVariant.NOISY: drawNoisyCaptcha(ctx, captcha, size); break; case _Captcha.IKwikUICaptchaVariant.DISTORTED: drawDistortedCaptcha(ctx, captcha, size); break; default: drawSimplifiedCaptcha(ctx, captcha, size); break; } }; exports.drawCaptchaOnCanvas = drawCaptchaOnCanvas; const getCaptchaLetterSpacing = value => getComputedStyle(document.documentElement).getPropertyValue(value); exports.getCaptchaLetterSpacing = getCaptchaLetterSpacing;