You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, scanPosition = '50', vintageIntensity = '80', movieTitle = 'Морозко (1964)') {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = originalImg.width;
canvas.height = originalImg.height;
// Sanitize parameters
let pos = Number(scanPosition);
if (isNaN(pos)) pos = 50;
pos = Math.max(0, Math.min(100, pos));
let intensity = Number(vintageIntensity);
if (isNaN(intensity)) intensity = 80;
intensity = Math.max(0, Math.min(100, intensity));
// Draw the image with a vintage look (sepia, high contrast)
const sepiaValue = (intensity / 100) * 0.8;
const contrastValue = 100 + (intensity / 100) * 40;
ctx.filter = `sepia(${sepiaValue}) contrast(${contrastValue}%) brightness(90%)`;
ctx.drawImage(originalImg, 0, 0, canvas.width, canvas.height);
ctx.filter = 'none';
// Add noise layer to represent old film / poor signal
const maxNoise = (intensity / 100) * 30;
if (maxNoise > 0) {
try {
const imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const data = imgData.data;
for (let i = 0; i < data.length; i += 4) {
const noise = (Math.random() - 0.5) * maxNoise * 2.55;
data[i] = Math.min(255, Math.max(0, data[i] + noise));
data[i+1] = Math.min(255, Math.max(0, data[i+1] + noise));
data[i+2] = Math.min(255, Math.max(0, data[i+2] + noise));
}
ctx.putImageData(imgData, 0, 0);
} catch (e) {
// Ignore if canvas is tainted due to CORS issues
console.warn("Could not apply pixel noise due to CORS constraints.");
}
}
// Add film grain vertical scratches
ctx.strokeStyle = `rgba(255, 255, 255, ${intensity / 200})`;
ctx.lineWidth = 1;
for(let i = 0; i < 5; i++) {
ctx.beginPath();
const x = Math.random() * canvas.width;
ctx.moveTo(x, 0);
ctx.lineTo(x + (Math.random() - 0.5) * 10, canvas.height);
ctx.stroke();
}
// --- Draw Scanner UI Overlay ---
ctx.strokeStyle = '#00FF41'; // Classic terminal green
ctx.fillStyle = '#00FF41';
ctx.shadowColor = '#00FF41';
ctx.shadowBlur = 10;
ctx.lineWidth = Math.max(2, canvas.width / 200);
// Viewfinder corners
const cornerSize = Math.min(canvas.width, canvas.height) * 0.1;
const margin = cornerSize / 2;
// Top-left
ctx.beginPath();
ctx.moveTo(margin, margin + cornerSize);
ctx.lineTo(margin, margin);
ctx.lineTo(margin + cornerSize, margin);
ctx.stroke();
// Top-right
ctx.beginPath();
ctx.moveTo(canvas.width - margin - cornerSize, margin);
ctx.lineTo(canvas.width - margin, margin);
ctx.lineTo(canvas.width - margin, margin + cornerSize);
ctx.stroke();
// Bottom-left
ctx.beginPath();
ctx.moveTo(margin, canvas.height - margin - cornerSize);
ctx.lineTo(margin, canvas.height - margin);
ctx.lineTo(margin + cornerSize, canvas.height - margin);
ctx.stroke();
// Bottom-right
ctx.beginPath();
ctx.moveTo(canvas.width - margin - cornerSize, canvas.height - margin);
ctx.lineTo(canvas.width - margin, canvas.height - margin);
ctx.lineTo(canvas.width - margin, canvas.height - margin - cornerSize);
ctx.stroke();
// Scanner horizontal line based on position
const yScan = (pos / 100) * canvas.height;
ctx.beginPath();
ctx.moveTo(0, yScan);
ctx.lineTo(canvas.width, yScan);
ctx.lineWidth = Math.max(3, canvas.height / 150);
ctx.stroke();
// Scanner Gradient Area below line to simulate scan glow
const grad = ctx.createLinearGradient(0, yScan - canvas.height * 0.1, 0, yScan);
grad.addColorStop(0, 'rgba(0, 255, 65, 0)');
grad.addColorStop(1, 'rgba(0, 255, 65, 0.3)');
ctx.fillStyle = grad;
ctx.fillRect(0, yScan - canvas.height * 0.1, canvas.width, canvas.height * 0.1);
// Context HUD text wrapping the "Russian folk titles" and "films of past years scanner" theme
const fontSize = Math.max(14, canvas.width / 40);
ctx.font = `${fontSize}px "Courier New", Courier, monospace`;
ctx.shadowBlur = 5;
ctx.fillStyle = '#00FF41';
ctx.textAlign = 'left';
ctx.textBaseline = 'top';
const textMargin = margin + 15;
// Top text info
ctx.fillText("ОБЗОР: ПРОГРАММА ФИЛЬМОВ ПРОШЛЫХ ЛЕТ", textMargin, margin + 10);
ctx.fillText(`СКАНИРОВАНИЕ... ПРОГРЕСС: ${pos}%`, textMargin, margin + 10 + fontSize * 1.5);
if (pos > 10) {
ctx.fillText("БАЗА: Медиатека русских народных сказок", textMargin, margin + 10 + fontSize * 3);
}
// Bottom text info regarding identifier
ctx.textBaseline = 'bottom';
if (pos >= 60) {
ctx.fillStyle = '#FFD700'; // Gold color to signify a match is found
ctx.shadowColor = '#FFD700';
ctx.fillText("ИДЕНТИФИКАТОР: НАЙДЕНО СОВПАДЕНИЕ", textMargin, canvas.height - margin - fontSize * 1.5 - 5);
ctx.fillText(`НАЗВАНИЕ: ${movieTitle}`, textMargin, canvas.height - margin - 5);
} else {
ctx.fillText("ИДЕНТИФИКАТОР: АНАЛИЗ КАДРОВ...", textMargin, canvas.height - margin - 5);
}
ctx.shadowBlur = 0; // reset shadows
return canvas;
}
Apply Changes