You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, eyeStyle = 'googly', eyeSize = 25, eyeColor = 'black', mouthStyle = 'smile', accessory = 'none', accessoryColor = 'black') {
// 1. Create a canvas and get its 2D rendering context
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// Get the natural dimensions of the image to handle cases where it might be scaled by CSS
const imgWidth = originalImg.naturalWidth;
const imgHeight = originalImg.naturalHeight;
// Set canvas dimensions to match the image
canvas.width = imgWidth;
canvas.height = imgHeight;
// Return an empty canvas if the image has no dimensions
if (imgWidth === 0 || imgHeight === 0) {
console.error("Image has zero dimensions. Ensure the image is fully loaded before processing.");
return canvas;
}
// 2. Draw the original image onto the canvas
ctx.drawImage(originalImg, 0, 0, imgWidth, imgHeight);
// 3. Define parameters and key positions for the features
// Scale the feature size based on the image width for better proportions on any image size.
const scaledSize = Math.max(5, Math.min(imgWidth / 15, eyeSize));
const lineWidth = Math.max(2, scaledSize / 8);
const centerX = imgWidth / 2;
const centerY = imgHeight / 2;
const eyeOffsetY = -scaledSize * 0.8;
const eyeOffsetX = scaledSize * 1.8;
const leftEyePos = { x: centerX - eyeOffsetX, y: centerY + eyeOffsetY };
const rightEyePos = { x: centerX + eyeOffsetX, y: centerY + eyeOffsetY };
// Helper function to draw a googly eye
const drawGooglyEye = (x, y) => {
// White sclera
ctx.beginPath();
ctx.arc(x, y, scaledSize, 0, 2 * Math.PI);
ctx.fillStyle = 'white';
ctx.fill();
ctx.strokeStyle = 'black';
ctx.lineWidth = lineWidth;
ctx.stroke();
// Pupil with a random offset for the "googly" effect
const pupilSize = scaledSize / 2;
const angle = Math.random() * Math.PI * 2;
const offset = scaledSize / 4;
const pupilX = x + offset * Math.cos(angle);
const pupilY = y + offset * Math.sin(angle);
ctx.beginPath();
ctx.arc(pupilX, pupilY, pupilSize, 0, Math.PI * 2);
ctx.fillStyle = eyeColor;
ctx.fill();
};
// 4. Draw Eyes based on the selected style
if (eyeStyle === 'googly') {
drawGooglyEye(leftEyePos.x, leftEyePos.y);
drawGooglyEye(rightEyePos.x, rightEyePos.y);
} else if (eyeStyle === 'simple') {
ctx.fillStyle = eyeColor;
ctx.beginPath();
ctx.arc(leftEyePos.x, leftEyePos.y, scaledSize * 0.7, 0, Math.PI * 2);
ctx.fill();
ctx.beginPath();
ctx.arc(rightEyePos.x, rightEyePos.y, scaledSize * 0.7, 0, Math.PI * 2);
ctx.fill();
} else if (eyeStyle === 'wink') {
// Draw the right eye as open and the left eye as a wink
drawGooglyEye(rightEyePos.x, rightEyePos.y);
ctx.beginPath();
ctx.arc(leftEyePos.x, leftEyePos.y + scaledSize * 0.5, scaledSize, 1.2 * Math.PI, 1.8 * Math.PI);
ctx.strokeStyle = 'black';
ctx.lineWidth = lineWidth;
ctx.stroke();
}
// 5. Draw Mouth
const mouthY = centerY + scaledSize * 1.5;
ctx.strokeStyle = 'black';
ctx.lineWidth = lineWidth;
ctx.lineCap = 'round';
if (mouthStyle === 'smile') {
ctx.beginPath();
ctx.arc(centerX, mouthY, scaledSize * 1.2, 0.2 * Math.PI, 0.8 * Math.PI);
ctx.stroke();
} else if (mouthStyle === 'o-shape') {
ctx.beginPath();
ctx.arc(centerX, mouthY + scaledSize * 0.5, scaledSize * 0.6, 0, 2 * Math.PI);
ctx.fillStyle = eyeColor; // Match mouth color with eye color for consistency
ctx.fill();
} else if (mouthStyle === 'straight') {
ctx.beginPath();
ctx.moveTo(centerX - scaledSize, mouthY + scaledSize / 2);
ctx.lineTo(centerX + scaledSize, mouthY + scaledSize / 2);
ctx.stroke();
}
// 6. Draw Accessory
if (accessory === 'top-hat') {
const hatWidth = scaledSize * 5;
const hatHeight = hatWidth * 0.7;
const hatX = centerX - hatWidth / 2;
// Position hat above the eyes, ensuring it doesn't go off-canvas
const hatBaseY = Math.min(leftEyePos.y, rightEyePos.y) - scaledSize * 1.5;
const hatTopY = hatBaseY - hatHeight;
ctx.fillStyle = accessoryColor;
// Top part
ctx.fillRect(hatX, hatTopY, hatWidth, hatHeight);
// Brim
ctx.fillRect(hatX - hatWidth * 0.2, hatBaseY, hatWidth * 1.4, hatHeight * 0.2);
} else if (accessory === 'monocle') {
const monocleRadius = scaledSize * 1.3;
ctx.strokeStyle = accessoryColor;
ctx.lineWidth = lineWidth / 2;
// Rim
ctx.beginPath();
ctx.arc(rightEyePos.x, rightEyePos.y, monocleRadius, 0, 2 * Math.PI);
ctx.stroke();
// Chain
ctx.beginPath();
ctx.moveTo(rightEyePos.x + monocleRadius, rightEyePos.y);
ctx.quadraticCurveTo(
rightEyePos.x + monocleRadius * 3,
rightEyePos.y + monocleRadius * 2,
rightEyePos.x + scaledSize * 5,
rightEyePos.y - scaledSize * 2
);
ctx.stroke();
}
// 7. Return the final canvas element
return canvas;
}
Apply Changes