You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, videoTitle = "Awesome Video Title", duration = "10:04", showPlayerUI = "true") {
// Create a canvas to draw our output
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// Set dimensions based on the original image
const w = originalImg.width;
const h = originalImg.height;
canvas.width = w;
canvas.height = h;
// Draw the original image onto the canvas as background
ctx.drawImage(originalImg, 0, 0, w, h);
// Helper function to draw rounded rectangles cross-browser
function drawRoundRect(ctx, x, y, width, height, radius) {
ctx.beginPath();
ctx.moveTo(x + radius, y);
ctx.lineTo(x + width - radius, y);
ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
ctx.lineTo(x + width, y + height - radius);
ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
ctx.lineTo(x + radius, y + height);
ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
ctx.lineTo(x, y + radius);
ctx.quadraticCurveTo(x, y, x + radius, y);
ctx.closePath();
}
const isPlayerUI = showPlayerUI === "true";
if (isPlayerUI) {
// Draw top shadow/gradient for the title
const topGrad = ctx.createLinearGradient(0, 0, 0, h * 0.25);
topGrad.addColorStop(0, 'rgba(0,0,0,0.8)');
topGrad.addColorStop(1, 'rgba(0,0,0,0)');
ctx.fillStyle = topGrad;
ctx.fillRect(0, 0, w, h * 0.25);
// Draw bottom shadow/gradient for the controls
const bottomGrad = ctx.createLinearGradient(0, h * 0.75, 0, h);
bottomGrad.addColorStop(0, 'rgba(0,0,0,0)');
bottomGrad.addColorStop(1, 'rgba(0,0,0,0.8)');
ctx.fillStyle = bottomGrad;
ctx.fillRect(0, h * 0.75, w, h * 0.25);
// Draw the Title Text
ctx.fillStyle = "#ffffff";
const titleFontSize = Math.max(16, h * 0.04);
ctx.font = `${titleFontSize}px Roboto, Arial, sans-serif`;
ctx.textBaseline = "top";
ctx.fillText(videoTitle, w * 0.03, h * 0.03);
// --- Bottom Controls ---
const controlY = h - h * 0.06;
const progBarY = h - h * 0.085;
// Progress Bar Background
ctx.fillStyle = 'rgba(255, 255, 255, 0.3)';
ctx.fillRect(w * 0.03, progBarY, w * 0.94, h * 0.008);
// Progress Bar Fill (Red)
ctx.fillStyle = '#FF0000'; // YouTube Red
const progressWidth = w * 0.35; // 35% viewed
ctx.fillRect(w * 0.03, progBarY, progressWidth, h * 0.008);
// Progress Knob
ctx.beginPath();
ctx.arc(w * 0.03 + progressWidth, progBarY + (h * 0.008) / 2, h * 0.015, 0, Math.PI * 2);
ctx.fill();
// Control Panel: Play Icon (Bottom Left)
ctx.fillStyle = "#ffffff";
ctx.beginPath();
const playIconSize = h * 0.035;
ctx.moveTo(w * 0.03, controlY);
ctx.lineTo(w * 0.03, controlY + playIconSize);
ctx.lineTo(w * 0.03 + playIconSize * 0.8, controlY + playIconSize / 2);
ctx.fill();
// Control Panel: Volume Icon Placeholder (Speaker shape)
const volX = w * 0.03 + playIconSize * 1.5;
const volY = controlY + playIconSize * 0.25;
const volSize = playIconSize * 0.5;
ctx.beginPath();
ctx.moveTo(volX, volY + volSize * 0.3);
ctx.lineTo(volX + volSize * 0.3, volY + volSize * 0.3);
ctx.lineTo(volX + volSize * 0.7, volY);
ctx.lineTo(volX + volSize * 0.7, volY + volSize);
ctx.lineTo(volX + volSize * 0.3, volY + volSize * 0.7);
ctx.lineTo(volX, volY + volSize * 0.7);
ctx.fill();
// Control Panel: Time / Duration Text
const timeFontSize = Math.max(12, h * 0.025);
ctx.font = `${timeFontSize}px Roboto, Arial, sans-serif`;
ctx.textBaseline = "middle";
ctx.fillText(`1:23 / ${duration}`, volX + volSize + w * 0.02, controlY + playIconSize / 2);
// Control Panel: Real fullscreen / settings placeholder rectangles to mock layout
const iconSize = playIconSize * 0.7;
// Fullscreen Box
ctx.fillRect(w * 0.97 - iconSize, controlY + (playIconSize - iconSize)/2, iconSize, iconSize);
// Theater Mode Box
ctx.strokeRect(w * 0.97 - iconSize * 2.5, controlY + (playIconSize - iconSize)/2, iconSize * 1.2, iconSize);
// Settings Gear Placeholder
ctx.beginPath();
ctx.arc(w * 0.97 - iconSize * 4, controlY + playIconSize / 2, iconSize / 2, 0, Math.PI * 2);
ctx.fill();
} else {
// Overlay standard YouTube duration pill (Thumbnail marker mode)
const pillFontSize = Math.max(12, h * 0.035);
ctx.font = `bold ${pillFontSize}px Roboto, Arial, sans-serif`;
const metrics = ctx.measureText(duration);
const textW = metrics.width;
const textH = pillFontSize;
const paddingX = textH * 0.5;
const paddingY = textH * 0.3;
const pX = w - textW - paddingX * 2 - (w * 0.02); // Margin right
const pY = h - textH - paddingY * 2 - (h * 0.02); // Margin bottom
ctx.fillStyle = 'rgba(0, 0, 0, 0.8)';
drawRoundRect(ctx, pX, pY, textW + paddingX * 2, textH + paddingY * 2, 4);
ctx.fill();
ctx.fillStyle = '#ffffff';
ctx.textBaseline = "top";
ctx.fillText(duration, pX + paddingX, pY + paddingY);
}
// --- Big Red Central Play Button ---
// Scaled proportionately, capped by minimum typical sizes
const bw = Math.max(68, w * 0.12);
const bh = bw * (48 / 68);
const bx = (w - bw) / 2;
const by = (h - bh) / 2;
ctx.fillStyle = '#FF0000'; // YouTube Red
drawRoundRect(ctx, bx, by, bw, bh, bw * 0.2); // Border radius is roughly 20% of width
ctx.fill();
// White Inner Triangle
const triW = bw * 0.25;
const triH = bh * 0.50;
const cx = w / 2;
const cy = h / 2;
// Use centroid positioning for visual balance
const triLeft = cx - triW / 3;
const triRight = cx + (triW * 2) / 3;
const triTop = cy - triH / 2;
const triBottom = cy + triH / 2;
ctx.fillStyle = '#FFFFFF';
ctx.beginPath();
ctx.moveTo(triLeft, triTop); // Top Vertex
ctx.lineTo(triRight, cy); // Right Vertex (Pointing)
ctx.lineTo(triLeft, triBottom); // Bottom Vertex
ctx.closePath();
ctx.fill();
return canvas;
}
Apply Changes