You can edit the below JavaScript code to customize the image tool.
Apply Changes
/**
* Simulates a web browser window around an image.
*
* @param {HTMLImageElement} originalImg The original image object to display inside the browser frame.
* @param {string} [theme='light'] The color theme of the browser window. Can be 'light' or 'dark'.
* @param {string} [url='https://example.com'] The URL to display in the address bar.
* @param {string} [controls='show'] Whether to display the window controls (dots). Can be 'show' or 'hide'.
* @param {number} [padding=20] The padding around the image inside the browser's content area.
* @param {number} [borderRadius=10] The corner radius of the browser window.
* @returns {HTMLCanvasElement} A canvas element containing the image within the browser frame.
*/
function processImage(originalImg, theme = 'light', url = 'https://example.com', controls = 'show', padding = 20, borderRadius = 10) {
// 1. Define theme colors for light and dark modes
const themes = {
light: {
frameBg: '#ffffff',
topBarBg: '#f0f0f0',
urlBg: '#ffffff',
urlText: '#333333',
separator: '#cccccc'
},
dark: {
frameBg: '#2d2d2d',
topBarBg: '#444444',
urlBg: '#333333',
urlText: '#cccccc',
separator: '#555555'
}
};
const currentTheme = themes[theme.toLowerCase()] || themes.light;
// 2. Calculate final canvas dimensions
const topBarHeight = 40;
const canvasWidth = originalImg.width + 2 * padding;
const canvasHeight = originalImg.height + 2 * padding + topBarHeight;
// 3. Create canvas and get 2D rendering context
const canvas = document.createElement('canvas');
canvas.width = canvasWidth;
canvas.height = canvasHeight;
const ctx = canvas.getContext('2d');
// 4. Draw the browser window shape
// We use a clipping path to ensure the entire drawing has rounded corners
ctx.save();
ctx.beginPath();
ctx.roundRect(0, 0, canvasWidth, canvasHeight, borderRadius);
ctx.clip();
// Fill the clipped area with the main background color
ctx.fillStyle = currentTheme.frameBg;
ctx.fillRect(0, 0, canvasWidth, canvasHeight);
// Draw the top bar (title bar) of the browser
ctx.fillStyle = currentTheme.topBarBg;
ctx.fillRect(0, 0, canvasWidth, topBarHeight);
// Draw a subtle separator line below the top bar
ctx.strokeStyle = currentTheme.separator;
ctx.lineWidth = 1;
ctx.beginPath();
ctx.moveTo(0, topBarHeight - 0.5);
ctx.lineTo(canvasWidth, topBarHeight - 0.5);
ctx.stroke();
// 5. Draw window controls (red, yellow, green dots)
if (controls.toLowerCase() === 'show') {
const controlsY = topBarHeight / 2;
const controlRadius = 6;
const controlXPositions = [18, 38, 58];
const controlColors = ['#ff5f57', '#ffbd2e', '#27c93f'];
controlColors.forEach((color, index) => {
ctx.fillStyle = color;
ctx.beginPath();
ctx.arc(controlXPositions[index], controlsY, controlRadius, 0, 2 * Math.PI);
ctx.fill();
});
}
// 6. Draw the address bar and the URL text
const addressBarX = controls.toLowerCase() === 'show' ? 80 : 15;
const addressBarY = 7;
const addressBarWidth = canvasWidth - addressBarX - 15;
const addressBarHeight = topBarHeight - 14;
ctx.fillStyle = currentTheme.urlBg;
ctx.beginPath();
ctx.roundRect(addressBarX, addressBarY, addressBarWidth, addressBarHeight, 5);
ctx.fill();
ctx.fillStyle = currentTheme.urlText;
// Use a font stack that prefers system UI fonts for a native look
ctx.font = '14px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif';
ctx.textAlign = 'left';
ctx.textBaseline = 'middle';
// Truncate the URL text with an ellipsis if it's too long to fit
const maxUrlWidth = addressBarWidth - 24; // 12px padding on each side
let truncatedUrl = url;
if (ctx.measureText(url).width > maxUrlWidth) {
while (ctx.measureText(truncatedUrl + '…').width > maxUrlWidth && truncatedUrl.length > 0) {
truncatedUrl = truncatedUrl.slice(0, -1);
}
truncatedUrl += '…';
}
ctx.fillText(truncatedUrl, addressBarX + 12, topBarHeight / 2 + 1);
// 7. Draw the main image onto the content area of the browser window
ctx.drawImage(originalImg, padding, topBarHeight + padding, originalImg.width, originalImg.height);
// Restore the context, removing the clipping path
ctx.restore();
// 8. Return the final canvas element
return canvas;
}
Apply Changes