You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, customText = "ВЕСЁЛЫЙ УЧИТЕЛЬ!", faceScale = "1", offsetX = "0", offsetY = "0") {
// Create the canvas and set up dimensions
const canvas = document.createElement('canvas');
canvas.width = 600;
canvas.height = 600;
const ctx = canvas.getContext('2d');
// 1. Draw Chalkboard Background
ctx.fillStyle = '#2c5e3b'; // Teacher's chalkboard green
ctx.fillRect(0, 0, canvas.width, canvas.height);
// Board wood frame
ctx.strokeStyle = '#8b5a2b';
ctx.lineWidth = 20;
ctx.strokeRect(10, 10, 580, 580);
// Draw an eraser and chalk resting on the frame bottom
ctx.fillStyle = '#eee';
ctx.fillRect(100, 575, 30, 8); // chalk
ctx.fillStyle = '#aa6633';
ctx.fillRect(150, 570, 50, 15); // eraser wood
ctx.fillStyle = '#444';
ctx.fillRect(150, 580, 50, 5); // eraser felt
// 2. Draw Chalkboard Text
ctx.fillStyle = '#ffffff';
ctx.font = 'bold 42px "Comic Sans MS", "Chalkboard SE", sans-serif';
ctx.textAlign = 'center';
// Slight shadow for realism
ctx.shadowColor = "rgba(0, 0, 0, 0.4)";
ctx.shadowBlur = 4;
ctx.shadowOffsetX = 2;
ctx.shadowOffsetY = 2;
ctx.fillText(customText, 300, 80);
// Reset shadow
ctx.shadowColor = "transparent";
ctx.shadowBlur = 0;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
// Center coordinates for our Shuttlecock Teacher
const centerX = 300;
const centerY = 410; // Face placement
// 3. Draw Legs & Arms (Back layer)
ctx.lineCap = 'round';
ctx.lineJoin = 'round';
// Left leg
ctx.beginPath();
ctx.moveTo(270, centerY + 60);
ctx.lineTo(270, centerY + 130);
ctx.lineTo(250, centerY + 130); // foot
ctx.lineWidth = 8;
ctx.strokeStyle = '#ffffff';
ctx.stroke();
// Right leg
ctx.beginPath();
ctx.moveTo(330, centerY + 60);
ctx.lineTo(330, centerY + 130);
ctx.lineTo(350, centerY + 130); // foot
ctx.stroke();
// Left arm (holds a pointer stick)
ctx.beginPath();
ctx.moveTo(235, centerY);
ctx.lineTo(170, centerY + 40); // elbow
ctx.lineTo(140, centerY + 10); // hand
ctx.stroke();
// The Pointer
ctx.beginPath();
ctx.moveTo(140, centerY + 20);
ctx.lineTo(60, 200); // pointing up at the text
ctx.lineWidth = 5;
ctx.strokeStyle = '#d4a373'; // wood pointer color
ctx.stroke();
// Right arm (holds a book)
ctx.beginPath();
ctx.moveTo(365, centerY);
ctx.lineTo(430, centerY + 40); // elbow
ctx.lineTo(400, centerY + 70); // hand
ctx.lineWidth = 8;
ctx.strokeStyle = '#ffffff';
ctx.stroke();
// The Book
ctx.fillStyle = '#b71c1c'; // Red cover
ctx.fillRect(370, centerY + 50, 45, 60);
ctx.fillStyle = '#ffffff'; // Pages
ctx.fillRect(375, centerY + 55, 35, 50);
// Quick lines for text inside the book
ctx.beginPath();
ctx.moveTo(380, centerY + 65); ctx.lineTo(405, centerY + 65);
ctx.moveTo(380, centerY + 75); ctx.lineTo(405, centerY + 75);
ctx.moveTo(380, centerY + 85); ctx.lineTo(405, centerY + 85);
ctx.lineWidth = 3;
ctx.strokeStyle = '#555';
ctx.stroke();
// 4. Draw Shuttlecock Skirt (Feathers structure)
const skirtTopY = 160;
const skirtBottomY = 385;
const topWidth = 180; // Distance from center to outer edge at top
const botWidth = 60; // Distance from center to outer edge at bottom
ctx.save();
ctx.beginPath();
ctx.moveTo(centerX - botWidth, skirtBottomY);
ctx.lineTo(centerX - topWidth, skirtTopY);
// Quadratic curve for the top rim
ctx.quadraticCurveTo(centerX, skirtTopY - 40, centerX + topWidth, skirtTopY);
ctx.lineTo(centerX + botWidth, skirtBottomY);
ctx.closePath();
// Make skirt translucent white to look like plastic/feathers
ctx.fillStyle = 'rgba(255, 255, 255, 0.85)';
ctx.fill();
ctx.lineWidth = 5;
ctx.strokeStyle = '#e0e0e0';
ctx.stroke();
// Draw the ribs (feathers)
ctx.lineWidth = 3;
ctx.strokeStyle = '#cccccc';
const numRibs = 10;
for (let i = 0; i <= numRibs; i++) {
let t = i / numRibs;
let bX = centerX - botWidth + (t * botWidth * 2);
let bY = skirtBottomY;
let tX = centerX - topWidth + (t * topWidth * 2);
// Calculate curve Y for the top point
let oneMinusT = 1 - t;
let tY = (Math.pow(oneMinusT, 2) * skirtTopY) +
(2 * oneMinusT * t * (skirtTopY - 40)) +
(Math.pow(t, 2) * skirtTopY);
ctx.beginPath();
ctx.moveTo(bX, bY);
ctx.lineTo(tX, tY);
ctx.stroke();
}
// Horizontal string wraps holding feathers together
ctx.strokeStyle = '#0288d1'; // Blue string accents are common
ctx.lineWidth = 4;
for (let j = 1; j <= 2; j++) {
let jt = j / 3;
let pY = skirtBottomY + jt * (skirtTopY - skirtBottomY);
let currentWidthHalf = botWidth + jt * (topWidth - botWidth);
ctx.beginPath();
ctx.moveTo(centerX - currentWidthHalf, pY);
ctx.quadraticCurveTo(centerX, pY - 20, centerX + currentWidthHalf, pY);
ctx.stroke();
}
ctx.restore();
// 5. Draw the Face (Cork Base)
// Setup user face constraints
const scale = parseFloat(faceScale) || 1;
const dx = parseFloat(offsetX) || 0;
const dy = parseFloat(offsetY) || 0;
const faceRadius = 70;
// Save context for clipping the image into a circle
ctx.save();
ctx.beginPath();
ctx.arc(centerX, centerY, faceRadius, 0, Math.PI * 2);
ctx.closePath();
ctx.fillStyle = '#ffeedd'; // Fallback base color
ctx.fill();
ctx.clip(); // Mask applied
// Scale and position the original image to fill the circle area
const targetDiameter = faceRadius * 2;
let minRatio = Math.max(targetDiameter / originalImg.width, targetDiameter / originalImg.height);
let drawW = originalImg.width * minRatio * scale;
let drawH = originalImg.height * minRatio * scale;
const imgCx = centerX + dx;
const imgCy = centerY + dy;
try {
ctx.drawImage(originalImg, imgCx - drawW / 2, imgCy - drawH / 2, drawW, drawH);
} catch(e) {
// Fallback if image fails to render
console.warn("Could not draw original image.", e);
}
ctx.restore();
// 6. Draw Outline & Red Ribbon Tape (to bind the Cork and Skirt nicely)
// Red ribbon
ctx.beginPath();
ctx.rect(centerX - 62, skirtBottomY - 10, 124, 15);
ctx.fillStyle = '#d32f2f'; // Tape red
ctx.fill();
ctx.lineWidth = 2;
ctx.strokeStyle = '#b71c1c';
ctx.stroke();
// Outline for the cork face
ctx.beginPath();
ctx.arc(centerX, centerY, faceRadius, 0, Math.PI * 2);
ctx.lineWidth = 5;
ctx.strokeStyle = 'rgba(0, 0, 0, 0.2)';
ctx.stroke();
return canvas;
}
Apply Changes