You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(
originalImg,
title = "The Lion King Hamtaro Character Role Swap",
role1 = "Boss (Hamtaro) as Mufasa",
role2 = "Hamtaro as Young Simba",
role3 = "Bljou (Hamtaro) as Young Nala"
) {
const canvas = document.createElement('canvas');
const width = 1200;
const height = 580; // 80px header + 400px image + 100px footer
canvas.width = width;
canvas.height = height;
const ctx = canvas.getContext('2d');
// 1. Draw Cinematic Background
ctx.fillStyle = '#111111';
ctx.fillRect(0, 0, width, height);
// 2. Draw Main Header Title
ctx.fillStyle = '#FFD700'; // Gold
ctx.font = 'bold 36px Impact, sans-serif';
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText(title, width / 2, 40);
// Helper: Draw image acting like CSS 'object-fit: cover'
function drawCover(context, img, dx, dy, dw, dh) {
const imgRatio = img.width / img.height;
const ctxRatio = dw / dh;
let sx, sy, sw, sh;
if (imgRatio > ctxRatio) {
sh = img.height;
sw = img.height * ctxRatio;
sx = (img.width - sw) / 2;
sy = 0;
} else {
sw = img.width;
sh = img.width / ctxRatio;
sx = 0;
sy = (img.height - sh) / 2;
}
context.drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh);
}
const panelW = 400;
const panelH = 400;
const startY = 80;
// 3. Process each section via Loop
for (let i = 0; i < 3; i++) {
const startX = i * panelW;
const cx = startX + panelW / 2; // Center X of panel
const cy = startY + panelH / 2; // Center Y of panel
const faceR = 90; // Face mask mapping radius
// Draw the uploaded image covering the panel
drawCover(ctx, originalImg, startX, startY, panelW, panelH);
// Apply a vignette for a dramatic look & clearer overlays
const vignette = ctx.createRadialGradient(cx, cy, 60, cx, cy, 250);
vignette.addColorStop(0, 'rgba(0,0,0, 0.1)');
vignette.addColorStop(1, 'rgba(0,0,0, 0.7)');
ctx.fillStyle = vignette;
ctx.fillRect(startX, startY, panelW, panelH);
// 4. Draw Custom Drawn Animal Features per Character Swap Overlay Filters
if (i === 0) {
// Boss as Mufasa
// Mufasa Mane (Outer layer)
ctx.fillStyle = '#4A2511';
for (let a = 0; a < Math.PI * 2; a += Math.PI / 8) {
ctx.beginPath();
ctx.arc(cx + Math.cos(a) * (faceR + 30), cy + Math.sin(a) * (faceR + 30), 55, 0, Math.PI * 2);
ctx.fill();
}
// Mufasa Mane (Inner layer)
ctx.fillStyle = '#8B4513';
for (let a = 0; a < Math.PI * 2; a += Math.PI / 6) {
ctx.beginPath();
ctx.arc(cx + Math.cos(a) * (faceR + 15), cy + Math.sin(a) * (faceR + 15), 45, 0, Math.PI * 2);
ctx.fill();
}
// Boss's simple round ears
ctx.fillStyle = '#6B4A33';
ctx.beginPath();
ctx.arc(cx - 65, cy - faceR + 10, 25, 0, Math.PI * 2);
ctx.arc(cx + 65, cy - faceR + 10, 25, 0, Math.PI * 2);
ctx.fill();
} else if (i === 1) {
// Hamtaro as Young Simba
// Simba's small hair tuft
ctx.fillStyle = '#CC3300';
ctx.beginPath();
ctx.moveTo(cx - 30, cy - faceR + 20);
ctx.lineTo(cx, cy - faceR - 40);
ctx.lineTo(cx + 30, cy - faceR + 20);
ctx.fill();
// Hamtaro's distinct orange fur patch outline (transparent overlay)
ctx.fillStyle = 'rgba(255, 165, 0, 0.35)'; // Orange tint over forehead area
ctx.beginPath();
ctx.arc(cx, cy, faceR, Math.PI, 2 * Math.PI);
ctx.fill();
// Outer Orange Hamtaro Ears
ctx.fillStyle = '#FFA500';
ctx.beginPath();
ctx.arc(cx - 70, cy - faceR + 25, 30, 0, Math.PI * 2);
ctx.arc(cx + 70, cy - faceR + 25, 30, 0, Math.PI * 2);
ctx.fill();
// Inner Pink Ear
ctx.fillStyle = '#FFC0CB';
ctx.beginPath();
ctx.arc(cx - 70, cy - faceR + 25, 15, 0, Math.PI * 2);
ctx.arc(cx + 70, cy - faceR + 25, 15, 0, Math.PI * 2);
ctx.fill();
} else if (i === 2) {
// Bljou (Hamtaro) as Young Nala
// Brighten forehead to mimic white fur / Nala tone
ctx.fillStyle = 'rgba(255, 255, 255, 0.3)';
ctx.beginPath();
ctx.arc(cx, cy, faceR, 0, 2 * Math.PI);
ctx.fill();
// Bijou's White Ears
ctx.fillStyle = '#FFFFFF';
ctx.beginPath();
ctx.arc(cx - 70, cy - faceR + 25, 30, 0, Math.PI * 2);
ctx.arc(cx + 70, cy - faceR + 25, 30, 0, Math.PI * 2);
ctx.fill();
// Pink Inner Ear
ctx.fillStyle = '#FFC0CB';
ctx.beginPath();
ctx.arc(cx - 70, cy - faceR + 25, 15, 0, Math.PI * 2);
ctx.arc(cx + 70, cy - faceR + 25, 15, 0, Math.PI * 2);
ctx.fill();
// Bijou's Blue Ribbons
ctx.fillStyle = '#1E90FF'; // DodgerBlue
// Left Ribbon
ctx.fillRect(cx - 80, cy - faceR - 5, 20, 20); // Central knot
ctx.beginPath(); ctx.moveTo(cx - 80, cy - faceR + 5); ctx.lineTo(cx - 115, cy - faceR - 20); ctx.lineTo(cx - 100, cy - faceR + 25); ctx.fill();
ctx.beginPath(); ctx.moveTo(cx - 60, cy - faceR + 5); ctx.lineTo(cx - 25, cy - faceR - 20); ctx.lineTo(cx - 40, cy - faceR + 25); ctx.fill();
// Right Ribbon
ctx.fillRect(cx + 60, cy - faceR - 5, 20, 20); // Central knot
ctx.beginPath(); ctx.moveTo(cx + 60, cy - faceR + 5); ctx.lineTo(cx + 25, cy - faceR - 20); ctx.lineTo(cx + 40, cy - faceR + 25); ctx.fill();
ctx.beginPath(); ctx.moveTo(cx + 80, cy - faceR + 5); ctx.lineTo(cx + 115, cy - faceR - 20); ctx.lineTo(cx + 100, cy - faceR + 25); ctx.fill();
}
// Apply Kawaii Blush cheeks for all characters to unify the Hamtaro aesthetic
ctx.fillStyle = 'rgba(255, 105, 180, 0.6)'; // Hot pink
ctx.beginPath();
ctx.ellipse(cx - 50, cy + 30, 20, 12, 0, 0, Math.PI * 2);
ctx.ellipse(cx + 50, cy + 30, 20, 12, 0, 0, Math.PI * 2);
ctx.fill();
// Emphasized Panel Border
ctx.lineWidth = 4;
ctx.strokeStyle = '#FFD700';
ctx.strokeRect(startX, startY, panelW, panelH);
// 5. Draw Target Role Texts Bottom Banner
let roleOverlayText = i === 0 ? role1 : (i === 1 ? role2 : role3);
ctx.fillStyle = '#FFFFFF';
ctx.font = '22px Arial, sans-serif'; // Clean, universally readable standard system font fallback
ctx.fillText(roleOverlayText, cx, startY + panelH + 50);
}
return canvas;
}
Apply Changes