You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(
originalImg,
labName = "Advanced Research Lab",
searchPlaceholder = "Search for experiments, papers, or topics...",
topicList = "Artificial Intelligence, Nanotechnology, Quantum Mechanics, Bioinformatics, Robotics, Astrophysics, Data Science, Materials Science",
themeColor = "#1e3a8a",
accentColor = "#3b82f6"
) {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
// Helper functions
function drawRoundRect(ctx, x, y, width, height, radius) {
ctx.beginPath();
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();
}
function hexToRgba(hex, alpha) {
let r = 0, g = 0, b = 0;
if (hex.length === 4) {
r = parseInt(hex[1] + hex[1], 16);
g = parseInt(hex[2] + hex[2], 16);
b = parseInt(hex[3] + hex[3], 16);
} else /* 7 */ {
r = parseInt(hex.substring(1, 3), 16);
g = parseInt(hex.substring(3, 5), 16);
b = parseInt(hex.substring(5, 7), 16);
}
return `rgba(${r}, ${g}, ${b}, ${alpha})`;
}
// Process Topics and calculate rows
const topics = topicList.split(',').map(t => t.trim()).filter(t => t);
const dummyCanvas = document.createElement('canvas');
const dummyCtx = dummyCanvas.getContext('2d');
dummyCtx.font = 'bold 15px "Segoe UI", Arial, sans-serif';
const paddingX = 24;
const pillHeight = 38;
const gap = 16;
const canvasBaseWidth = 800;
const maxTopicsWidth = canvasBaseWidth - 100; // Leave 50px margins on both sides
let rows = [];
let currentRow = [];
let currentWidth = 0;
for (let i = 0; i < topics.length; i++) {
const textW = dummyCtx.measureText(topics[i]).width;
const pillW = textW + paddingX * 2;
if (currentWidth + pillW + gap > maxTopicsWidth && currentRow.length > 0) {
rows.push({ items: currentRow, width: currentWidth - gap });
currentRow = [];
currentWidth = 0;
}
currentRow.push({ text: topics[i], width: pillW });
currentWidth += pillW + gap;
}
if (currentRow.length > 0) {
rows.push({ items: currentRow, width: currentWidth - gap });
}
const yStartTopics = 320;
const canvasHeight = Math.max(400, yStartTopics + (rows.length * (pillHeight + gap)) + 40);
// Set Canvas Dimensions
canvas.width = canvasBaseWidth;
canvas.height = canvasHeight;
// 1. Draw Background
ctx.fillStyle = '#f8fafc'; // light gray-blue
ctx.fillRect(0, 0, canvas.width, canvas.height);
// 2. Draw Top Navigation Header
ctx.fillStyle = themeColor;
ctx.fillRect(0, 0, canvas.width, 80);
// 3. Draw Uploaded Image as Logo
ctx.save();
const logoX = 40;
const logoY = 15;
const logoSize = 50;
ctx.beginPath();
ctx.arc(logoX + logoSize / 2, logoY + logoSize / 2, logoSize / 2, 0, Math.PI * 2);
ctx.clip();
// Scale and center the image to cover the logo area
const scale = Math.max(logoSize / originalImg.width, logoSize / originalImg.height);
const sw = originalImg.width * scale;
const sh = originalImg.height * scale;
ctx.drawImage(originalImg, logoX + logoSize / 2 - sw / 2, logoY + logoSize / 2 - sh / 2, sw, sh);
ctx.restore();
// 4. Draw Lab Name
ctx.fillStyle = '#ffffff';
ctx.font = 'bold 24px "Segoe UI", Arial, sans-serif';
ctx.textBaseline = 'middle';
ctx.textAlign = 'left';
ctx.fillText(labName, logoX + logoSize + 20, 80 / 2 + 2);
// 5. Draw Main Content Title
ctx.fillStyle = themeColor;
ctx.font = 'bold 36px "Segoe UI", Arial, sans-serif';
ctx.textAlign = 'center';
ctx.fillText("Explore Lab Resources", canvas.width / 2, 140);
// 6. Draw Search Bar
const searchW = 600;
const searchH = 64;
const searchX = (canvas.width - searchW) / 2;
const searchY = 180;
// Search Box Shadow and Background
ctx.shadowColor = 'rgba(0, 0, 0, 0.08)';
ctx.shadowBlur = 15;
ctx.shadowOffsetY = 8;
ctx.fillStyle = '#ffffff';
drawRoundRect(ctx, searchX, searchY, searchW, searchH, 32);
ctx.fill();
ctx.shadowColor = 'transparent';
// Search Placeholder Text
ctx.fillStyle = '#94a3b8';
ctx.font = '18px "Segoe UI", Arial, sans-serif';
ctx.textAlign = 'left';
// Magnifying glass icon (unicode representation)
ctx.fillText("🔍 " + searchPlaceholder, searchX + 25, searchY + searchH / 2 + 2);
// Search Button
const btnW = 120;
const btnH = 50;
const btnX = searchX + searchW - btnW - 7;
const btnY = searchY + 7;
ctx.fillStyle = accentColor;
drawRoundRect(ctx, btnX, btnY, btnW, btnH, 25);
ctx.fill();
ctx.fillStyle = '#ffffff';
ctx.font = 'bold 18px "Segoe UI", Arial, sans-serif';
ctx.textAlign = 'center';
ctx.fillText("Search", btnX + btnW / 2, btnY + btnH / 2 + 2);
// 7. Draw Generated Topics Section
ctx.fillStyle = themeColor;
ctx.font = 'bold 20px "Segoe UI", Arial, sans-serif';
ctx.textAlign = 'center';
ctx.fillText("Suggested Innovation Topics", canvas.width / 2, yStartTopics - 25);
// 8. Draw Topic Pills
let currentY = yStartTopics;
ctx.font = 'bold 15px "Segoe UI", Arial, sans-serif';
rows.forEach(row => {
let currentX = (canvas.width - row.width) / 2;
row.items.forEach(item => {
// Pill background
ctx.fillStyle = hexToRgba(accentColor, 0.12);
drawRoundRect(ctx, currentX, currentY, item.width, pillHeight, pillHeight / 2);
ctx.fill();
// Pill border
ctx.strokeStyle = hexToRgba(accentColor, 0.5);
ctx.lineWidth = 1.5;
ctx.stroke();
// Pill text
ctx.fillStyle = themeColor;
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
ctx.fillText(item.text, currentX + item.width / 2, currentY + pillHeight / 2 + 1);
currentX += item.width + gap;
});
currentY += pillHeight + gap;
});
return canvas;
}
Apply Changes