You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, bellScale = "0.85", backgroundColor = "transparent") {
// Parse parameters
const scale = parseFloat(bellScale) || 0.85;
// Set up canvas
const canvas = document.createElement("canvas");
const w = originalImg.width;
const h = originalImg.height;
canvas.width = w;
canvas.height = h;
const ctx = canvas.getContext("2d");
// Dimensions for the bell to fit squarely within the image
const size = Math.min(w, h) * scale;
const cx = w / 2;
const cy = h / 2;
const bw = size; // Bell bounding width
const bh = size; // Bell bounding height
ctx.fillStyle = "black";
ctx.strokeStyle = "black";
// 1. Draw the bell handle (top ring)
ctx.beginPath();
ctx.arc(cx, cy - bh * 0.43, bw * 0.06, 0, Math.PI * 2);
ctx.lineWidth = bw * 0.035;
ctx.stroke();
// 2. Draw the main bell body (mask shape)
ctx.beginPath();
ctx.moveTo(cx, cy - bh * 0.4); // Top center
// Left dome
ctx.bezierCurveTo(
cx - bw * 0.25, cy - bh * 0.4,
cx - bw * 0.3, cy - bh * 0.1,
cx - bw * 0.3, cy + bh * 0.1
);
// Left flare
ctx.bezierCurveTo(
cx - bw * 0.3, cy + bh * 0.25,
cx - bw * 0.45, cy + bh * 0.38,
cx - bw * 0.45, cy + bh * 0.38
);
// Bottom opening curve
ctx.quadraticCurveTo(
cx, cy + bh * 0.48,
cx + bw * 0.45, cy + bh * 0.38
);
// Right flare
ctx.bezierCurveTo(
cx + bw * 0.45, cy + bh * 0.38,
cx + bw * 0.3, cy + bh * 0.25,
cx + bw * 0.3, cy + bh * 0.1
);
// Right dome
ctx.bezierCurveTo(
cx + bw * 0.3, cy - bh * 0.1,
cx + bw * 0.25, cy - bh * 0.4,
cx, cy - bh * 0.4
);
ctx.closePath();
ctx.fill();
// Smooth out the sharp flare extremities with a rounded stroke
ctx.lineJoin = "round";
ctx.lineWidth = bw * 0.02;
ctx.stroke();
// 3. Draw the clapper
ctx.beginPath();
ctx.arc(cx, cy + bh * 0.43, bw * 0.06, 0, Math.PI * 2);
ctx.fill();
// Overlay the original image inside the bell shape
ctx.globalCompositeOperation = "source-in";
ctx.drawImage(originalImg, 0, 0, w, h);
// Apply background color if not transparent
if (backgroundColor && backgroundColor.trim().toLowerCase() !== "transparent") {
ctx.globalCompositeOperation = "destination-over";
ctx.fillStyle = backgroundColor.trim();
ctx.fillRect(0, 0, w, h);
}
// Reset composite operation to default
ctx.globalCompositeOperation = "source-over";
return canvas;
}
Apply Changes