You can edit the below JavaScript code to customize the image tool.
Apply Changes
/**
* Processes an image by applying a cinematic filter, letterboxing,
* and an overlay reflecting a "Movie Request Processing" theme.
*
* @param {HTMLImageElement} originalImg - The source image object.
* @param {string} textRu - Top title text in Russian per description.
* @param {string} textEn - Bottom subtitle text in English per description.
* @param {number} progressPercentage - Value for the progress bar (0 to 100).
* @param {number} cinematicStrength - Intensity of the teal-and-orange color grading (0 to 1).
* @param {number} overlayOpacity - Darkness of the processing screen overlay (0 to 1).
* @returns {HTMLCanvasElement} - The processed canvas element displaying the final result.
*/
function processImage(
originalImg,
textRu = "Обработка Кино запроса",
textEn = "Processing Your Requect",
progressPercentage = 65,
cinematicStrength = 0.3,
overlayOpacity = 0.55
) {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// Match canvas size to the source image
canvas.width = originalImg.width;
canvas.height = originalImg.height;
// 1. Draw the original image as base
ctx.drawImage(originalImg, 0, 0);
// 2. Apply Cinematic Color Grading (Teal and Orange)
// Wrapped in a try-catch to prevent failure if cross-origin image triggers a CORS error.
try {
const imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
const data = imgData.data;
for (let i = 0; i < data.length; i += 4) {
let r = data[i];
let g = data[i+1];
let b = data[i+2];
// Calculate relative luminance
let luma = 0.299 * r + 0.587 * g + 0.114 * b;
let mix = luma / 255;
// Highlight (orange-ish) and Shadow (teal-ish) mapping
let targetR = 25 * (1 - mix) + 255 * mix;
let targetG = 100 * (1 - mix) + 153 * mix;
let targetB = 120 * (1 - mix) + 51 * mix;
// Blend original colors with the cinematic tone mapping
data[i] = r * (1 - cinematicStrength) + targetR * cinematicStrength;
data[i+1] = g * (1 - cinematicStrength) + targetG * cinematicStrength;
data[i+2] = b * (1 - cinematicStrength) + targetB * cinematicStrength;
}
ctx.putImageData(imgData, 0, 0);
} catch (e) {
console.warn("Could not apply cinematic grading due to canvas CORS restrictions.", e);
}
// 3. Cinematic Letterbox (Black Bars)
const barHeight = Math.floor(canvas.height * 0.12); // 12% bar height on top and bottom
ctx.fillStyle = "#000000";
ctx.fillRect(0, 0, canvas.width, barHeight); // Top bar
ctx.fillRect(0, canvas.height - barHeight, canvas.width, barHeight); // Bottom bar
// 4. Dark Overlay (only between the letterbox bars to emphasize the processing text)
ctx.fillStyle = `rgba(0, 0, 0, ${overlayOpacity})`;
ctx.fillRect(0, barHeight, canvas.width, canvas.height - barHeight * 2);
// 5. Scanlines effect (Simulation of a terminal/display)
ctx.fillStyle = "rgba(0, 0, 0, 0.15)";
for (let i = barHeight; i < canvas.height - barHeight; i += 4) {
ctx.fillRect(0, i, canvas.width, 2);
}
// 6. Draw Texts
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.shadowColor = "rgba(0, 0, 0, 0.9)";
ctx.shadowBlur = Math.max(3, canvas.width * 0.005);
// Main text (Russian)
const fontSizeRu = Math.max(16, canvas.height * 0.05);
ctx.font = `bold ${fontSizeRu}px "Courier New", Courier, monospace`;
ctx.fillStyle = "#ffffff";
ctx.fillText(textRu, canvas.width / 2, canvas.height / 2 - fontSizeRu);
// Sub text (English)
const fontSizeEn = Math.max(12, canvas.height * 0.035);
ctx.font = `${fontSizeEn}px "Courier New", Courier, monospace`;
ctx.fillStyle = "#b0b0b0";
ctx.fillText(textEn, canvas.width / 2, canvas.height / 2 + fontSizeEn * 0.5);
// Reset shadow for drawing the UI elements
ctx.shadowBlur = 0;
// 7. Progress Bar
const pbWidth = canvas.width * 0.45;
const pbHeight = Math.max(10, canvas.height * 0.02);
const pbX = (canvas.width - pbWidth) / 2;
const pbY = canvas.height / 2 + fontSizeEn * 2.5;
// Progress bar outer boundary
ctx.strokeStyle = "#ffffff";
const strokeWidth = Math.max(2, canvas.width * 0.002);
ctx.lineWidth = strokeWidth;
ctx.strokeRect(pbX, pbY, pbWidth, pbHeight);
// Progress bar inner fill
ctx.fillStyle = "#00ffcc"; // Cyber/Sci-Fi green tint
const boundedProgress = Math.min(100, Math.max(0, progressPercentage));
const padding = strokeWidth + 2;
const innerWidth = (pbWidth - padding * 2) * (boundedProgress / 100);
const innerHeight = Math.max(1, pbHeight - padding * 2);
if(innerWidth > 0) {
ctx.fillRect(pbX + padding, pbY + padding, innerWidth, innerHeight);
}
return canvas;
}
Apply Changes