You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, characterName = "STAR B.", commandsStr = "Attack,Magic,Mewberty,Item", videoTime = "14:26 / 35:10", progressPercent = 42) {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// Set standard 16:9 gameplay video resolution
const width = 1280;
const height = 720;
canvas.width = width;
canvas.height = height;
// 1. Draw the "gameplay" background by scaling the original image properly (object-fit: cover)
const imgRatio = originalImg.width / originalImg.height;
const canvasRatio = width / height;
let sWidth, sHeight, sx, sy;
if (imgRatio > canvasRatio) {
sHeight = originalImg.height;
sWidth = sHeight * canvasRatio;
sx = (originalImg.width - sWidth) / 2;
sy = 0;
} else {
sWidth = originalImg.width;
sHeight = sWidth / canvasRatio;
sx = 0;
sy = (originalImg.height - sHeight) / 2;
}
// Draw background image
ctx.drawImage(originalImg, sx, sy, sWidth, sHeight, 0, 0, width, height);
// Convenience function for rounded rectangles
function drawRoundRect(x, y, w, h, r) {
ctx.beginPath();
ctx.moveTo(x + r, y);
ctx.lineTo(x + w - r, y);
ctx.arcTo(x + w, y, x + w, y + r, r);
ctx.lineTo(x + w, y + h - r);
ctx.arcTo(x + w, y + h, x + w - r, y + h, r);
ctx.lineTo(x + r, y + h);
ctx.arcTo(x, y + h, x, y + h - r, r);
ctx.lineTo(x, y + r);
ctx.arcTo(x, y, x + r, y, r);
ctx.closePath();
}
// 2. Kingdom Hearts x SVTFOE HUD rendering
const hudSafeY = height - 120; // Leave room for video player UI
// ---- A. COMMAND MENU (Bottom Left) ----
const cmdWidth = 200;
const cmdHeight = 220;
const cmdX = 60;
const cmdY = hudSafeY - cmdHeight;
// Command box background (SVTFOE x KH theme: Dark blue glass with pink border)
ctx.fillStyle = 'rgba(10, 10, 40, 0.7)';
ctx.strokeStyle = '#ff66b2'; // Neon pink for SVTFOE
ctx.lineWidth = 4;
drawRoundRect(cmdX, cmdY, cmdWidth, cmdHeight, 15);
ctx.fill();
ctx.stroke();
// Command texts
const commands = commandsStr.split(',').slice(0, 4); // Max 4 commands
ctx.font = 'bold 26px "Palatino Linotype", "Book Antiqua", Palatino, serif';
ctx.textAlign = 'left';
ctx.textBaseline = 'middle';
for (let i = 0; i < commands.length; i++) {
const textY = cmdY + 45 + (i * 45);
if (i === 1) { // Simulate having "Mewberty/Magic" selected
ctx.fillStyle = 'rgba(255, 102, 178, 0.4)'; // Pink highlight
drawRoundRect(cmdX + 8, textY - 20, cmdWidth - 16, 40, 8);
ctx.fill();
ctx.fillStyle = '#ffff66'; // Yellow selected text
// Draw a little SVTFOE wand/star icon for selection cursor
ctx.fillStyle = '#ff3399';
ctx.beginPath();
ctx.arc(cmdX + 25, textY, 6, 0, Math.PI * 2);
ctx.fill();
} else {
ctx.fillStyle = '#ffffff';
}
ctx.shadowColor = 'black';
ctx.shadowBlur = 4;
ctx.shadowOffsetX = 2;
ctx.shadowOffsetY = 2;
ctx.fillText(commands[i].trim(), cmdX + 45, textY);
ctx.shadowColor = 'transparent'; // reset
}
// ---- B. CHARACTER HUD (Bottom Right) ----
const uiX = width - 180;
const uiY = hudSafeY - 90;
// Character Name
ctx.font = 'bold 28px "Palatino Linotype", "Book Antiqua", Palatino, serif';
ctx.textAlign = 'center';
ctx.fillStyle = '#ffffff';
ctx.shadowColor = 'black';
ctx.shadowBlur = 5;
ctx.fillText(characterName.toUpperCase(), uiX, uiY + 80);
ctx.shadowColor = 'transparent';
// HUD Bars Math (wrapping around top of portrait)
const startAngle = 0.8 * Math.PI;
const maxEnd = 2.2 * Math.PI;
const span = maxEnd - startAngle;
// HP Bar (SVTFOE bright green to pinkish hue)
const hpEnd = startAngle + (span * 0.85); // 85% HP
ctx.lineCap = 'round';
// Background HP track
ctx.beginPath();
ctx.arc(uiX, uiY, 70, startAngle, maxEnd, false);
ctx.strokeStyle = 'rgba(0, 50, 0, 0.6)';
ctx.lineWidth = 18;
ctx.stroke();
// Foreground HP track
ctx.beginPath();
ctx.arc(uiX, uiY, 70, startAngle, hpEnd, false);
ctx.strokeStyle = '#00ff66';
ctx.stroke();
// MP Bar (bright blue track inside)
const mpEnd = startAngle + (span * 0.45); // 45% MP
ctx.beginPath();
ctx.arc(uiX, uiY, 54, startAngle, maxEnd, false);
ctx.strokeStyle = 'rgba(0, 0, 50, 0.6)';
ctx.lineWidth = 10;
ctx.stroke();
ctx.beginPath();
ctx.arc(uiX, uiY, 54, startAngle, mpEnd, false);
ctx.strokeStyle = '#00ccff';
ctx.stroke();
// Portrait Frame Backing
ctx.beginPath();
ctx.arc(uiX, uiY, 45, 0, Math.PI * 2);
ctx.fillStyle = 'rgba(0, 0, 0, 0.7)';
ctx.fill();
ctx.lineWidth = 4;
ctx.strokeStyle = 'gold';
ctx.stroke();
// Draw stylized SVTFOE Star inside portrait as fallback rendering
function drawStarHelper(cx, cy, spikes, outerRadius, innerRadius) {
let rot = Math.PI / 2 * 3;
let x = cx;
let y = cy;
let step = Math.PI / spikes;
ctx.beginPath();
ctx.moveTo(cx, cy - outerRadius);
for(let i = 0; i < spikes; i++) {
x = cx + Math.cos(rot) * outerRadius;
y = cy + Math.sin(rot) * outerRadius;
ctx.lineTo(x, y);
rot += step;
x = cx + Math.cos(rot) * innerRadius;
y = cy + Math.sin(rot) * innerRadius;
ctx.lineTo(x, y);
rot += step;
}
ctx.lineTo(cx, cy - outerRadius);
ctx.closePath();
}
ctx.fillStyle = '#ff99cc';
drawStarHelper(uiX, uiY, 5, 25, 12);
ctx.fill();
ctx.lineWidth = 2;
ctx.strokeStyle = '#fff';
ctx.stroke();
// 3. YouTube/Video Player Interface Overlay
// Top gradient & video title
const topGradient = ctx.createLinearGradient(0, 0, 0, 80);
topGradient.addColorStop(0, 'rgba(0,0,0,0.8)');
topGradient.addColorStop(1, 'rgba(0,0,0,0)');
ctx.fillStyle = topGradient;
ctx.fillRect(0, 0, width, 80);
ctx.fillStyle = '#ffffff';
ctx.font = 'bold 22px Arial, sans-serif';
ctx.textAlign = 'left';
ctx.shadowColor = 'black';
ctx.shadowBlur = 3;
ctx.fillText("Kingdom Hearts x SVTFOE Mod [HD Gameplay]", 30, 40);
ctx.shadowColor = 'transparent';
// Bottom gradient for scrubber
const bottomGradient = ctx.createLinearGradient(0, height - 90, 0, height);
bottomGradient.addColorStop(0, 'rgba(0,0,0,0)');
bottomGradient.addColorStop(1, 'rgba(0,0,0,0.85)');
ctx.fillStyle = bottomGradient;
ctx.fillRect(0, height - 90, width, 90);
// Progress Bar Track
const barX = 25;
const barW = width - 50;
const barY = height - 45;
ctx.fillStyle = 'rgba(255, 255, 255, 0.3)';
ctx.fillRect(barX, barY, barW, 6);
// Progress Bar Active
const progVal = Math.min(Math.max(Number(progressPercent) || 42, 0), 100) / 100;
ctx.fillStyle = '#ff0000'; // Standard video player red
ctx.fillRect(barX, barY, barW * progVal, 6);
// Scrubber Knob
ctx.beginPath();
ctx.arc(barX + (barW * progVal), barY + 3, 7, 0, Math.PI * 2);
ctx.fillStyle = '#ff0000';
ctx.fill();
// Play/Pause / Volume / Times
ctx.fillStyle = '#ffffff';
// Play triangle
ctx.beginPath();
ctx.moveTo(35, height - 25);
ctx.lineTo(48, height - 17);
ctx.lineTo(35, height - 9);
ctx.fill();
ctx.font = '14px Arial, sans-serif';
ctx.fillText(videoTime, 65, height - 12);
// Fake fullscreen icon (bottom right corner)
ctx.strokeRect(width - 45, height - 25, 16, 12);
return canvas;
}
Apply Changes