You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, currentTime = "1:41:52", duration = "1:42:00", movieTitle = "Big Hero 6", gagText = "Tubi TV • Jun 30, 2027") {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// Standardize canvas dimensions to the input image
canvas.width = originalImg.width;
canvas.height = originalImg.height;
// Draw the original image as the background (the "video")
ctx.drawImage(originalImg, 0, 0, canvas.width, canvas.height);
// Calculate scaling factor for the UI based on standard 1280p width
const scale = Math.max(canvas.width / 1280, 0.4);
// Draw Top Gradient Overlay (for Header)
const topGrad = ctx.createLinearGradient(0, 0, 0, 150 * scale);
topGrad.addColorStop(0, 'rgba(0, 0, 0, 0.85)');
topGrad.addColorStop(1, 'rgba(0, 0, 0, 0)');
ctx.fillStyle = topGrad;
ctx.fillRect(0, 0, canvas.width, 150 * scale);
// Draw Bottom Gradient Overlay (for Controls)
const bottomGrad = ctx.createLinearGradient(0, canvas.height, 0, canvas.height - 180 * scale);
bottomGrad.addColorStop(0, 'rgba(0, 0, 0, 0.9)');
bottomGrad.addColorStop(1, 'rgba(0, 0, 0, 0)');
ctx.fillStyle = bottomGrad;
ctx.fillRect(0, canvas.height - 180 * scale, canvas.width, 180 * scale);
// ----- TOP UI -----
// Back Arrow
const topY = 60 * scale;
ctx.strokeStyle = '#ffffff';
ctx.lineWidth = 3 * scale;
ctx.lineCap = 'round';
ctx.lineJoin = 'round';
ctx.beginPath();
ctx.moveTo(35 * scale + 12 * scale, topY - 10 * scale);
ctx.lineTo(35 * scale + 2 * scale, topY);
ctx.lineTo(35 * scale + 12 * scale, topY + 10 * scale);
ctx.moveTo(35 * scale + 2 * scale, topY);
ctx.lineTo(35 * scale + 25 * scale, topY);
ctx.stroke();
// Movie Title
ctx.fillStyle = '#ffffff';
ctx.textBaseline = 'middle';
ctx.textAlign = 'left';
ctx.font = `600 ${28 * scale}px "Segoe UI", Roboto, Helvetica, Arial, sans-serif`;
ctx.fillText(`${movieTitle} (2014)`, 80 * scale, topY - 5 * scale);
// Gag/MetaData Text
ctx.fillStyle = '#cccccc';
ctx.font = `400 ${16 * scale}px "Segoe UI", Roboto, Helvetica, Arial, sans-serif`;
ctx.fillText(gagText, 80 * scale, topY + 20 * scale);
// Tubi Logo
ctx.fillStyle = '#F54300'; // Tubi classic orange
ctx.font = `bold ${38 * scale}px "Arial Rounded MT Bold", "Helvetica Rounded", sans-serif`;
ctx.textAlign = 'right';
ctx.fillText("tubi", canvas.width - 40 * scale, topY);
ctx.textAlign = 'left'; // Reset
// ----- BOTTOM UI -----
const uiY = canvas.height - 45 * scale;
const barY = canvas.height - 85 * scale;
// Progress Bar Background
const barX = 30 * scale;
const barW = canvas.width - 60 * scale;
ctx.fillStyle = 'rgba(255, 255, 255, 0.3)';
ctx.fillRect(barX, barY - 3 * scale, barW, 6 * scale);
// Calculate Progress
const parseTime = (str) => {
const parts = str.split(':').map(Number);
if (parts.length === 3) return parts[0] * 3600 + parts[1] * 60 + parts[2];
if (parts.length === 2) return parts[0] * 60 + parts[1];
return 0;
};
const currentSec = parseTime(currentTime);
const durationSec = parseTime(duration);
let progress = durationSec > 0 ? currentSec / durationSec : 0.99;
if (progress > 1) progress = 1;
// Progress Line
ctx.fillStyle = '#F54300';
ctx.fillRect(barX, barY - 3 * scale, barW * progress, 6 * scale);
// Progress Thumb Circle
ctx.fillStyle = '#ffffff';
ctx.beginPath();
ctx.arc(barX + barW * progress, barY, 8 * scale, 0, Math.PI * 2);
ctx.fill();
// Pause Button
const pauseX = 40 * scale;
ctx.fillStyle = '#ffffff';
ctx.fillRect(pauseX, uiY - 12 * scale, 6 * scale, 24 * scale);
ctx.fillRect(pauseX + 12 * scale, uiY - 12 * scale, 6 * scale, 24 * scale);
// Volume Icon
const volX = pauseX + 50 * scale;
ctx.beginPath();
ctx.moveTo(volX + 10 * scale, uiY - 6 * scale);
ctx.lineTo(volX + 10 * scale, uiY + 6 * scale);
ctx.lineTo(volX, uiY + 6 * scale);
ctx.lineTo(volX, uiY - 6 * scale);
ctx.fill();
ctx.beginPath();
ctx.moveTo(volX + 10 * scale, uiY - 12 * scale);
ctx.lineTo(volX + 22 * scale, uiY - 20 * scale);
ctx.lineTo(volX + 22 * scale, uiY + 20 * scale);
ctx.lineTo(volX + 10 * scale, uiY + 12 * scale);
ctx.fill();
// Volume Curves
ctx.beginPath();
ctx.arc(volX + 22 * scale, uiY, 12 * scale, -Math.PI / 3, Math.PI / 3);
ctx.stroke();
ctx.beginPath();
ctx.arc(volX + 22 * scale, uiY, 20 * scale, -Math.PI / 3.5, Math.PI / 3.5);
ctx.stroke();
// Time Text
const timeX = volX + 50 * scale;
ctx.fillStyle = '#ffffff';
ctx.font = `${18 * scale}px "Segoe UI", Roboto, Helvetica, Arial, sans-serif`;
ctx.fillText(`${currentTime}`, timeX, uiY + 1 * scale);
const currTimeW = ctx.measureText(`${currentTime}`).width;
ctx.fillStyle = '#aaaaaa';
ctx.fillText(` / ${duration}`, timeX + currTimeW, uiY + 1 * scale);
// Right Side Icons (Fullscreen, Settings, CC)
const fsX = canvas.width - 40 * scale; // Center of Fullscreen Icon
// Fullscreen Corners
const s = 9 * scale;
ctx.strokeStyle = '#ffffff';
ctx.lineWidth = 2.5 * scale;
ctx.beginPath();
// Top-left
ctx.moveTo(fsX - s, uiY - s + 6 * scale); ctx.lineTo(fsX - s, uiY - s); ctx.lineTo(fsX - s + 6 * scale, uiY - s);
// Top-right
ctx.moveTo(fsX + s - 6 * scale, uiY - s); ctx.lineTo(fsX + s, uiY - s); ctx.lineTo(fsX + s, uiY - s + 6 * scale);
// Bottom-right
ctx.moveTo(fsX + s, uiY + s - 6 * scale); ctx.lineTo(fsX + s, uiY + s); ctx.lineTo(fsX + s - 6 * scale, uiY + s);
// Bottom-left
ctx.moveTo(fsX - s + 6 * scale, uiY + s); ctx.lineTo(fsX - s, uiY + s); ctx.lineTo(fsX - s, uiY + s - 6 * scale);
ctx.stroke();
// Settings Gear Icon
const gearX = fsX - 55 * scale;
ctx.beginPath();
ctx.arc(gearX, uiY, 9 * scale, 0, Math.PI * 2);
ctx.lineWidth = 2.5 * scale;
ctx.stroke();
for(let i = 0; i < 8; i++) {
const angle = (Math.PI / 4) * i;
ctx.beginPath();
ctx.moveTo(gearX + Math.cos(angle) * 9 * scale, uiY + Math.sin(angle) * 9 * scale);
ctx.lineTo(gearX + Math.cos(angle) * 13 * scale, uiY + Math.sin(angle) * 13 * scale);
ctx.stroke();
}
// Gear Center Hole
ctx.beginPath();
ctx.arc(gearX, uiY, 3 * scale, 0, Math.PI * 2);
ctx.fillStyle = '#111'; // Makes it look cut out by covering it
ctx.fill();
// Subtitles (CC) Icon
const ccX = gearX - 55 * scale;
ctx.lineWidth = 2 * scale;
ctx.beginPath();
if (ctx.roundRect) {
ctx.roundRect(ccX - 15 * scale, uiY - 11 * scale, 30 * scale, 22 * scale, 4 * scale);
} else {
ctx.rect(ccX - 15 * scale, uiY - 11 * scale, 30 * scale, 22 * scale);
}
ctx.stroke();
ctx.fillStyle = '#ffffff';
ctx.font = `bold ${12 * scale}px Arial`;
ctx.textAlign = 'center';
ctx.fillText("CC", ccX, uiY + 1 * scale);
ctx.textAlign = 'left';
return canvas;
}
Apply Changes