You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, addressBarText = "https://www.example.com", theme = "light", padding = 32, cornerRadius = 12) {
// Sanitize and enforce default types for parameters
addressBarText = String(addressBarText);
theme = String(theme).trim().toLowerCase();
padding = Number(padding);
if (isNaN(padding) || padding < 0) padding = 32;
cornerRadius = Number(cornerRadius);
if (isNaN(cornerRadius) || cornerRadius < 0) cornerRadius = 12;
const isDark = theme === "dark";
const topBarColor = isDark ? "#2A2A2A" : "#F6F6F6";
const addressBarBg = isDark ? "#1C1C1C" : "#FFFFFF";
const addressBarBorder = isDark ? "#1C1C1C" : "#E0E0E0";
const textColor = isDark ? "#E0E0E0" : "#333333";
const pageBg = isDark ? "#121212" : "#FFFFFF";
const separatorColor = isDark ? "#000000" : "#E5E5E5";
// Set layout dimensions
const topBarHeight = 40;
const minWidth = 350;
let windowWidth = Math.max(originalImg.width, minWidth);
let windowHeight = originalImg.height + topBarHeight;
const canvasWidth = windowWidth + padding * 2;
const canvasHeight = windowHeight + padding * 2;
const canvas = document.createElement("canvas");
canvas.width = canvasWidth;
canvas.height = canvasHeight;
const ctx = canvas.getContext("2d");
// Helper to draw a rounded rectangle path
function buildRoundRectPath(x, y, w, h, r) {
ctx.beginPath();
ctx.moveTo(x + r, y);
ctx.lineTo(x + w - r, y);
ctx.arcTo(x + w, y, x + w, y + h, r);
ctx.lineTo(x + w, y + h - r);
ctx.arcTo(x + w, y + h, x + w - r, y + h, r);
ctx.lineTo(x + r, y + h);
ctx.arcTo(x, y + h, x, y + h - r, r);
ctx.lineTo(x, y + r);
ctx.arcTo(x, y, x + r, y, r);
ctx.closePath();
}
// --- Step 1: Draw the window shadow and base background ---
ctx.save();
buildRoundRectPath(padding, padding, windowWidth, windowHeight, cornerRadius);
ctx.shadowColor = "rgba(0, 0, 0, 0.2)";
ctx.shadowBlur = 24;
ctx.shadowOffsetY = 10;
ctx.fillStyle = pageBg;
ctx.fill();
ctx.restore();
// --- Step 2: Clip the context to the window border radius ---
ctx.save();
buildRoundRectPath(padding, padding, windowWidth, windowHeight, cornerRadius);
ctx.clip();
// Fill page background (in case image has transparency or is narrower than minWidth)
ctx.fillStyle = pageBg;
ctx.fillRect(padding, padding, windowWidth, windowHeight);
// --- Step 3: Draw the user's original image ---
// If the image is smaller than min window width, horizontally center it.
const imgX = padding + (windowWidth - originalImg.width) / 2;
const imgY = padding + topBarHeight;
ctx.drawImage(originalImg, imgX, imgY);
// --- Step 4: Draw the Top Browser Bar ---
ctx.fillStyle = topBarColor;
ctx.fillRect(padding, padding, windowWidth, topBarHeight);
// Separator line between top bar and content
ctx.beginPath();
ctx.moveTo(padding, padding + topBarHeight);
ctx.lineTo(padding + windowWidth, padding + topBarHeight);
ctx.lineWidth = 1;
ctx.strokeStyle = separatorColor;
ctx.stroke();
// --- Step 5: Draw MacOS style window control dots ---
const dotY = padding + topBarHeight / 2;
const dotRadius = 6;
const dotColors = ["#FF605C", "#FFBD44", "#00CA4E"]; // Red, Yellow, Green
dotColors.forEach((color, index) => {
ctx.beginPath();
// 16px left margin, 20px space between each dot
ctx.arc(padding + 16 + index * 20, dotY, dotRadius, 0, Math.PI * 2);
ctx.fillStyle = color;
ctx.fill();
});
// --- Step 6: Draw the Address Bar ---
// Make address bar responsive but constrained nicely
const maxAddrWidth = windowWidth - 180;
const addrWidth = Math.min(Math.max(180, windowWidth * 0.5), maxAddrWidth);
const addrX = padding + (windowWidth - addrWidth) / 2;
const addrY = padding + 7;
const addrHeight = 26;
const addrRadius = 6;
ctx.beginPath();
buildRoundRectPath(addrX, addrY, addrWidth, addrHeight, addrRadius);
ctx.fillStyle = addressBarBg;
ctx.fill();
// Draw slight border around address bar
ctx.lineWidth = 1;
ctx.strokeStyle = addressBarBorder;
ctx.stroke();
// --- Step 7: Draw Address Bar Text ---
ctx.font = "12px -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif";
ctx.fillStyle = textColor;
ctx.textAlign = "center";
ctx.textBaseline = "middle";
// Max text width leaves 10px padding inside the address bar horizontally
ctx.fillText(addressBarText, addrX + addrWidth / 2, addrY + addrHeight / 2 + 1, addrWidth - 20);
// Restore context to un-clip
ctx.restore();
return canvas;
}
Apply Changes