You can edit the below JavaScript code to customize the image tool.
Apply Changes
async function processImage(originalImg, secondImgUrl = '', layout = 'horizontal', vsTextColor = '#ffffff', vsBgColor = '#e74c3c') {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// Attempt to load the second image from URL, if provided.
// If not provided or fails, it will fall back to the original image.
let img2 = originalImg;
if (secondImgUrl.trim() !== '') {
try {
img2 = await new Promise((resolve, reject) => {
const img = new Image();
img.crossOrigin = "Anonymous";
img.onload = () => resolve(img);
img.onerror = () => resolve(originalImg);
img.src = secondImgUrl;
});
} catch (e) {
img2 = originalImg;
}
}
// Determine layout dimensions based on the original image to maintain high quality.
const partWidth = originalImg.width;
const partHeight = originalImg.height;
if (layout === 'vertical') {
canvas.width = partWidth;
canvas.height = partHeight * 2;
} else { // default to horizontal
canvas.width = partWidth * 2;
canvas.height = partHeight;
}
// Helper function to draw an image covering a specific rectangular area (object-fit: cover)
function drawImageCover(img, x, y, w, h) {
const scale = Math.max(w / img.width, h / img.height);
const drawW = img.width * scale;
const drawH = img.height * scale;
const drawX = x + (w - drawW) / 2;
const drawY = y + (h - drawH) / 2;
ctx.save();
ctx.beginPath();
ctx.rect(x, y, w, h);
ctx.clip();
ctx.drawImage(img, drawX, drawY, drawW, drawH);
ctx.restore();
}
// Draw both images onto their respective halves
if (layout === 'vertical') {
drawImageCover(originalImg, 0, 0, partWidth, partHeight);
drawImageCover(img2, 0, partHeight, partWidth, partHeight);
} else {
drawImageCover(originalImg, 0, 0, partWidth, partHeight);
drawImageCover(img2, partWidth, 0, partWidth, partHeight);
}
// Setup visual styling for graphic elements
const smallerDimension = Math.min(canvas.width, canvas.height);
const dividerSize = Math.max(smallerDimension * 0.01, 2);
const badgeRadius = Math.max(smallerDimension * 0.08, 15);
const centerX = canvas.width / 2;
const centerY = canvas.height / 2;
// Add drop shadow for the VS badge and divider
ctx.shadowColor = 'rgba(0, 0, 0, 0.6)';
ctx.shadowBlur = Math.max(smallerDimension * 0.02, 5);
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = Math.max(smallerDimension * 0.005, 2);
// Draw dividing line
ctx.fillStyle = vsBgColor;
if (layout === 'vertical') {
ctx.fillRect(0, partHeight - dividerSize / 2, canvas.width, dividerSize);
} else {
ctx.fillRect(partWidth - dividerSize / 2, 0, dividerSize, canvas.height);
}
// Draw VS Badge background
ctx.beginPath();
ctx.arc(centerX, centerY, badgeRadius, 0, 2 * Math.PI);
ctx.fillStyle = vsBgColor;
ctx.fill();
// Reset shadow before drawing stroke and text to keep them sharp
ctx.shadowColor = 'transparent';
ctx.shadowBlur = 0;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
// Badge border lines
ctx.lineWidth = Math.max(dividerSize * 0.8, 1);
ctx.strokeStyle = vsTextColor;
ctx.stroke();
ctx.beginPath();
ctx.arc(centerX, centerY, badgeRadius * 0.88, 0, 2 * Math.PI);
ctx.lineWidth = Math.max(dividerSize * 0.2, 1);
ctx.strokeStyle = vsBgColor;
ctx.stroke();
// Draw "VS" Text
ctx.fillStyle = vsTextColor;
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
// Choose a heavy, impact-style font
let fontSize = badgeRadius * 0.9;
ctx.font = `italic bold ${fontSize}px "Impact", "Arial Black", sans-serif`;
// Handle slight optic visual alignment offset for most fonts
ctx.fillText('VS', centerX, centerY + (fontSize * 0.05));
return canvas;
}
Apply Changes