You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, urlText = "https://www.example.com", theme = "light", padding = 40, bgColor = "#e2e8f0", maxWidth = 1200) {
const canvas = document.createElement("canvas");
const ctx = canvas.getContext("2d");
// Helper: Cross-browser rounded rectangle
function drawRoundRect(ctx, x, y, width, height, radius) {
ctx.beginPath();
if (typeof ctx.roundRect === 'function') {
ctx.roundRect(x, y, width, height, radius);
} else {
ctx.moveTo(x + radius, y);
ctx.lineTo(x + width - radius, y);
ctx.quadraticCurveTo(x + width, y, x + width, y + radius);
ctx.lineTo(x + width, y + height - radius);
ctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
ctx.lineTo(x + radius, y + height);
ctx.quadraticCurveTo(x, y + height, x, y + height - radius);
ctx.lineTo(x, y + radius);
ctx.quadraticCurveTo(x, y, x + radius, y);
ctx.closePath();
}
}
// Handle constraints and scaling
const pad = Math.max(0, parseInt(padding, 10) || 0);
const maxBW = Math.max(400, parseInt(maxWidth, 10) || 1200);
const minBW = 400; // ensuring sufficient width for top bar UI elements
const barHeight = 50;
let bw = originalImg.width;
let bh = originalImg.height;
let scale = 1;
if (bw > maxBW) {
scale = maxBW / bw;
bw = maxBW;
bh = originalImg.height * scale;
} else if (bw < minBW) {
scale = minBW / bw;
bw = minBW;
bh = originalImg.height * scale;
}
// Prepare canvas dimensions
canvas.width = bw + pad * 2;
canvas.height = bh + barHeight + pad * 2;
// Theme logic
const isDark = theme.toLowerCase() === "dark";
const topBarColor = isDark ? "#333333" : "#f1f5f9";
const addressBarColor = isDark ? "#222222" : "#ffffff";
const fontColor = isDark ? "#a1a1aa" : "#52525b";
const borderColor = isDark ? "rgba(255,255,255,0.08)" : "rgba(0,0,0,0.08)";
const shadowBase = isDark ? "rgba(0,0,0,0.5)" : "rgba(0,0,0,0.18)";
// 1. Draw outer background
if (pad > 0 && bgColor && bgColor.toLowerCase() !== "transparent" && bgColor.toLowerCase() !== "none") {
ctx.fillStyle = bgColor;
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
// 2. Draw outer shadow and base shape mechanics
ctx.save();
drawRoundRect(ctx, pad, pad, bw, bh + barHeight, 10);
ctx.shadowColor = shadowBase;
ctx.shadowBlur = 24;
ctx.shadowOffsetY = 12;
ctx.shadowOffsetX = 0;
ctx.fillStyle = topBarColor;
ctx.fill();
// Reset shadow
ctx.shadowColor = "transparent";
ctx.shadowBlur = 0;
ctx.shadowOffsetY = 0;
// 3. Clip all inner items exactly to this rounded window base
ctx.clip();
// Fill top bar
ctx.fillStyle = topBarColor;
ctx.fillRect(pad, pad, bw, barHeight);
// Draw traffic light UI buttons (macOS style window controls)
const dotY = pad + barHeight / 2;
const dotColors = ["#ff5f56", "#ffbd2e", "#27c93f"];
for (let i = 0; i < 3; i++) {
ctx.beginPath();
ctx.arc(pad + 20 + i * 20, dotY, 6, 0, Math.PI * 2);
ctx.fillStyle = dotColors[i];
ctx.fill();
ctx.lineWidth = 0.5;
ctx.strokeStyle = "rgba(0,0,0,0.15)";
ctx.stroke();
}
// Draw Address Bar
const addrW = Math.min(bw * 0.55, 600);
const addrH = 28;
const addrX = pad + (bw - addrW) / 2;
const addrY = pad + (barHeight - addrH) / 2;
ctx.fillStyle = addressBarColor;
drawRoundRect(ctx, addrX, addrY, addrW, addrH, 6);
ctx.fill();
ctx.lineWidth = 1;
ctx.strokeStyle = borderColor;
ctx.stroke();
// Optional: Draw text and lock icon securely within the address bar bounds
ctx.save();
drawRoundRect(ctx, addrX, addrY, addrW, addrH, 6);
ctx.clip(); // Prevent extremely long URLs from spilling out
ctx.font = "14px 'Segoe UI', -apple-system, BlinkMacSystemFont, Roboto, Helvetica, Arial, sans-serif";
ctx.fillStyle = fontColor;
ctx.textAlign = "center";
ctx.textBaseline = "middle";
const textW = ctx.measureText(urlText).width;
const contentW = textW + 18; // approx width added for lock icon + margins
const startX = pad + bw / 2 - contentW / 2;
// Draw Lock Icon
const lockW = 8;
const lockH = 6;
const lockX = startX;
const lockY = dotY; // middle point
// Lock shackle
ctx.beginPath();
ctx.arc(lockX + lockW / 2, lockY - 1, 2.5, Math.PI, 0);
ctx.strokeStyle = fontColor;
ctx.lineWidth = 1.2;
ctx.stroke();
// Lock body
ctx.fillStyle = fontColor;
drawRoundRect(ctx, lockX, lockY - 1, lockW, lockH, 1.5);
ctx.fill();
// URL domain text
ctx.fillText(urlText, startX + 16 + textW / 2, lockY + 1);
ctx.restore();
// Sub-border divider line below top bar
ctx.fillStyle = borderColor;
ctx.fillRect(pad, pad + barHeight - 1, bw, 1);
// 4. Draw the actual image
ctx.drawImage(originalImg, pad, pad + barHeight, bw, bh);
ctx.restore(); // Undo base window clipping
// Overlay subtle sharp window border wrapping everything
ctx.save();
drawRoundRect(ctx, pad, pad, bw, bh + barHeight, 10);
ctx.strokeStyle = isDark ? "rgba(255,255,255,0.06)" : "rgba(0,0,0,0.04)";
ctx.lineWidth = 1;
ctx.stroke();
ctx.restore();
return canvas;
}
Apply Changes