You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(
originalImg,
leftTint = "rgba(0, 120, 255, 0.3)",
rightTint = "rgba(255, 20, 50, 0.3)",
vsText = "VS",
splitSlant = "0.08"
) {
const canvas = document.createElement("canvas");
const origW = originalImg.width;
const origH = originalImg.height;
// Double the width to put original and "enemy" side by side
const w = origW * 2;
const h = origH;
canvas.width = w;
canvas.height = h;
const ctx = canvas.getContext("2d");
// Offset for the slanted split
const slant = parseFloat(splitSlant) || 0.08;
const offset = w * slant;
// Scale the image slightly to ensure it completely covers the slanted area
const scale = (w / 2 + offset) / (w / 2);
const imgDrawW = origW * scale;
const imgDrawH = origH * scale;
// Center vertical offset for the slight scale adjustment
const dy = (h - imgDrawH) / 2;
// --- LEFT SIDE (Hero) ---
ctx.save();
ctx.beginPath();
ctx.moveTo(0, 0);
ctx.lineTo(w / 2 + offset, 0);
ctx.lineTo(w / 2 - offset, h);
ctx.lineTo(0, h);
ctx.closePath();
ctx.clip(); // Restrict drawing to the left polygon
ctx.drawImage(originalImg, 0, dy, imgDrawW, imgDrawH);
// Apply Left Tint
ctx.fillStyle = leftTint;
ctx.fill();
ctx.restore();
// --- RIGHT SIDE (Nemesis) ---
ctx.save();
ctx.beginPath();
ctx.moveTo(w / 2 + offset, 0);
ctx.lineTo(w, 0);
ctx.lineTo(w, h);
ctx.lineTo(w / 2 - offset, h);
ctx.closePath();
ctx.clip(); // Restrict drawing to the right polygon
// Flip horizontally to create the 'nemesis' effect
ctx.translate(w, 0);
ctx.scale(-1, 1);
// Draw flipped original image
ctx.drawImage(originalImg, 0, dy, imgDrawW, imgDrawH);
// Reset transform to fill the path in global coordinates
ctx.setTransform(1, 0, 0, 1, 0, 0);
ctx.fillStyle = rightTint;
ctx.fill();
ctx.restore();
// --- CENTRAL DIVIDER LINE ---
ctx.beginPath();
ctx.moveTo(w / 2 + offset, 0);
ctx.lineTo(w / 2 - offset, h);
const baseLineWidth = Math.max(w * 0.005, 3);
// Outer glow/shadow for divider
ctx.lineWidth = baseLineWidth * 3;
ctx.strokeStyle = "rgba(0, 0, 0, 0.7)";
ctx.stroke();
// Inner bright line
ctx.lineWidth = baseLineWidth;
ctx.strokeStyle = "#ffffff";
ctx.stroke();
// --- CINEMATIC VIGNETTE ---
const cx = w / 2;
const cy = h / 2;
const radius = Math.sqrt(w * w + h * h) / 2;
const vignette = ctx.createRadialGradient(cx, cy, radius * 0.3, cx, cy, radius);
vignette.addColorStop(0, "rgba(0,0,0,0)");
vignette.addColorStop(1, "rgba(0,0,0,0.85)");
ctx.fillStyle = vignette;
ctx.fillRect(0, 0, w, h);
// --- VS BADGE ---
const vsRadius = Math.min(w, h) * 0.12;
// Dark backdrop for VS text
ctx.beginPath();
ctx.arc(cx, cy, vsRadius, 0, Math.PI * 2);
ctx.fillStyle = "#111111";
ctx.fill();
// Thick badge border
ctx.lineWidth = baseLineWidth * 1.5;
ctx.strokeStyle = "#ffffff";
ctx.stroke();
// Inner thin border detail
const innerRadius = vsRadius * 0.85;
ctx.beginPath();
ctx.arc(cx, cy, innerRadius, 0, Math.PI * 2);
ctx.strokeStyle = "#888888";
ctx.lineWidth = baseLineWidth * 0.5;
ctx.stroke();
// --- VS TEXT ---
ctx.fillStyle = "white";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
const fontSize = vsRadius * 0.9;
ctx.font = `italic bold ${fontSize}px Impact, "Arial Black", sans-serif`;
// Drop shadow for the text
ctx.shadowColor = "rgba(0, 0, 0, 0.9)";
ctx.shadowOffsetX = 4;
ctx.shadowOffsetY = 4;
ctx.shadowBlur = 5;
// Fiery gradient for "VS" intensity
const textGrad = ctx.createLinearGradient(cx, cy - vsRadius, cx, cy + vsRadius);
textGrad.addColorStop(0, "#FFD700"); // Gold
textGrad.addColorStop(1, "#FF4500"); // Red-Orange
ctx.fillStyle = textGrad;
// Slight visual Y-shift correction since Impact is top-heavy
ctx.fillText(vsText.toString(), cx, cy + vsRadius * 0.05);
ctx.shadowColor = "transparent";
return canvas;
}
Apply Changes