Please bookmark this page to avoid losing your image tool!

Parent’s Day Photo Frame Generator

(Free & Supports Bulk Upload)

Drag & drop your images here or

The result will appear here...
You can edit the below JavaScript code to customize the image tool.
async function processImage(originalImg, customText = "С Днём родителей!", frameColor = "#ffe6e6", textColor = "#a31d1d") {
    // Dynamically load a beautiful Google Font for the text overlay
    const fontName = 'Caveat';
    const style = document.createElement('style');
    style.appendChild(document.createTextNode(`
        @import url('https://fonts.googleapis.com/css2?family=${fontName}:wght@700&display=swap');
    `));
    document.head.appendChild(style);

    // Wait until the font is likely loaded. 
    try {
        await document.fonts.load(`700 30px "${fontName}"`);
    } catch (e) {
        console.warn("Custom font loading failed, falling back to standard fonts.");
    }

    const canvas = document.createElement('canvas');
    const ctx = canvas.getContext('2d');

    // Calculate dimensions dynamically relative to the image size
    const baseScale = Math.min(originalImg.width, originalImg.height);
    const marginX = Math.max(originalImg.width * 0.10, baseScale * 0.12); 
    const marginYTop = Math.max(originalImg.height * 0.10, baseScale * 0.12);
    const marginYBottom = marginYTop + baseScale * 0.18; // Extra padding for text at the bottom

    canvas.width = originalImg.width + marginX * 2;
    canvas.height = originalImg.height + marginYTop + marginYBottom;

    // 1. Draw elegant Frame Background gradient
    const bgGrad = ctx.createLinearGradient(0, 0, canvas.width, canvas.height);
    bgGrad.addColorStop(0, '#ffffff'); // Lighter top-left
    bgGrad.addColorStop(1, frameColor); // Themed color bottom-right
    ctx.fillStyle = bgGrad;
    ctx.fillRect(0, 0, canvas.width, canvas.height);

    // 2. Draw Decorative outer borders (classic look)
    const inset1 = baseScale * 0.015;
    const inset2 = baseScale * 0.03;

    // Outer thin solid line
    ctx.strokeStyle = "rgba(255, 255, 255, 0.8)";
    ctx.lineWidth = Math.max(1, baseScale * 0.005);
    ctx.strokeRect(inset1, inset1, canvas.width - inset1 * 2, canvas.height - inset1 * 2);

    // Inner dotted playful line
    ctx.strokeStyle = textColor;
    ctx.lineWidth = Math.max(2, baseScale * 0.008);
    ctx.lineCap = "round";
    const dotSpacing = Math.max(10, baseScale * 0.02);
    ctx.setLineDash([0, dotSpacing]);
    ctx.strokeRect(inset2, inset2, canvas.width - inset2 * 2, canvas.height - inset2 * 2);
    ctx.setLineDash([]); // Reset line dash for further drawing

    // 3. Draw the Original Image with drop shadow
    ctx.save();
    ctx.shadowColor = 'rgba(0, 0, 0, 0.4)';
    ctx.shadowBlur = baseScale * 0.03;
    ctx.shadowOffsetX = baseScale * 0.01;
    ctx.shadowOffsetY = baseScale * 0.015;
    ctx.drawImage(originalImg, marginX, marginYTop, originalImg.width, originalImg.height);
    ctx.restore();

    // 4. Inner border overlapping the image for a framed look
    ctx.strokeStyle = '#ffffff';
    ctx.lineWidth = Math.max(5, baseScale * 0.01);
    ctx.strokeRect(marginX, marginYTop, originalImg.width, originalImg.height);
    
    // Tiny gold accent line on the inner border
    ctx.strokeStyle = '#d4af37'; 
    ctx.lineWidth = Math.max(1, baseScale * 0.003);
    ctx.strokeRect(
        marginX + ctx.lineWidth * 2,
        marginYTop + ctx.lineWidth * 2,
        originalImg.width - ctx.lineWidth * 4,
        originalImg.height - ctx.lineWidth * 4
    );

    // Helper function to draw hearts
    function drawHeart(x, y, size, color) {
        ctx.save();
        ctx.translate(x, y);
        ctx.beginPath();
        const topCurveHeight = size * 0.3;
        ctx.moveTo(0, topCurveHeight);
        // Top Left
        ctx.bezierCurveTo(0, 0, -size/2, 0, -size/2, topCurveHeight);
        // Bottom Left
        ctx.bezierCurveTo(-size/2, (size + topCurveHeight)/2, 0, (size + topCurveHeight)/2, 0, size);
        // Bottom Right
        ctx.bezierCurveTo(0, (size + topCurveHeight)/2, size/2, (size + topCurveHeight)/2, size/2, topCurveHeight);
        // Top Right
        ctx.bezierCurveTo(size/2, 0, 0, 0, 0, topCurveHeight);
        ctx.closePath();
        
        // Fill and slight stroke for popping effect
        ctx.shadowColor = 'rgba(0,0,0,0.2)';
        ctx.shadowBlur = size * 0.1;
        ctx.fillStyle = color;
        ctx.fill();
        ctx.lineWidth = Math.max(1, size * 0.03);
        ctx.strokeStyle = 'white';
        ctx.stroke();
        ctx.restore();
    }

    // 5. Add love/family themed corner decorations (Hearts)
    const cornerSize = baseScale * 0.09;
    const cornerColors = ['#ff4d4d', '#ff9999']; // Red, light pink

    drawHeart(marginX * 0.6, marginYTop * 0.6, cornerSize, cornerColors[0]);
    drawHeart(canvas.width - marginX * 0.6, marginYTop * 0.6, cornerSize, cornerColors[1]);
    drawHeart(marginX * 0.6, canvas.height - marginYBottom + baseScale * 0.05, cornerSize, cornerColors[1]);
    drawHeart(canvas.width - marginX * 0.6, canvas.height - marginYBottom + baseScale * 0.05, cornerSize, cornerColors[0]);

    // 6. Add Custom Text at the bottom
    if (customText) {
        let fontSize = marginYBottom * 0.35;
        ctx.font = `700 ${fontSize}px "${fontName}", cursive, sans-serif`;
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';
        
        // Scale down text if it's too long to fit horizontally
        const maxTextWidth = canvas.width - (marginX * 1.5);
        while (ctx.measureText(customText).width > maxTextWidth && fontSize > 10) {
            fontSize -= 2;
            ctx.font = `700 ${fontSize}px "${fontName}", cursive, sans-serif`;
        }

        const textX = canvas.width / 2;
        const textY = canvas.height - (marginYBottom / 2);

        // Highlight text shadow
        ctx.shadowColor = 'rgba(255, 255, 255, 0.9)';
        ctx.shadowBlur = 8;
        ctx.shadowOffsetX = 2;
        ctx.shadowOffsetY = 2;

        ctx.fillStyle = textColor;
        ctx.fillText(customText, textX, textY);

        // Reset shadow for next text-flanking items
        ctx.shadowColor = 'transparent';

        // Little hearts flanking the text
        const textWidth = ctx.measureText(customText).width;
        const miniHeartSize = fontSize * 0.5;
        drawHeart(textX - textWidth / 2 - miniHeartSize * 1.5, textY - miniHeartSize * 0.4, miniHeartSize, cornerColors[0]);
        drawHeart(textX + textWidth / 2 + miniHeartSize * 1.5, textY - miniHeartSize * 0.4, miniHeartSize, cornerColors[0]);
    }

    return canvas;
}

Free Image Tool Creator

Can't find the image tool you're looking for?
Create one based on your own needs now!

Description

The Parent’s Day Photo Frame Generator allows you to transform your personal photographs into themed, celebratory images. The tool adds an elegant decorative frame, colorful gradients, and heart-shaped accents to your photos. You can also overlay custom heartfelt messages using stylish typography. This tool is ideal for creating personalized digital greetings, social media posts, or printable keepsakes to celebrate family occasions and Parent’s Day.

Leave a Reply

Your email address will not be published. Required fields are marked *