You can edit the below JavaScript code to customize the image tool.
Apply Changes
function processImage(
originalImg,
headlineText = "SHOCKING EXCLUSIVE!",
subheadlineText = "The full story that has everyone talking, right here, right now! You won't believe your eyes when you see page 3!",
headlineBannerColor = "#FFFF00", // Yellow
headlineTextColor = "#000000", // Black
subheadlineTextColor = "#000000", // Black
canvasBackgroundColor = "#FFFFFF", // White
fontFamily = "Impact, Haettenschweiler, 'Arial Narrow Bold', sans-serif",
headlineFontSize = 80, // px
subheadlineFontSize = 30 // px
) {
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
const canvasWidth = 600;
const canvasHeight = 800;
canvas.width = canvasWidth;
canvas.height = canvasHeight;
// Layout dimensions
const headlineSectionHeight = 150;
const imageSectionHeight = 400;
// const subheadlineSectionHeight = canvasHeight - headlineSectionHeight - imageSectionHeight; // = 250, implicitly
// --- 1. Draw canvas background ---
ctx.fillStyle = canvasBackgroundColor;
ctx.fillRect(0, 0, canvasWidth, canvasHeight);
// --- 2. Headline Section ---
const headlineTextPaddingHorizontal = 20; // Horizontal padding for text within banner
// Draw banner background
ctx.fillStyle = headlineBannerColor;
ctx.fillRect(0, 0, canvasWidth, headlineSectionHeight);
// Draw headline text (fit to width, single line, uppercase)
const upperHeadlineText = headlineText.toUpperCase();
let currentHeadlineFontSize = headlineFontSize;
ctx.font = `${currentHeadlineFontSize}px ${fontFamily}`;
ctx.fillStyle = headlineTextColor;
ctx.textAlign = "center";
ctx.textBaseline = "middle"; // Vertically center single line of text
const headlineTextMaxWidth = canvasWidth - 2 * headlineTextPaddingHorizontal;
// Reduce font size until text fits
while (ctx.measureText(upperHeadlineText).width > headlineTextMaxWidth && currentHeadlineFontSize > 10) {
currentHeadlineFontSize--;
ctx.font = `${currentHeadlineFontSize}px ${fontFamily}`;
}
ctx.fillText(upperHeadlineText, canvasWidth / 2, headlineSectionHeight / 2);
// --- 3. Image Section ---
const imageSectionY = headlineSectionHeight;
// Calculate scaled image dimensions to fit within its section while maintaining aspect ratio
const imgMaxW = canvasWidth; // Image can span full canvas width
const imgMaxH = imageSectionHeight;
let drawW = originalImg.width;
let drawH = originalImg.height;
const imgRatio = originalImg.width / originalImg.height;
const sectionRatio = imgMaxW / imgMaxH; // Aspect ratio of the image display area
if (imgRatio > sectionRatio) { // Image is wider than section proportionally, fit to width
drawW = imgMaxW;
drawH = drawW / imgRatio;
} else { // Image is taller or same proportion, fit to height
drawH = imgMaxH;
drawW = drawH * imgRatio;
}
// Center the image within the image section
const imgX = (canvasWidth - drawW) / 2;
const imgY = imageSectionY + (imageSectionHeight - drawH) / 2;
ctx.drawImage(originalImg, imgX, imgY, drawW, drawH);
// --- 4. Subheadline Section ---
const subheadlineSectionY = headlineSectionHeight + imageSectionHeight;
const subheadlineTextPaddingHorizontal = 30;
const subheadlineTextPaddingTop = 20; // Padding from top of subheadline section to where text starts
// Helper function to draw wrapped text for subheadline.
// It's defined inside to easily access subheadlineFontSize, fontFamily, subheadlineTextColor.
function drawWrappedSubheadlineText(context, text, x_center, y_start, maxWidth, lineHeight) {
context.font = `${subheadlineFontSize}px ${fontFamily}`;
context.fillStyle = subheadlineTextColor;
context.textAlign = 'center';
context.textBaseline = 'top'; // Reference point is the top of the text line
const words = text.split(' ');
let line = '';
let currentY = y_start;
for (let n = 0; n < words.length; n++) {
const testLine = line + words[n] + ' ';
// Font must be set before measureText
const metrics = context.measureText(testLine);
const testWidth = metrics.width;
if (testWidth > maxWidth && n > 0) { // If line is too wide and it's not the first word
context.fillText(line.trim(), x_center, currentY);
line = words[n] + ' '; // Start new line
currentY += lineHeight;
} else {
line = testLine;
}
}
context.fillText(line.trim(), x_center, currentY); // Draw the last remaining line
}
drawWrappedSubheadlineText(
ctx,
subheadlineText,
canvasWidth / 2, // x_center
subheadlineSectionY + subheadlineTextPaddingTop, // y_start (top of text block)
canvasWidth - 2 * subheadlineTextPaddingHorizontal, // maxWidth for text
subheadlineFontSize * 1.2 // lineHeight (approx 120% of font size)
);
return canvas;
}
Apply Changes