You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, supportText = "МЫ С ТОБОЙ! / WE SUPPORT YOU!", numSupporters = "5", bgColor = "#f0f8ff") {
// Create the canvas element
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// Parse parameters
let count = parseInt(numSupporters, 10);
if (isNaN(count) || count < 1) count = 5;
if (count > 50) count = 50; // Performance & visual cap
const imgW = originalImg.width;
const imgH = originalImg.height;
// Use a reference width to scale drawn elements proportionately with the original image size
const refWidth = Math.max(imgW, 400);
const s = refWidth / 800; // global scale multiplier based on 800px base width
// Padding calculations
const padX = 100 * s;
const padTop = 150 * s;
const padBottom = 200 * s;
// Set canvas dimensions
canvas.width = imgW + padX * 2;
canvas.height = imgH + padTop + padBottom;
// Fill the background
ctx.fillStyle = bgColor;
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Draw motivational header text
ctx.fillStyle = "#333333";
ctx.font = "bold " + (50 * s) + "px sans-serif";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText(supportText, canvas.width / 2, padTop / 2.5);
// Draw subtitle "Support Group"
ctx.font = "italic " + (22 * s) + "px sans-serif";
ctx.fillStyle = "#666666";
ctx.fillText("Группа поддержки", canvas.width / 2, padTop / 2.5 + (45 * s));
// Draw the image "block" with a realistic drop shadow to look heavy
ctx.save();
ctx.shadowColor = 'rgba(0, 0, 0, 0.4)';
ctx.shadowBlur = 20 * s;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 15 * s;
ctx.drawImage(originalImg, padX, padTop, imgW, imgH);
ctx.restore();
// Add a solid stroke around the image framing
ctx.strokeStyle = "#222222";
ctx.lineWidth = Math.max(3 * s, 1);
ctx.strokeRect(padX, padTop, imgW, imgH);
// Variables for drawing the stick figure "supporters"
const bottomOfImage = padTop + imgH;
const spacing = imgW / (count + 1);
ctx.lineCap = "round";
ctx.lineJoin = "round";
// Scale body sizes
const headR = 15 * s;
const bodyL = 40 * s;
const legL = 30 * s;
const armReach = bottomOfImage;
// Iterate and draw each stick figure pushing up on the bottom edge of the image
for (let i = 1; i <= count; i++) {
const cx = padX + i * spacing;
const baseY = bottomOfImage + (40 * s) + headR;
// Draw solid head background
ctx.fillStyle = "#ffffff";
ctx.strokeStyle = "#333333";
ctx.lineWidth = Math.max(4 * s, 1);
ctx.beginPath();
ctx.arc(cx, baseY, headR, 0, Math.PI * 2);
ctx.fill();
ctx.stroke();
// Draw straining face to indicate heavy weight support ( > < )
ctx.lineWidth = Math.max(2 * s, 1);
ctx.beginPath();
// Left eye
ctx.moveTo(cx - 7 * s, baseY - 4 * s);
ctx.lineTo(cx - 3 * s, baseY - 1 * s);
ctx.lineTo(cx - 7 * s, baseY + 2 * s);
// Right eye
ctx.moveTo(cx + 7 * s, baseY - 4 * s);
ctx.lineTo(cx + 3 * s, baseY - 1 * s);
ctx.lineTo(cx + 7 * s, baseY + 2 * s);
ctx.stroke();
// Gritted mouth
ctx.beginPath();
ctx.moveTo(cx - 5 * s, baseY + 7 * s);
ctx.lineTo(cx + 5 * s, baseY + 7 * s);
ctx.stroke();
// Straining body
ctx.lineWidth = Math.max(4 * s, 1);
const bodyStartY = baseY + headR;
const bodyEndY = bodyStartY + bodyL;
ctx.beginPath();
ctx.moveTo(cx, bodyStartY);
ctx.lineTo(cx, bodyEndY);
ctx.stroke();
// Straining bent legs
ctx.beginPath();
// Left leg
ctx.moveTo(cx, bodyEndY);
ctx.lineTo(cx - 15 * s, bodyEndY + (legL * 0.5));
ctx.lineTo(cx - 20 * s, bodyEndY + legL);
// Right leg
ctx.moveTo(cx, bodyEndY);
ctx.lineTo(cx + 15 * s, bodyEndY + (legL * 0.5));
ctx.lineTo(cx + 20 * s, bodyEndY + legL);
ctx.stroke();
// Arms reaching up to support the frame physically
const armStartY = bodyStartY + 5 * s;
ctx.beginPath();
ctx.moveTo(cx, armStartY);
ctx.lineTo(cx - 18 * s, armReach); // Left hand
ctx.stroke();
ctx.beginPath();
ctx.moveTo(cx, armStartY);
ctx.lineTo(cx + 18 * s, armReach); // Right hand
ctx.stroke();
// Draw a sweat drop by their head to show effort from supporting
ctx.fillStyle = "#87CEFA";
const sweatX = cx + headR + 4 * s;
const sweatY = baseY - 6 * s;
const sweatR = 3 * s;
ctx.beginPath();
// Bottom half of sweat tear
ctx.arc(sweatX, sweatY, sweatR, 0, Math.PI);
// Tip of the tear
ctx.lineTo(sweatX, sweatY - sweatR * 2.5);
ctx.closePath();
ctx.fill();
}
return canvas;
}
Apply Changes