You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, mode = "mask", primaryColor = "rgba(0, 105, 148, 0.7)", backgroundColor = "transparent") {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const width = originalImg.width;
const height = originalImg.height;
canvas.width = width;
canvas.height = height;
// Apply optional background color
if (backgroundColor && backgroundColor !== "transparent" && backgroundColor.trim() !== "") {
ctx.fillStyle = backgroundColor;
ctx.fillRect(0, 0, width, height);
}
// Helper function to trace a highly detailed, cartoonish whale shape path
// Designed in a 100x100 relative bounding box
const defineWhalePath = (targetCtx, cx, cy, size, flipHorizontally = false) => {
const scale = size / 100;
targetCtx.save();
targetCtx.translate(cx, cy);
if (flipHorizontally) {
targetCtx.scale(-1, 1);
}
targetCtx.scale(scale, scale);
// Center the 100x100 drawing area around the provided coordinate
targetCtx.translate(-50, -50);
targetCtx.beginPath();
// Nose starting point
targetCtx.moveTo(10, 60);
// Head and Arching Back
targetCtx.bezierCurveTo(10, 20, 75, 20, 85, 50);
// Top Fluke (Tail fin upper edge)
targetCtx.quadraticCurveTo(92, 50, 98, 35);
// Tail Notch
targetCtx.lineTo(90, 55);
// Bottom Fluke
targetCtx.lineTo(98, 75);
// Bottom Peduncle
targetCtx.quadraticCurveTo(92, 60, 85, 60);
// Rear belly
targetCtx.quadraticCurveTo(70, 65, 55, 65);
// Flipper tip protruding
targetCtx.lineTo(45, 88);
// Flipper returning edge
targetCtx.lineTo(40, 65);
// Front belly closing to Nose
targetCtx.quadraticCurveTo(20, 70, 10, 60);
targetCtx.closePath();
// Eye Cutout (Drawn counter-clockwise for "evenodd" fill rules to create a hole)
targetCtx.moveTo(26.5, 43);
targetCtx.arc(24, 43, 2.5, 0, Math.PI * 2, true);
targetCtx.closePath();
// Water Spout Droplets (Added dynamically as positive space above the whale)
const drawDrop = (dx, dy, sc) => {
targetCtx.moveTo(dx, dy - 5 * sc);
// Right and bottom curve of drop
targetCtx.bezierCurveTo(dx + 3.5 * sc, dy - 1 * sc, dx + 3.5 * sc, dy + 5 * sc, dx, dy + 5 * sc);
// Left returning side of drop
targetCtx.bezierCurveTo(dx - 3.5 * sc, dy + 5 * sc, dx - 3.5 * sc, dy - 1 * sc, dx, dy - 5 * sc);
targetCtx.closePath();
};
drawDrop(40, 10, 1.2); // Main center droplet
drawDrop(28, 18, 0.8); // Left spray droplet
drawDrop(52, 18, 0.8); // Right spray droplet
targetCtx.restore();
};
// Modes Implementation
if (mode === "mask") {
// Clips the original image directly into the shape of a giant whale
ctx.save();
defineWhalePath(ctx, width / 2, height / 2, Math.min(width, height) * 0.95, false);
ctx.clip("evenodd");
ctx.drawImage(originalImg, 0, 0, width, height);
ctx.restore();
}
else if (mode === "overlay") {
// Draws the original image with a vibrant translucent whale overlaid on top
ctx.drawImage(originalImg, 0, 0, width, height);
defineWhalePath(ctx, width / 2, height / 2, Math.min(width, height) * 0.85, false);
ctx.fillStyle = primaryColor;
ctx.fill("evenodd");
ctx.lineWidth = Math.max(3, width * 0.005);
ctx.strokeStyle = "rgba(255, 255, 255, 0.9)";
ctx.stroke();
}
else if (mode === "herd") {
// Draws the original image and stamps a wandering pod of whales across it
ctx.drawImage(originalImg, 0, 0, width, height);
const numWhales = 12;
for (let i = 0; i < numWhales; i++) {
const x = width * Math.random();
const y = height * Math.random();
const size = Math.min(width, height) * (0.15 + Math.random() * 0.25);
const flip = Math.random() > 0.5;
ctx.save();
defineWhalePath(ctx, x, y, size, flip);
// Randomize transparencies slightly for depth
ctx.globalAlpha = 0.6 + Math.random() * 0.4;
ctx.fillStyle = primaryColor;
ctx.fill("evenodd");
ctx.globalAlpha = 0.8;
ctx.lineWidth = Math.max(1, size * 0.02);
ctx.strokeStyle = "rgba(255, 255, 255, 0.7)";
ctx.stroke();
ctx.restore();
}
}
else if (mode === "emoji") {
// A playful mode that scatters native whale emojis everywhere
ctx.drawImage(originalImg, 0, 0, width, height);
const numEmojis = 25;
ctx.textAlign = "center";
ctx.textBaseline = "middle";
for (let i = 0; i < numEmojis; i++) {
const size = Math.min(width, height) * (0.05 + Math.random() * 0.15);
ctx.font = `${size}px sans-serif`;
const x = width * Math.random();
const y = height * Math.random();
ctx.save();
ctx.translate(x, y);
ctx.rotate((Math.random() - 0.5) * 0.6); // Random gentle rotations
// Mix classical and spouting whale emojis
const whaleChar = Math.random() > 0.5 ? "🐋" : "🐳";
ctx.fillText(whaleChar, 0, 0);
ctx.restore();
}
}
else {
// Fallback safety to original image
ctx.drawImage(originalImg, 0, 0, width, height);
}
return canvas;
}
Apply Changes