You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, url = "https://www.example.com", theme = "light", padding = 40, backgroundColor = "#e5e7eb") {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// Ensure padding is a safe number
const pad = parseInt(padding, 10);
const safePadding = isNaN(pad) ? 40 : pad;
// Minimum width so the browser UI doesn't visually break
const minWidth = 450;
const finalWidth = Math.max(originalImg.width, minWidth);
const ratio = finalWidth / originalImg.width;
const finalImgHeight = originalImg.height * ratio;
const uiHeight = 50; // Standard browser bar height
canvas.width = finalWidth + safePadding * 2;
canvas.height = finalImgHeight + uiHeight + safePadding * 2;
// Draw outer background (if not transparent)
if (backgroundColor && backgroundColor.toLowerCase() !== 'transparent') {
ctx.fillStyle = backgroundColor;
ctx.fillRect(0, 0, canvas.width, canvas.height);
}
// Helper to trace rounded rectangle path
function makeRoundRectPath(ctx, x, y, w, h, r) {
ctx.beginPath();
ctx.moveTo(x + r, y);
ctx.arcTo(x + w, y, x + w, y + h, r);
ctx.arcTo(x + w, y + h, x, y + h, r);
ctx.arcTo(x, y + h, x, y, r);
ctx.arcTo(x, y, x + w, y, r);
ctx.closePath();
}
const isDark = theme.toLowerCase() === 'dark';
const topBarColor = isDark ? '#323233' : '#f3f4f6';
const urlBarColor = isDark ? '#1e1e1e' : '#ffffff';
const urlTextColor = isDark ? '#d1d5db' : '#374151';
const borderColor = isDark ? '#4b5563' : '#d1d5db';
// Draw Shadow for the main window
ctx.save();
ctx.shadowColor = 'rgba(0, 0, 0, 0.15)';
ctx.shadowBlur = 20;
ctx.shadowOffsetY = 10;
ctx.shadowOffsetX = 0;
ctx.fillStyle = '#ffffff'; // Color to block the shadow from bleeding inside
makeRoundRectPath(ctx, safePadding, safePadding, finalWidth, uiHeight + finalImgHeight, 10);
ctx.fill();
ctx.restore();
// Clip rendering strictly into the browser window bounds
ctx.save();
makeRoundRectPath(ctx, safePadding, safePadding, finalWidth, uiHeight + finalImgHeight, 10);
ctx.clip();
// Draw Browser Tools Top Bar (Chrome/Safari style)
ctx.fillStyle = topBarColor;
ctx.fillRect(safePadding, safePadding, finalWidth, uiHeight);
// Draw macOS style controls dots
const dotColors = ['#ed6a5e', '#f4c050', '#61c554'];
dotColors.forEach((color, index) => {
ctx.fillStyle = color;
ctx.beginPath();
ctx.arc(safePadding + 20 + (index * 17), safePadding + (uiHeight / 2), 5.5, 0, Math.PI * 2);
ctx.fill();
});
// Draw Inner URL Bar
const urlBarX = safePadding + 85;
const urlBarY = safePadding + 11;
const urlBarWidth = finalWidth - 105;
const urlBarHeight = 28;
ctx.fillStyle = urlBarColor;
makeRoundRectPath(ctx, urlBarX, urlBarY, urlBarWidth, urlBarHeight, 6);
ctx.fill();
// Subtle edge for URL bar
ctx.strokeStyle = isDark ? '#3f3f40' : '#e5e7eb';
ctx.lineWidth = 1;
ctx.stroke();
// Setup Text styling for URL
ctx.fillStyle = urlTextColor;
ctx.font = '13px Arial, sans-serif';
ctx.textBaseline = 'middle';
// Manage truncation if the URL is long
let displayUrl = url;
const lockText = "🔒 ";
const lockWidth = ctx.measureText(lockText).width;
const maxTextWidth = Math.max(10, urlBarWidth - lockWidth - 24);
if (ctx.measureText(displayUrl).width > maxTextWidth) {
while (ctx.measureText(displayUrl + '...').width > maxTextWidth && displayUrl.length > 0) {
displayUrl = displayUrl.slice(0, -1);
}
displayUrl += '...';
}
// Draw the text
ctx.fillText(lockText, urlBarX + 12, safePadding + (uiHeight / 2));
ctx.fillText(displayUrl, urlBarX + 12 + lockWidth, safePadding + (uiHeight / 2));
// Draw the actual image underneath the browser UI
ctx.drawImage(originalImg, safePadding, safePadding + uiHeight, finalWidth, finalImgHeight);
// Restore to remove the clipping mask
ctx.restore();
// Draw an outlined border for the overall window itself
ctx.strokeStyle = borderColor;
ctx.lineWidth = 1;
makeRoundRectPath(ctx, safePadding, safePadding, finalWidth, uiHeight + finalImgHeight, 10);
ctx.stroke();
return canvas;
}
Apply Changes