You can edit the below JavaScript code to customize the image tool.
Apply Changes
async function processImage(originalImg, titleText = "AWESOME MOVIE", subtitleText = "COMING SOON", fontFamily = "Cinzel", titleSize = 12, subtitleSize = 4, titleColor = "#FFFFFF", subtitleColor = "#EEEEEE", position = "center", textEffect = "shadow") {
/**
* Dynamically loads a font from Google Fonts if it's not already available.
* @param {string} fontFamily The name of the font family to load.
*/
const loadFont = async (fontFamily) => {
const webSafeFonts = ["Arial", "Verdana", "Georgia", "Times New Roman", "Courier New", "Impact", "sans-serif", "serif"];
if (webSafeFonts.some(f => fontFamily.toLowerCase().includes(f.toLowerCase()))) {
return; // It's a web-safe font, no need to load
}
// Check if font is already available (e.g., loaded by a previous call)
if (document.fonts.check(`12px "${fontFamily}"`)) {
return;
}
// A simple map for popular Google Fonts.
// URLs are for specific weights, but should work for general use cases.
const fontSources = {
'Cinzel': 'https://fonts.gstatic.com/s/cinzel/v19/8vIJ7ww6ddmXBZYtNrd-iA.woff2',
'Bebas Neue': 'https://fonts.gstatic.com/s/bebasneue/v9/JTUSjIg69CK48gW7PXoo9Wlhyw.woff2',
'Oswald': 'https://fonts.gstatic.com/s/oswald/v49/TK3_WkUHHAIjg75cFRf3bXL8LICs1_FvsUtiZSSUhiCXABs.woff2',
'Anton': 'https://fonts.gstatic.com/s/anton/v23/1Ptgg87LROyAm3Kz-C8.woff2',
'Lobster': 'https://fonts.gstatic.com/s/lobster/v28/neILzCirqoswsqX9zo-mM5Ez.woff2'
};
const fontUrl = fontSources[fontFamily];
if (!fontUrl) {
console.warn(`Font "${fontFamily}" is not pre-configured. Browser will use a fallback.`);
return;
}
const fontFace = new FontFace(fontFamily, `url(${fontUrl})`);
try {
await fontFace.load();
document.fonts.add(fontFace);
} catch (e) {
console.error(`Failed to load font "${fontFamily}":`, e);
// Fallback to a generic sans-serif if loading fails
fontFamily = "sans-serif";
}
};
/**
* Draws text on the canvas with optional effects like shadow or outline.
*/
const drawTextWithEffect = (ctx, text, x, y, effect, outlineColor = 'black') => {
const fontSize = parseInt(ctx.font, 10);
if (isNaN(fontSize)) return;
// Apply effects
if (effect === 'shadow') {
ctx.shadowColor = 'rgba(0, 0, 0, 0.8)';
ctx.shadowBlur = fontSize / 10;
ctx.shadowOffsetX = fontSize / 20;
ctx.shadowOffsetY = fontSize / 20;
ctx.fillText(text, x, y);
} else if (effect === 'outline') {
ctx.strokeStyle = outlineColor;
ctx.lineWidth = Math.max(1, fontSize / 20);
ctx.strokeText(text, x, y);
ctx.fillText(text, x, y);
} else { // 'none' or any other value
ctx.fillText(text, x, y);
}
// Reset effects for next draw call
ctx.shadowColor = 'transparent';
ctx.shadowBlur = 0;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
};
// 1. Load the specified font
await loadFont(fontFamily);
// 2. Create canvas and draw the original image
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = originalImg.naturalWidth;
canvas.height = originalImg.naturalHeight;
ctx.drawImage(originalImg, 0, 0, canvas.width, canvas.height);
// 3. Set up text properties
ctx.textAlign = 'center';
ctx.textBaseline = 'middle';
// 4. Calculate font sizes and positions
const titleFontSize = Math.max(10, canvas.width * (Number(titleSize) / 100));
const subtitleFontSize = Math.max(8, canvas.width * (Number(subtitleSize) / 100));
const gap = titleFontSize * 0.2;
// Determine the vertical center (y) of the text block
let blockCenterY;
if (position === 'top') {
blockCenterY = canvas.height * 0.25;
} else if (position === 'bottom') {
blockCenterY = canvas.height * 0.75;
} else { // 'center'
blockCenterY = canvas.height / 2;
}
// Calculate individual text Y positions
let titleY = null;
let subtitleY = null;
// Convert to uppercase for cinematic feel
const upperTitle = titleText.trim().toUpperCase();
const upperSubtitle = subtitleText.trim().toUpperCase();
if (upperTitle && upperSubtitle) {
const totalTextHeight = titleFontSize + subtitleFontSize + gap;
titleY = blockCenterY - (totalTextHeight / 2) + (titleFontSize / 2);
subtitleY = titleY + (titleFontSize / 2) + gap + (subtitleFontSize / 2);
} else if (upperTitle) {
titleY = blockCenterY;
} else if (upperSubtitle) {
subtitleY = blockCenterY;
}
// 5. Draw the texts
const x = canvas.width / 2;
if (titleY !== null) {
ctx.font = `bold ${titleFontSize}px "${fontFamily}", sans-serif`;
ctx.fillStyle = titleColor;
drawTextWithEffect(ctx, upperTitle, x, titleY, textEffect);
}
if (subtitleY !== null) {
ctx.font = `${subtitleFontSize}px "${fontFamily}", sans-serif`;
ctx.fillStyle = subtitleColor;
drawTextWithEffect(ctx, upperSubtitle, x, subtitleY, textEffect);
}
return canvas;
}
Apply Changes