You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(
originalImg,
title = "Овощные соревнования",
subtitle = "ПОБЕДИТЕЛЬ ВЫСТАВКИ!",
themeColor = "#2E7D32",
emojis = "🍅,🥒,🥕,🥔,🎃,🥦,🧅"
) {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// Constrain the image size to avoid out-of-memory errors on massive uploads
const maxImgSize = 700;
let scale = 1;
if (originalImg.width > maxImgSize || originalImg.height > maxImgSize) {
scale = Math.min(maxImgSize / originalImg.width, maxImgSize / originalImg.height);
}
const imgW = Math.round(originalImg.width * scale);
const imgH = Math.round(originalImg.height * scale);
// Padding around the image to create the certificate frame
const padX = 100;
const topPad = 130;
const botPad = 180;
canvas.width = imgW + padX * 2;
canvas.height = imgH + topPad + botPad;
// 1. Draw Paper Background
ctx.fillStyle = '#FFFDF5'; // Warm paper hue
ctx.fillRect(0, 0, canvas.width, canvas.height);
// 2. Draw Decorative Borders
ctx.strokeStyle = themeColor;
ctx.lineWidth = 12;
ctx.strokeRect(20, 20, canvas.width - 40, canvas.height - 40);
ctx.strokeStyle = "#F9A825"; // Inner Gold Border
ctx.lineWidth = 4;
ctx.strokeRect(38, 38, canvas.width - 76, canvas.height - 76);
// 3. Draw Title Text
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillStyle = themeColor;
ctx.font = "bold 44px 'Trebuchet MS', 'Lucida Sans Unicode', 'Lucida Grande', 'Lucida Sans', Arial, sans-serif";
ctx.fillText(title, canvas.width / 2, 75);
// 4. Draw Main Image with a nice drop shadow
ctx.shadowColor = "rgba(0, 0, 0, 0.4)";
ctx.shadowBlur = 20;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 10;
ctx.drawImage(originalImg, padX, topPad, imgW, imgH);
// Reset shadow for the frame
ctx.shadowColor = "transparent";
ctx.shadowBlur = 0;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
// Image Frame Lines (Polaroid-like border base)
ctx.strokeStyle = "#FFFFFF";
ctx.lineWidth = 10;
ctx.strokeRect(padX - 5, topPad - 5, imgW + 10, imgH + 10);
ctx.strokeStyle = "#E0E0E0";
ctx.lineWidth = 1;
ctx.strokeRect(padX - 10, topPad - 10, imgW + 20, imgH + 20);
// 5. Draw Subtitle (Winner Declaration)
ctx.fillStyle = "#C62828"; // Deep red for emphasis
ctx.font = "bold 40px 'Trebuchet MS', Arial, sans-serif";
ctx.fillText(subtitle, canvas.width / 2, topPad + imgH + 70);
// 6. Draw Vegetable Emojis along the bottom border
const emojiArr = emojis.split(',').map(e => e.trim()).filter(e => e.length > 0);
if (emojiArr.length > 0) {
ctx.font = "45px sans-serif";
const totalSpace = canvas.width - 120; // 60px padding on each side
const spacing = totalSpace / (emojiArr.length - 1 || 1);
for (let i = 0; i < emojiArr.length; i++) {
const ex = emojiArr.length === 1 ? canvas.width / 2 : 60 + i * spacing;
ctx.fillText(emojiArr[i], ex, canvas.height - 65);
}
}
// 7. Helper to draw a "1st Place" Rosette / Ribbon
const drawRosette = (x, y) => {
// Drop shadow for the entire rosette and tails
ctx.shadowColor = "rgba(0, 0, 0, 0.5)";
ctx.shadowBlur = 10;
ctx.shadowOffsetY = 5;
// Ribbon Tails
ctx.fillStyle = "#C62828";
ctx.beginPath();
ctx.moveTo(x - 15, y);
ctx.lineTo(x - 35, y + 95);
ctx.lineTo(x, y + 75);
ctx.lineTo(x + 35, y + 95);
ctx.lineTo(x + 15, y);
ctx.closePath();
ctx.fill();
// Outer Wavy Circle (Gold)
ctx.fillStyle = "#FBC02D";
ctx.beginPath();
for (let i = 0; i < 28; i++) {
const angle = (i / 28) * Math.PI * 2;
const r = (i % 2 === 0) ? 55 : 42;
const px = x + Math.cos(angle) * r;
const py = y + Math.sin(angle) * r;
if (i === 0) ctx.moveTo(px, py);
else ctx.lineTo(px, py);
}
ctx.closePath();
ctx.fill();
ctx.strokeStyle = "#F57F17"; // Darker gold outline
ctx.lineWidth = 3;
ctx.stroke();
// Reset shadow to avoid blurring the text/inner elements
ctx.shadowColor = "transparent";
ctx.shadowBlur = 0;
ctx.shadowOffsetY = 0;
// Inner Circle (White)
ctx.fillStyle = "#FFFFFF";
ctx.beginPath();
ctx.arc(x, y, 26, 0, Math.PI * 2);
ctx.fill();
ctx.stroke();
// Rosette Text
ctx.fillStyle = "#C62828";
ctx.font = "bold 30px sans-serif";
ctx.fillText("1", x, y + 3);
};
// Draw the rosette at the bottom-right corner of the image
drawRosette(padX + imgW, topPad + imgH);
return canvas;
}
Apply Changes