You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(originalImg, baseKeyword = "Visual Design", numberOfIdeas = 6) {
// Ensure parameters are correctly typed
baseKeyword = String(baseKeyword) || "Content Creation";
let numIdeas = parseInt(numberOfIdeas);
if (isNaN(numIdeas) || numIdeas <= 0) numIdeas = 6;
if (numIdeas > 8) numIdeas = 8; // Limit to fit inside the canvas gracefully
// Set up canvas dimensions
const width = 1200;
const height = 800;
const canvas = document.createElement('canvas');
canvas.width = width;
canvas.height = height;
const ctx = canvas.getContext('2d');
// Utility for rounded rectangles
function drawRoundRect(x, y, w, h, radius) {
ctx.beginPath();
ctx.moveTo(x + radius, y);
ctx.lineTo(x + w - radius, y);
ctx.quadraticCurveTo(x + w, y, x + w, y + radius);
ctx.lineTo(x + w, y + h - radius);
ctx.quadraticCurveTo(x + w, y + h, x + w - radius, y + h);
ctx.lineTo(x + radius, y + h);
ctx.quadraticCurveTo(x, y + h, x, y + h - radius);
ctx.lineTo(x, y + radius);
ctx.quadraticCurveTo(x, y, x + radius, y);
ctx.closePath();
}
// Utility for multi-line text mapping
function fillTextMultiLine(text, x, y, maxWidth, lineHeight) {
let words = text.split(' ');
let line = '';
let startY = y;
for (let n = 0; n < words.length; n++) {
let testLine = line + words[n] + ' ';
let metrics = ctx.measureText(testLine);
if (metrics.width > maxWidth && n > 0) {
ctx.fillText(line.trim(), x, y);
line = words[n] + ' ';
y += lineHeight;
} else {
line = testLine;
}
}
ctx.fillText(line.trim(), x, y);
return y + lineHeight; // Expected next line start
}
// 1. Draw blurred, dark background from original image
ctx.filter = 'blur(20px) brightness(30%)';
ctx.drawImage(originalImg, -50, -50, width + 100, height + 100);
ctx.filter = 'none'; // Reset filters
// 2. Draw Main Dashboard Panel
const padding = 50;
const panelWidth = width - padding * 2;
const panelHeight = height - padding * 2;
ctx.shadowColor = 'rgba(0, 0, 0, 0.7)';
ctx.shadowBlur = 30;
ctx.shadowOffsetY = 10;
ctx.fillStyle = 'rgba(25, 28, 35, 0.85)';
drawRoundRect(padding, padding, panelWidth, panelHeight, 24);
ctx.fill();
ctx.shadowBlur = 0;
ctx.shadowOffsetY = 0;
// 3. Header Section
ctx.fillStyle = '#ffffff';
ctx.font = 'bold 36px "Segoe UI", Arial, sans-serif';
ctx.fillText('Creator Studio', padding + 40, padding + 60);
ctx.fillStyle = '#888899';
ctx.font = '22px "Segoe UI", Arial, sans-serif';
ctx.fillText('Advanced Search Topic Idea Generator', padding + 40, padding + 95);
// Mock Search Bar Input
ctx.fillStyle = '#111216';
drawRoundRect(padding + 40, padding + 130, panelWidth - 80, 56, 12);
ctx.fill();
ctx.strokeStyle = '#444455';
ctx.lineWidth = 1;
ctx.stroke();
ctx.fillStyle = '#00e5ff';
ctx.font = 'bold 20px "Segoe UI", Arial, sans-serif';
ctx.fillText('🔍 Advanced Search Topic:', padding + 60, padding + 165);
ctx.fillStyle = '#ffffff';
ctx.font = '20px "Segoe UI", Arial, sans-serif';
ctx.fillText(baseKeyword, padding + 325, padding + 165);
// Separator line
ctx.strokeStyle = '#333344';
ctx.beginPath();
ctx.moveTo(padding + 40, padding + 220);
ctx.lineTo(padding + panelWidth - 40, padding + 220);
ctx.stroke();
// 4. Source Image Preview (Left Column)
const contentY = padding + 260;
const leftColWidth = 450;
ctx.fillStyle = '#cccccc';
ctx.font = 'bold 16px "Segoe UI", Arial, sans-serif';
ctx.fillText('SOURCE MEDIA', padding + 40, contentY - 15);
// Calculate image fit scale
const maxImgWidth = leftColWidth;
const maxImgHeight = 350;
const scale = Math.min(maxImgWidth / originalImg.width, maxImgHeight / originalImg.height);
const pWidth = originalImg.width * scale;
const pHeight = originalImg.height * scale;
ctx.fillStyle = '#000000';
drawRoundRect(padding + 40, contentY, pWidth, pHeight, 8);
ctx.fill();
ctx.save();
ctx.clip();
ctx.drawImage(originalImg, padding + 40, contentY, pWidth, pHeight);
ctx.restore();
// 5. Generated Topic Ideas (Right Column)
const rightColX = padding + 40 + leftColWidth + 60;
const rightColWidth = panelWidth - leftColWidth - 140;
ctx.fillStyle = '#00e5ff';
ctx.font = 'bold 24px "Segoe UI", Arial, sans-serif';
ctx.fillText('⚡ Top Performing Content Ideas', rightColX, contentY);
const prefixes = [
"Advanced strategies for",
"How to master",
"The hidden truth about",
"10 surprising facts about",
"Why everyone is searching for",
"The ultimate guide to",
"Unlocking the potential of",
"Behind the scenes of"
];
const suffixes = [
"in 2024",
"you didn't know",
"revealed",
"for creators",
"explained step-by-step",
"- full tutorial",
"without losing your mind",
"(Expert level)"
];
let currentY = contentY + 40;
ctx.font = '20px "Segoe UI", Arial, sans-serif';
// Generate Idea Cards
for (let i = 0; i < numIdeas; i++) {
// Pseudo-random selection based on image dimensions and loop index to ensure consistency
const pseudo1 = (originalImg.width + i * 13) % prefixes.length;
const pseudo2 = (originalImg.height + i * 29) % suffixes.length;
const topicText = `${prefixes[pseudo1]} "${baseKeyword}" ${suffixes[pseudo2]}`;
// Idea Card Background
ctx.fillStyle = 'rgba(255, 255, 255, 0.05)';
drawRoundRect(rightColX, currentY, rightColWidth, 50, 8);
ctx.fill();
// Idea Status/Trend Icon
ctx.fillStyle = '#ffaa00';
ctx.font = '16px "Segoe UI", Arial, sans-serif';
ctx.fillText(`🔥 High Volume`, rightColX + rightColWidth - 130, currentY + 32);
// Render Idea Text
ctx.fillStyle = '#ffffff';
ctx.font = 'bold 18px "Segoe UI", Arial, sans-serif';
// Number badge
ctx.fillStyle = '#333344';
drawRoundRect(rightColX + 15, currentY + 12, 26, 26, 4);
ctx.fill();
ctx.fillStyle = '#ffffff';
ctx.fillText(String(i + 1), rightColX + 22 + (i>=9?-4:0), currentY + 31);
ctx.fillStyle = '#ddeeff';
ctx.font = '18px "Segoe UI", Arial, sans-serif';
fillTextMultiLine(topicText, rightColX + 55, currentY + 32, rightColWidth - 190, 24);
currentY += 60; // Offset for next card
}
return canvas;
}
Apply Changes