You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, themeColor = "#00FF41", scanPositionPercent = 65, gridOpacity = 0.15) {
const canvas = document.createElement("canvas");
const w = originalImg.width;
const h = originalImg.height;
canvas.width = w;
canvas.height = h;
const ctx = canvas.getContext("2d");
// Dimensions and dynamic scaling properties
const minDim = Math.min(w, h);
const cx = w / 2;
const cy = h / 2;
const fontSize = Math.max(12, Math.floor(minDim * 0.03));
const margin = fontSize * 1.5;
// 1. Draw base image
ctx.drawImage(originalImg, 0, 0);
// 2. Apply dark vignette and tint to improve HUD contrast
const vignette = ctx.createRadialGradient(cx, cy, minDim * 0.3, cx, cy, Math.max(w, h) * 0.7);
vignette.addColorStop(0, "rgba(0,0,0,0.1)");
vignette.addColorStop(1, "rgba(0,0,0,0.6)");
ctx.fillStyle = vignette;
ctx.fillRect(0, 0, w, h);
ctx.globalAlpha = 0.2;
ctx.fillStyle = themeColor; // Apply slight monochromatic tint
ctx.fillRect(0, 0, w, h);
// 3. Draw grid overlay
ctx.globalAlpha = Number(gridOpacity);
ctx.strokeStyle = themeColor;
ctx.lineWidth = Math.max(1, minDim * 0.002);
const gridSize = minDim * 0.1;
for(let x = 0; x < w; x += gridSize) {
ctx.beginPath(); ctx.moveTo(x, 0); ctx.lineTo(x, h); ctx.stroke();
}
for(let y = 0; y < h; y += gridSize) {
ctx.beginPath(); ctx.moveTo(0, y); ctx.lineTo(w, y); ctx.stroke();
}
// 4. Scanner Line and scanning zone effect
const scanY = h * (Number(scanPositionPercent) / 100);
// Tint the area that has already been "scanned"
ctx.globalAlpha = 0.15;
ctx.fillStyle = themeColor;
ctx.fillRect(0, 0, w, scanY);
// Main scan glow line
ctx.globalAlpha = 0.9;
ctx.shadowColor = themeColor;
ctx.shadowBlur = Math.max(10, minDim * 0.02);
ctx.strokeStyle = themeColor;
ctx.lineWidth = Math.max(3, minDim * 0.008);
ctx.beginPath();
ctx.moveTo(0, scanY);
ctx.lineTo(w, scanY);
ctx.stroke();
// Bright core of the scan line
ctx.globalAlpha = 1.0;
ctx.shadowBlur = 0;
ctx.strokeStyle = "#FFFFFF";
ctx.lineWidth = Math.max(1, minDim * 0.003);
ctx.beginPath();
ctx.moveTo(0, scanY);
ctx.lineTo(w, scanY);
ctx.stroke();
// Reset shadow & styles for UI elements
ctx.shadowBlur = Math.max(4, minDim * 0.008);
ctx.shadowColor = themeColor;
ctx.strokeStyle = themeColor;
ctx.fillStyle = themeColor;
// 5. Biometric Identity / Face Target Box
const boxW = minDim * 0.45;
const boxH = boxW * 1.3;
const bLeft = cx - boxW / 2;
const bRight = cx + boxW / 2;
const bTop = cy - boxH / 2;
const bBottom = cy + boxH / 2;
const len = boxW * 0.15;
ctx.globalAlpha = 0.8;
ctx.lineWidth = Math.max(2, minDim * 0.006);
// Corner brackets
ctx.beginPath(); ctx.moveTo(bLeft, bTop+len); ctx.lineTo(bLeft, bTop); ctx.lineTo(bLeft+len, bTop); ctx.stroke(); // TL
ctx.beginPath(); ctx.moveTo(bRight, bTop+len); ctx.lineTo(bRight, bTop); ctx.lineTo(bRight-len, bTop); ctx.stroke(); // TR
ctx.beginPath(); ctx.moveTo(bLeft, bBottom-len); ctx.lineTo(bLeft, bBottom); ctx.lineTo(bLeft+len, bBottom); ctx.stroke(); // BL
ctx.beginPath(); ctx.moveTo(bRight, bBottom-len); ctx.lineTo(bRight, bBottom); ctx.lineTo(bRight-len, bBottom); ctx.stroke(); // BR
// Central crosshairs
ctx.lineWidth = Math.max(1, minDim * 0.003);
ctx.globalAlpha = 0.5;
const crossR = minDim * 0.05;
ctx.beginPath(); ctx.moveTo(cx - crossR * 1.5, cy); ctx.lineTo(cx + crossR * 1.5, cy); ctx.stroke();
ctx.beginPath(); ctx.moveTo(cx, cy - crossR * 1.5); ctx.lineTo(cx, cy + crossR * 1.5); ctx.stroke();
ctx.beginPath(); ctx.arc(cx, cy, crossR, 0, Math.PI * 2); ctx.stroke();
// 6. Text and Data Overlays (Thematic to Programmer / Computer / Overview / Scanner)
ctx.globalAlpha = 0.9;
ctx.font = `${fontSize}px monospace`;
ctx.textBaseline = "top";
const textsTopLeft = [
"SYS_ID: 948A-NODE",
">> IDENTITY SCANNER: ACTIVE",
">> IMAGE OVERVIEW: IN PROGRESS",
">> UPLINK: PROGRAMMER TERMINAL"
];
textsTopLeft.forEach((txt, i) => ctx.fillText(txt, margin, margin + i * (fontSize * 1.3)));
const textsBottomLeft = [
"STATUS: ANALYZING BIOMETRICS...",
"TITLE: SIMILAR TARGET SEARCH",
"MATCHES FOUND: 0 (PENDING)",
"COMPUTER UPLINK: STABLE"
];
ctx.textBaseline = "bottom";
textsBottomLeft.forEach((txt, i) => ctx.fillText(txt, margin, h - margin - (3 - i) * (fontSize * 1.3)));
// Right side raw data feed
ctx.textAlign = "right";
ctx.textBaseline = "top";
const rightLines = Math.min(Math.floor((h - margin * 2) / (fontSize * 1.3)), 30);
for(let i = 0; i < rightLines; i++) {
let isBinary = Math.random() > 0.6;
let dataStr = "";
if (isBinary) {
for(let j = 0; j < 8; j++) dataStr += Math.random() > 0.5 ? "1" : "0";
} else {
let hex = Math.floor(Math.random() * 16777215).toString(16).toUpperCase().padStart(6, '0');
dataStr = "0x" + hex;
}
ctx.globalAlpha = Math.random() * 0.5 + 0.3; // flickering effect
ctx.fillText(dataStr, w - margin, margin + i * (fontSize * 1.3));
}
// Bracket labels
ctx.textAlign = "left";
ctx.textBaseline = "middle";
ctx.globalAlpha = 0.8;
ctx.fillText("FACIAL_GEO XY", bRight + margin * 0.5, bTop + len);
ctx.fillText("RETINA_SCAN", bRight + margin * 0.5, bBottom - len);
ctx.textAlign = "right";
ctx.fillText(String(Math.floor(Math.random() * 99)) + "%", bLeft - margin * 0.5, bTop + len);
return canvas;
}
Apply Changes