You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, urlOrTitle = "https://example.com", theme = "mac", paddingStr = "50", bgColor = "#e9ecef") {
// Parse parameters
const parsedPadding = parseInt(paddingStr, 10);
const padding = isNaN(parsedPadding) ? 50 : parsedPadding;
// Core dimensions dynamically scaled based on the image size
const bw = originalImg.width;
const headerHeight = Math.max(30, Math.min(100, bw * 0.05));
const bh = originalImg.height + headerHeight;
const radius = Math.max(5, headerHeight * 0.2);
// Canvas setup
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const cw = bw + padding * 2;
const ch = bh + padding * 2;
canvas.width = cw;
canvas.height = ch;
// Draw background
ctx.fillStyle = bgColor;
ctx.fillRect(0, 0, cw, ch);
const bx = padding;
const by = padding;
// Helper function to draw rounded rectangles
function drawRoundRect(x, y, w, h, r) {
ctx.beginPath();
ctx.moveTo(x + r, y);
ctx.lineTo(x + w - r, y);
ctx.quadraticCurveTo(x + w, y, x + w, y + r);
ctx.lineTo(x + w, y + h - r);
ctx.quadraticCurveTo(x + w, y + h, x + w - r, y + h);
ctx.lineTo(x + r, y + h);
ctx.quadraticCurveTo(x, y + h, x, y + h - r);
ctx.lineTo(x, y + r);
ctx.quadraticCurveTo(x, y, x + r, y);
ctx.closePath();
}
// Drop shadow
const shadowSize = Math.max(0, Math.min(padding * 0.8, bw * 0.03));
if (shadowSize > 0) {
ctx.shadowColor = 'rgba(0, 0, 0, 0.25)';
ctx.shadowBlur = shadowSize;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = shadowSize * 0.5;
}
// Draw main browser container
drawRoundRect(bx, by, bw, bh, radius);
ctx.fillStyle = '#ffffff';
ctx.fill();
// Reset shadow to prevent bleeding into other drawing operations
ctx.shadowColor = 'transparent';
ctx.shadowBlur = 0;
// Set a clipping region to keep the header and image inside the rounded corners
ctx.save();
drawRoundRect(bx, by, bw, bh, radius);
ctx.clip();
// Generate Header (Browser Top Bar)
ctx.fillStyle = '#f1f1f1'; // Minimalist light gray
ctx.fillRect(bx, by, bw, headerHeight);
// Draw subtle border line at the bottom of the header
ctx.fillStyle = '#e0e0e0';
ctx.fillRect(bx, by + headerHeight - 1, bw, 1);
// Draw Window Action Buttons based on chosen theme
if (theme.toLowerCase() !== 'windows') {
// Mac Style (Colored dots on the left)
const dotRadius = headerHeight * 0.18;
const dotSpacing = dotRadius * 3.5;
const startX = bx + dotSpacing;
const startY = by + headerHeight / 2;
const colors = ['#ff5f56', '#ffbd2e', '#27c93f']; // Red, Yellow, Green
colors.forEach((c, i) => {
ctx.beginPath();
ctx.arc(startX + i * dotSpacing, startY, dotRadius, 0, Math.PI * 2);
ctx.fillStyle = c;
ctx.fill();
});
} else {
// Windows Style (Monochrome shapes on the right)
const btnW = headerHeight * 1.2;
const btnH = headerHeight;
const startX = bx + bw - btnW * 3;
const startY = by;
ctx.strokeStyle = '#333333';
ctx.lineWidth = Math.max(1, headerHeight * 0.03);
// Minimize
ctx.beginPath();
ctx.moveTo(startX + btnW * 0.35, startY + btnH * 0.6);
ctx.lineTo(startX + btnW * 0.65, startY + btnH * 0.6);
ctx.stroke();
// Maximize
ctx.beginPath();
ctx.strokeRect(startX + btnW + btnW * 0.35, startY + btnH * 0.35, btnW * 0.3, btnH * 0.3);
ctx.stroke();
// Close
ctx.beginPath();
ctx.moveTo(startX + btnW * 2 + btnW * 0.4, startY + btnH * 0.4);
ctx.lineTo(startX + btnW * 2 + btnW * 0.6, startY + btnH * 0.6);
ctx.moveTo(startX + btnW * 2 + btnW * 0.6, startY + btnH * 0.4);
ctx.lineTo(startX + btnW * 2 + btnW * 0.4, startY + btnH * 0.6);
ctx.stroke();
}
// Draw URL Content Bar
const urlBarW = Math.min(bw * 0.5, 800);
const urlBarH = headerHeight * 0.55;
const urlBarX = bx + (bw - urlBarW) / 2;
const urlBarY = by + (headerHeight - urlBarH) / 2;
drawRoundRect(urlBarX, urlBarY, urlBarW, urlBarH, Math.max(3, urlBarH * 0.3));
ctx.fillStyle = '#ffffff';
ctx.fill();
ctx.strokeStyle = '#e0e0e0';
ctx.lineWidth = 1;
ctx.stroke();
// Add text into the URL Bar
if (urlOrTitle.trim().length > 0) {
ctx.fillStyle = '#666666';
let fontSize = Math.floor(urlBarH * 0.45);
ctx.font = `${fontSize}px Arial, sans-serif`;
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
let textToDraw = urlOrTitle;
// Truncate text logic to fit neatly inside the URL Bar bounds
if (ctx.measureText(textToDraw).width > urlBarW - 20) {
while (textToDraw.length > 0 && ctx.measureText(textToDraw + '...').width > urlBarW - 20) {
textToDraw = textToDraw.slice(0, -1);
}
textToDraw += '...';
}
ctx.fillText(textToDraw, urlBarX + urlBarW / 2, urlBarY + urlBarH / 2 + 1);
}
// Draw the original photo within the browser interface
ctx.drawImage(originalImg, bx, by + headerHeight, bw, originalImg.height);
// Remove the clip
ctx.restore();
return canvas;
}
Apply Changes