You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, title = "ДЕЛО ОБОРОТНЯ", stampText = "СОВЕРШЕННО СЕКРЕТНО", paperColor = "#e6daba", details = "ИМЯ: НЕИЗВЕСТНО\nСУЩНОСТЬ: ОБОРОТЕНЬ\nСТАТУС: КРАЙНЕ ОПАСЕН\nОСОБЫЕ ПРИМЕТЫ: СМЕНА ОБЛИКА\nГРИФ СЕКРЕТНОСТИ: ВЫСШИЙ") {
// Determine canvas dimensions based on a standard A4 proportion for a dossier/case file
const canvas = document.createElement("canvas");
const w = 800;
const h = 1130;
canvas.width = w;
canvas.height = h;
const ctx = canvas.getContext("2d");
// 1. Draw old paper background
ctx.fillStyle = paperColor;
ctx.fillRect(0, 0, w, h);
// Add vintage paper texture (noise)
ctx.fillStyle = "rgba(0,0,0,0.04)";
for (let i = 0; i < w; i += 3) {
for (let j = 0; j < h; j += 3) {
if (Math.random() > 0.6) {
ctx.fillRect(i, j, 2, 2);
}
}
}
// Add vignette effect for the aged look
const gradient = ctx.createRadialGradient(w/2, h/2, h/4, w/2, h/2, h);
gradient.addColorStop(0, "rgba(0,0,0,0)");
gradient.addColorStop(1, "rgba(0,0,0,0.5)");
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, w, h);
// 2. Draw Dossier Titles
ctx.fillStyle = "#111";
ctx.font = 'bold 50px "Courier New", Courier, monospace';
ctx.textAlign = "center";
ctx.fillText("СЕКРЕТНЫЙ АРХИВ", w/2, 90);
ctx.font = 'bold 75px "Courier New", Courier, monospace';
ctx.fillText(title, w/2, 170);
// Decorative line separator
ctx.beginPath();
ctx.moveTo(100, 200);
ctx.lineTo(w - 100, 200);
ctx.lineWidth = 4;
ctx.strokeStyle = "#111";
ctx.stroke();
// 3. Draw Suspect Photo (Attached Polaroid style)
const maxImgW = 450;
const maxImgH = 450;
const scale = Math.min(maxImgW / originalImg.width, maxImgH / originalImg.height);
const imgW = originalImg.width * scale;
const imgH = originalImg.height * scale;
const imgX = (w - imgW) / 2;
const imgY = 250;
const pad = 18;
ctx.save();
// Slightly rotate the photo to look organically placed
const rotationAngle = -2 * Math.PI / 180;
ctx.translate(w/2, imgY + imgH/2);
ctx.rotate(rotationAngle);
ctx.translate(-w/2, -(imgY + imgH/2));
// Photo shadow and border
ctx.shadowColor = "rgba(0, 0, 0, 0.7)";
ctx.shadowBlur = 15;
ctx.shadowOffsetX = 6;
ctx.shadowOffsetY = 6;
ctx.fillStyle = "#f5f5f5";
ctx.fillRect(imgX - pad, imgY - pad, imgW + 2 * pad, imgH + pad + 50); // Extra space at bottom
// Clear shadow for image drawing
ctx.shadowColor = "transparent";
// Apply old photo filter (grayscale + sepia + contrast)
ctx.filter = "grayscale(100%) sepia(50%) contrast(1.5) brightness(0.9)";
ctx.drawImage(originalImg, imgX, imgY, imgW, imgH);
ctx.filter = "none";
// Add noise OVER the photo for a grainy vintage camera look
ctx.fillStyle = "rgba(255,255,255,0.06)";
for (let i = 0; i < imgW; i += 2) {
for (let j = 0; j < imgH; j += 2) {
if (Math.random() > 0.5) ctx.fillRect(imgX + i, imgY + j, 2, 2);
}
}
// Tape on top to "hold" the photo
ctx.fillStyle = "rgba(210, 210, 190, 0.75)";
ctx.shadowColor = "rgba(0,0,0,0.3)";
ctx.shadowBlur = 3;
ctx.shadowOffsetY = 2;
// Slanted tape
ctx.translate(imgX + imgW/2, imgY - pad + 5);
ctx.rotate(-5 * Math.PI / 180);
ctx.fillRect(-60, -15, 120, 30);
ctx.restore();
// 4. Draw Typewriter Case Details
ctx.fillStyle = "#111";
ctx.font = 'bold 28px "Courier New", Courier, monospace';
ctx.textAlign = "left";
const lines = details.split('\n');
let textY = imgY + imgH + 130;
for (let line of lines) {
ctx.fillText(line.trim(), 100, textY);
// Typewriter dotted underline effect
ctx.beginPath();
ctx.moveTo(100, textY + 8);
ctx.lineTo(100 + ctx.measureText(line.trim()).width, textY + 8);
ctx.lineWidth = 1;
ctx.setLineDash([3, 4]);
ctx.strokeStyle = "#444";
ctx.stroke();
ctx.setLineDash([]);
textY += 50;
}
// 5. Draw red Top Secret stamp
ctx.save();
ctx.translate(w - 240, h - 200);
ctx.rotate(-12 * Math.PI / 180);
const stampW = 380;
const stampH = 70;
// Outer box of the stamp
ctx.strokeStyle = "rgba(180, 20, 20, 0.85)";
ctx.lineWidth = 5;
ctx.strokeRect(-stampW/2, -stampH/2, stampW, stampH);
// Inner box of the stamp
ctx.lineWidth = 2;
ctx.strokeRect(-stampW/2 + 8, -stampH/2 + 8, stampW - 16, stampH - 16);
// Stamp text
ctx.fillStyle = "rgba(180, 20, 20, 0.85)";
ctx.font = 'bold 36px Arial, sans-serif';
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText(stampText, 0, 0);
// Distress/scratch effect for the rubber stamp
ctx.globalCompositeOperation = "destination-out";
for (let i = 0; i < 40; i++) {
ctx.beginPath();
ctx.arc(-stampW/2 + Math.random() * stampW, -stampH/2 + Math.random() * stampH, Math.random() * 3, 0, Math.PI * 2);
ctx.fill();
}
ctx.restore();
// 6. Draw Footer Info
ctx.fillStyle = "#222";
ctx.font = '22px "Courier New", Courier, monospace';
ctx.textAlign = "right";
ctx.fillText("Стр. 01/01", w - 80, h - 60);
ctx.textAlign = "left";
let formattedDate = new Date().toLocaleDateString('ru-RU');
ctx.fillText(`ДАТА ОБНОВЛЕНИЯ: ${formattedDate}`, 80, h - 100);
ctx.fillText("ПОДПИСЬ КУРАТОРА: ____________", 80, h - 60);
return canvas;
}
Apply Changes