You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, variantYear = "1994", includeSearchlights = "true", customText = "20th,CENTURY,VARIANTS") {
const width = originalImg.width;
const height = originalImg.height;
const canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
const ctx = canvas.getContext('2d');
const year = variantYear.toString().trim();
const luma = (r, g, b) => 0.299 * r + 0.587 * g + 0.114 * b;
// 1. Initial CSS filtering based on Era
if (year === "1935") {
ctx.filter = 'grayscale(100%) contrast(1.3) brightness(0.9)';
} else if (year === "1953") {
ctx.filter = 'saturate(1.5) contrast(1.1) sepia(0.2)';
} else if (year === "1981") {
ctx.filter = 'saturate(1.2) contrast(1.1) brightness(0.95)';
} else if (year === "1994") {
ctx.filter = 'saturate(1.4) contrast(1.2) brightness(1.1)';
} else if (year === "2009") {
ctx.filter = 'saturate(1.6) contrast(1.3)';
} else if (year === "2020") {
ctx.filter = 'saturate(1.2) contrast(1.1)';
} else {
ctx.filter = 'none';
}
// Draw base image
ctx.drawImage(originalImg, 0, 0);
ctx.filter = 'none'; // Reset filter
// 2. Pixel-level color grading for deep cinematic styles
const imgData = ctx.getImageData(0, 0, width, height);
const data = imgData.data;
for (let i = 0; i < data.length; i += 4) {
let r = data[i], g = data[i+1], b = data[i+2];
let lum = luma(r, g, b);
if (year === "1935") {
// Apply slight sepia tone to grayscale base
data[i] = Math.min(255, r * 1.1);
data[i+1] = g;
data[i+2] = b * 0.9;
} else if (year === "1994") {
// Golden hour / CGI warmth
data[i] = Math.min(255, r * 1.15);
data[i+1] = Math.min(255, g * 1.1);
data[i+2] = b * 0.85;
} else if (year === "2009" || year === "2020") {
// Blockbuster Teal & Orange Look
if (lum < 130) {
// Boost blue/teal in shadows
data[i] = r * 0.9;
data[i+1] = g * 1.05;
data[i+2] = Math.min(255, b * 1.3);
} else {
// Boost orange in highlights
data[i] = Math.min(255, r * 1.25);
data[i+1] = Math.min(255, g * 1.15);
data[i+2] = b * 0.9;
}
}
}
ctx.putImageData(imgData, 0, 0);
// 3. Film Grain for older variants
if (year === "1935" || year === "1953" || year === "1981") {
const grainData = ctx.getImageData(0, 0, width, height);
const gData = grainData.data;
const intensity = year === "1935" ? 45 : (year === "1953" ? 25 : 15);
for (let i = 0; i < gData.length; i += 4) {
const noise = (Math.random() - 0.5) * intensity;
gData[i] = Math.max(0, Math.min(255, gData[i] + noise));
gData[i+1] = Math.max(0, Math.min(255, gData[i+1] + noise));
gData[i+2] = Math.max(0, Math.min(255, gData[i+2] + noise));
}
ctx.putImageData(grainData, 0, 0);
}
// 4. Overlap Iconic Cinematic Searchlights
if (includeSearchlights === "true" || includeSearchlights === "1") {
ctx.save();
ctx.globalCompositeOperation = "screen";
const drawLight = (startX, startY, endX1, endX2, opacity = 0.3) => {
ctx.beginPath();
ctx.moveTo(startX, startY);
ctx.lineTo(endX1, 0);
ctx.lineTo(endX2, 0);
ctx.closePath();
const grad = ctx.createLinearGradient(0, height, 0, 0);
grad.addColorStop(0, `rgba(255, 255, 220, ${opacity})`);
grad.addColorStop(1, `rgba(255, 255, 220, 0)`);
ctx.fillStyle = grad;
ctx.fill();
};
// Left, Right, and Center-ish crisscrossing searchlights
drawLight(width * 0.15, height, width * 0.35, width * 0.55, 0.4);
drawLight(width * 0.85, height, width * 0.20, width * 0.45, 0.45);
drawLight(width * 0.55, height, width * 0.70, width * 0.90, 0.25);
drawLight(width * 0.05, height, width * 0.10, width * 0.25, 0.2);
ctx.restore();
}
// 5. Render 3D Logo Block Text Setup
if (customText && customText.length > 0) {
ctx.save();
const lines = customText.split(",");
// Dynamic sizing and positioning
const baseSize = Math.max((width + height) / 2 * 0.08, 30);
ctx.translate(width / 2, height - (lines.length * baseSize * 0.8) - (height * 0.1));
// Apply perspective skew (angled slightly upward and leaning right into the Z-axis)
ctx.transform(1, -0.15, 0, 1, 0, 0);
ctx.font = `bold ${baseSize}px 'Arial Black', Impact, sans-serif`;
ctx.textAlign = "center";
ctx.textBaseline = "middle";
const lineHeight = baseSize * 1.1;
const depth = year === "1935" ? Math.floor(baseSize * 0.1) : Math.floor(baseSize * 0.3);
// Loop backwards for 3D extrusion/thickness stack
for (let i = depth; i >= 0; i--) {
// Shadow face coloring scheme based on era
if (i === 0) {
ctx.fillStyle = year === "1935" ? "#f4f4f4" : "#ffcc00"; // Top Face
} else {
ctx.fillStyle = year === "1935" ? "#555" : ((i % 2 === 0) ? "#a67c00" : "#d49a00"); // Sides
}
const xOffset = -i * (baseSize * 0.03);
const yOffset = i * (baseSize * 0.03);
for (let l = 0; l < lines.length; l++) {
const yPos = (l * lineHeight) - ((lines.length * lineHeight) / 2);
ctx.fillText(lines[l], xOffset, yPos + yOffset);
// Add an outline on the final top layer for extra pop
if (i === 0 && year !== "1935") {
ctx.strokeStyle = "#fff2a8";
ctx.lineWidth = Math.max(baseSize * 0.02, 1);
ctx.strokeText(lines[l], xOffset, yPos + yOffset);
}
}
}
ctx.restore();
}
// 6. Draw Vignette to finish the cinematic framing
if (year === "1935" || year === "1953" || year === "1981") {
const outerRadius = Math.sqrt(Math.pow(width/2, 2) + Math.pow(height/2, 2));
const gradient = ctx.createRadialGradient(width/2, height/2, outerRadius * 0.4, width/2, height/2, outerRadius);
gradient.addColorStop(0, 'rgba(0,0,0,0)');
gradient.addColorStop(1, year === "1935" ? 'rgba(0,0,0,0.85)' : 'rgba(0,0,0,0.4)');
ctx.fillStyle = gradient;
ctx.fillRect(0, 0, width, height);
}
return canvas;
}
Apply Changes