You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, topicText = "UNKNOWN SUBJECT", tvColor = "#6e2929", scanlineIntensity = 0.5) {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = 512;
canvas.height = 512;
// Helper to draw a rounded rectangle
function drawRoundRect(x, y, w, h, r) {
ctx.beginPath();
ctx.moveTo(x + r, y);
ctx.lineTo(x + w - r, y);
ctx.quadraticCurveTo(x + w, y, x + w, y + r);
ctx.lineTo(x + w, y + h - r);
ctx.quadraticCurveTo(x + w, y + h, x + w - r, y + h);
ctx.lineTo(x + r, y + h);
ctx.quadraticCurveTo(x, y + h, x, y + h - r);
ctx.lineTo(x, y + r);
ctx.quadraticCurveTo(x, y, x + r, y);
ctx.closePath();
}
// Helper to draw a TV dial
function drawDial(x, y, radius, angleOff) {
// Outer ring shadow/rim
ctx.fillStyle = '#111';
ctx.beginPath();
ctx.arc(x, y, radius + 4, 0, Math.PI * 2);
ctx.fill();
// Inner knob
ctx.fillStyle = '#ccc';
ctx.beginPath();
ctx.arc(x, y, radius, 0, Math.PI * 2);
ctx.fill();
// Knob indicator line
ctx.strokeStyle = '#333';
ctx.lineWidth = 4;
ctx.lineCap = 'round';
ctx.beginPath();
ctx.moveTo(x, y);
const angle = Math.PI * angleOff;
ctx.lineTo(x + Math.cos(angle) * (radius - 4), y + Math.sin(angle) * (radius - 4));
ctx.stroke();
}
// 1. Clear background (Transparent for icon format)
ctx.clearRect(0, 0, canvas.width, canvas.height);
// 2. Draw Antennae
ctx.lineWidth = 6;
ctx.strokeStyle = '#999';
ctx.lineCap = 'round';
// Left Antenna
ctx.beginPath();
ctx.moveTo(230, 80);
ctx.lineTo(120, 20);
ctx.stroke();
// Right Antenna
ctx.beginPath();
ctx.moveTo(282, 80);
ctx.lineTo(392, 20);
ctx.stroke();
// Antenna Balls
ctx.fillStyle = '#ccc';
ctx.beginPath();
ctx.arc(120, 20, 8, 0, Math.PI * 2);
ctx.fill();
ctx.beginPath();
ctx.arc(392, 20, 8, 0, Math.PI * 2);
ctx.fill();
// 3. Draw TV Outer Body
ctx.shadowColor = 'rgba(0,0,0,0.6)';
ctx.shadowBlur = 15;
ctx.shadowOffsetY = 10;
ctx.fillStyle = tvColor;
drawRoundRect(32, 80, 448, 360, 32);
ctx.fill();
// Reset shadow
ctx.shadowColor = 'transparent';
ctx.shadowBlur = 0;
ctx.shadowOffsetY = 0;
// 4. TV Screen Rim/Bezel
ctx.fillStyle = '#1a1a1a';
drawRoundRect(48, 96, 336, 328, 16);
ctx.fill();
// 5. Drawing the Screen Content
ctx.save();
drawRoundRect(56, 104, 320, 312, 12);
ctx.clip(); // Mask everything inside the screen
// Calculate scale to fill screen
const sc = Math.max(320 / originalImg.width, 312 / originalImg.height);
const imgW = originalImg.width * sc;
const imgH = originalImg.height * sc;
const dx = 56 + (320 - imgW) / 2;
const dy = 104 + (312 - imgH) / 2;
// Draw original image
ctx.drawImage(originalImg, dx, dy, imgW, imgH);
// Apply CRT Color Tint
ctx.fillStyle = 'rgba(0, 30, 10, 0.2)';
ctx.fillRect(56, 104, 320, 312);
// Apply Scanlines
let intensity = parseFloat(scanlineIntensity);
if (isNaN(intensity)) intensity = 0.5;
ctx.fillStyle = `rgba(0, 0, 0, ${intensity})`;
for(let i = 104; i < 416; i += 4) {
ctx.fillRect(56, i, 320, 2);
}
// Overlay: Search Topic Identifier Tool Graphics
// Crosshair/Bounding Box
ctx.strokeStyle = 'rgba(0, 255, 0, 0.8)';
ctx.lineWidth = 3;
const cx = 56 + 160;
const cy = 104 + 156;
const size = 110;
const len = 20;
// Draw Corner Brackets
const tr = {x: cx + size, y: cy - size};
const tl = {x: cx - size, y: cy - size};
const br = {x: cx + size, y: cy + size};
const bl = {x: cx - size, y: cy + size};
ctx.beginPath();
ctx.moveTo(tl.x, tl.y + len); ctx.lineTo(tl.x, tl.y); ctx.lineTo(tl.x + len, tl.y); // Top-left
ctx.moveTo(tr.x - len, tr.y); ctx.lineTo(tr.x, tr.y); ctx.lineTo(tr.x, tr.y + len); // Top-right
ctx.moveTo(bl.x, bl.y - len); ctx.lineTo(bl.x, bl.y); ctx.lineTo(bl.x + len, bl.y); // Bottom-left
ctx.moveTo(br.x - len, br.y); ctx.lineTo(br.x, br.y); ctx.lineTo(br.x, br.y - len); // Bottom-right
ctx.stroke();
// Center Crosshair
ctx.beginPath();
ctx.moveTo(cx - 10, cy); ctx.lineTo(cx + 10, cy);
ctx.moveTo(cx, cy - 10); ctx.lineTo(cx, cy + 10);
ctx.stroke();
// Text Overlays
ctx.fillStyle = '#0f0';
ctx.font = 'bold 16px monospace';
ctx.fillText("TARGET IDENTIFIED", cx - size, cy - size - 10);
ctx.font = '14px monospace';
ctx.fillText(`TOPIC: ${topicText}`, cx - size, cy + size + 20, size * 2);
// Recording/Scanning Indication
ctx.fillStyle = '#f00';
ctx.beginPath();
ctx.arc(76, 124, 6, 0, Math.PI * 2);
ctx.fill();
ctx.fillStyle = '#fff';
ctx.font = '12px monospace';
ctx.fillText("SCANNING...", 88, 128);
// Screen Glare Reflection
ctx.fillStyle = 'rgba(255, 255, 255, 0.07)';
ctx.beginPath();
ctx.moveTo(56, 104);
ctx.lineTo(250, 104);
ctx.lineTo(80, 416);
ctx.lineTo(56, 416);
ctx.fill();
ctx.restore(); // End clipping region
// 6. Right Side TV Control Panel
ctx.fillStyle = '#2b2b2b';
drawRoundRect(400, 96, 64, 328, 8);
ctx.fill();
// Control Dials
drawDial(432, 140, 20, -0.2);
drawDial(432, 210, 20, 0.6);
// Speaker Holes
ctx.fillStyle = '#111';
for(let r = 0; r < 6; r++) {
for(let c = 0; c < 3; c++) {
ctx.beginPath();
ctx.arc(416 + c * 16, 280 + r * 16, 3, 0, Math.PI * 2);
ctx.fill();
}
}
// Branding / Badge Text
ctx.fillStyle = '#aaa';
ctx.font = 'bold 11px sans-serif';
ctx.textAlign = 'center';
ctx.fillText("IDENTIFIER", 432, 395);
ctx.fillStyle = '#777';
ctx.fillText("TOOL MK-I", 432, 410);
return canvas;
}
Apply Changes