You can edit the below JavaScript code to customize the image tool.
Apply Changes
async function processImage(
originalImg,
mainTitle = "МОДНЫЙ ДОМ",
subTitle = "LATEST FASHION TRENDS",
filterType = "glamour",
textColor = "#ffffff"
) {
// Dynamically load an elegant Web Font from Google Fonts
await new Promise((resolve) => {
if (document.getElementById('fashion-house-font')) {
resolve();
return;
}
const link = document.createElement('link');
link.id = 'fashion-house-font';
link.href = 'https://fonts.googleapis.com/css2?family=Playfair+Display:ital,wght@0,400;0,700;1,400&display=swap';
link.rel = 'stylesheet';
link.onload = () => {
if (document.fonts) {
document.fonts.ready.then(resolve);
} else {
setTimeout(resolve, 500); // Fallback timeout if document.fonts is missing
}
};
link.onerror = resolve; // Continue even if font loading fails
document.head.appendChild(link);
});
// Create canvas
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = originalImg.width;
canvas.height = originalImg.height;
// Apply specific fashion filter
let filterStr = 'none';
switch (filterType.toLowerCase()) {
case 'glamour':
filterStr = 'contrast(1.15) saturate(1.25) brightness(1.05)';
break;
case 'noir':
filterStr = 'grayscale(1) contrast(1.4) brightness(0.95)';
break;
case 'vintage':
filterStr = 'sepia(0.35) contrast(1.1) brightness(0.95) saturate(0.8)';
break;
case 'chic':
filterStr = 'contrast(1.25) saturate(0.7) hue-rotate(-5deg)';
break;
}
ctx.filter = filterStr;
ctx.drawImage(originalImg, 0, 0, canvas.width, canvas.height);
// Reset filter for overlays
ctx.filter = 'none';
// Figure out if text is dark or light for optimal gradient contrast
const isDarkText = (textColor.toLowerCase() === '#000000' || textColor.toLowerCase() === 'black');
const gradCol1 = isDarkText ? 'rgba(255, 255, 255, 0.7)' : 'rgba(0, 0, 0, 0.6)';
const gradCol2 = isDarkText ? 'rgba(255, 255, 255, 0)' : 'rgba(0, 0, 0, 0)';
// Top Gradient for title readability
const topGradient = ctx.createLinearGradient(0, 0, 0, canvas.height * 0.4);
topGradient.addColorStop(0, gradCol1);
topGradient.addColorStop(1, gradCol2);
ctx.fillStyle = topGradient;
ctx.fillRect(0, 0, canvas.width, canvas.height * 0.4);
// Bottom Gradient for footer readability
const bottomGradient = ctx.createLinearGradient(0, canvas.height, 0, canvas.height * 0.7);
bottomGradient.addColorStop(0, gradCol1);
bottomGradient.addColorStop(1, gradCol2);
ctx.fillStyle = bottomGradient;
ctx.fillRect(0, canvas.height * 0.7, canvas.width, canvas.height * 0.3);
// Setup text basics
ctx.textAlign = 'center';
ctx.fillStyle = textColor;
// Add shadow to text directly
ctx.shadowColor = isDarkText ? 'rgba(255,255,255,0.9)' : 'rgba(0,0,0,0.8)';
ctx.shadowBlur = Math.max(5, canvas.width * 0.01);
ctx.shadowOffsetX = 1;
ctx.shadowOffsetY = 1;
// Font utility configuration
const fontFamily = '"Playfair Display", "Times New Roman", serif';
// Render Main Title dynamically resizing to fit
let titleFontSize = Math.floor(canvas.width * 0.15);
ctx.font = `bold ${titleFontSize}px ${fontFamily}`;
let titleMetrics = ctx.measureText(mainTitle);
if (titleMetrics.width > canvas.width * 0.85) { // Scale down if too wide
titleFontSize = titleFontSize * (canvas.width * 0.85 / titleMetrics.width);
ctx.font = `bold ${titleFontSize}px ${fontFamily}`;
}
ctx.textBaseline = 'top';
const topTextY = canvas.height * 0.07;
ctx.fillText(mainTitle, canvas.width / 2, topTextY);
// Render Subtitle
let subFontSize = Math.floor(canvas.width * 0.04);
ctx.font = `italic ${subFontSize}px ${fontFamily}`;
let subMetrics = ctx.measureText(subTitle);
if (subMetrics.width > canvas.width * 0.8) {
subFontSize = subFontSize * (canvas.width * 0.8 / subMetrics.width);
ctx.font = `italic ${subFontSize}px ${fontFamily}`;
}
ctx.fillText(subTitle, canvas.width / 2, topTextY + titleFontSize + canvas.height * 0.02);
// Render Bottom Info Text
let bottomFontSize = Math.floor(canvas.width * 0.025);
ctx.font = `bold ${bottomFontSize}px ${fontFamily}`;
ctx.textBaseline = 'bottom';
const currentYear = new Date().getFullYear();
ctx.fillText(`N° 01 — ${currentYear} COLLECTION`, canvas.width / 2, canvas.height * 0.95);
// Clear shadow to draw the structural border correctly
ctx.shadowColor = 'transparent';
ctx.shadowBlur = 0;
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
// Draw aesthetic fashion magazine frame border
ctx.strokeStyle = textColor;
ctx.lineWidth = Math.max(1, Math.floor(canvas.width * 0.003));
const margin = canvas.width * 0.04;
ctx.strokeRect(margin, margin, canvas.width - (margin * 2), canvas.height - (margin * 2));
// Add an inner elegant border framing
const innerMargin = margin + (canvas.width * 0.015);
ctx.lineWidth = Math.max(1, Math.floor(canvas.width * 0.001));
ctx.strokeRect(innerMargin, innerMargin, canvas.width - (innerMargin * 2), canvas.height - (innerMargin * 2));
return canvas;
}
Apply Changes