Please bookmark this page to avoid losing your image tool!

Photo Friends Reunion Maker

(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.
function processImage(originalImg, caption = "Воссоединение друзей!", friendsNames = "Саша, Маша, Паша", themeColor = "#2c3e50") {
    // Determine output dimensions
    const canvas = document.createElement('canvas');
    const width = 1000;
    const height = 1000;
    canvas.width = width;
    canvas.height = height;
    const ctx = canvas.getContext('2d');

    // 1. Draw elegant background
    // Create a radial gradient for a realistic focus lighting effect on the backboard
    const grad = ctx.createRadialGradient(width / 2, height / 2, 100, width / 2, height / 2, width * 0.8);
    grad.addColorStop(0, themeColor);
    grad.addColorStop(1, '#1a252f'); // Darker vignette around edges
    ctx.fillStyle = grad;
    ctx.fillRect(0, 0, width, height);

    // 2. Add festive confetti to celebrate the reunion
    const colors = ['#ff4757', '#2ed573', '#1e90ff', '#ffa502', '#ffffff', '#eccc68'];
    for (let j = 0; j < 150; j++) {
        ctx.save();
        ctx.fillStyle = colors[Math.floor(Math.random() * colors.length)];
        let cx = Math.random() * width;
        let cy = Math.random() * height;
        ctx.translate(cx, cy);
        ctx.rotate(Math.random() * Math.PI * 2);
        ctx.globalAlpha = 0.5 + Math.random() * 0.4;
        
        // Mix between circles and tiny rectangles
        if (Math.random() > 0.5) {
            ctx.beginPath();
            ctx.arc(0, 0, Math.random() * 4 + 2, 0, Math.PI * 2);
            ctx.fill();
        } else {
            ctx.fillRect(-4, -8, 8, 16);
        }
        ctx.restore();
    }

    // 3. Parse friends' names and prepare photo calculation
    let names = friendsNames.split(',').map(n => n.trim()).filter(n => n);
    if (names.length === 0) names = ["Друг 1", "Друг 2", "Друг 3"];
    const numPhotos = names.length;

    // Dynamically scale photo sizes so they fit well depending on how many friends there are
    const scaleFactor = Math.max(1.5, Math.sqrt(numPhotos)); 
    const maxImgSide = 450 / (scaleFactor / 1.5);
    const scale = Math.min(maxImgSide / originalImg.width, maxImgSide / originalImg.height);
    
    const imgW = originalImg.width * scale;
    const imgH = originalImg.height * scale;
    const padding = 20;
    const bottomPadding = 75;
    const pw = imgW + 2 * padding;
    const ph = imgH + padding + bottomPadding;

    // 4. Draw photos arranged in a scattered circle (creating a collage on a board)
    for (let i = 0; i < numPhotos; i++) {
        ctx.save();
        
        // Spread logic for layout
        const radius = Math.min(270, 80 * numPhotos);
        const angleLayout = (Math.PI * 2 / numPhotos) * i - Math.PI / 2;
        const cx = width / 2 + Math.cos(angleLayout) * radius + (Math.random() - 0.5) * 60;
        const cy = height / 2 + Math.sin(angleLayout) * radius + (Math.random() - 0.5) * 60 + 50; // Shift down slightly
        
        ctx.translate(cx, cy);
        
        // Gives each photo a realistic "tossed onto a table" rotation
        const angle = (Math.random() - 0.5) * 0.5; // ~ ±14 degrees tilt
        ctx.rotate(angle);

        // Polaroid drop shadow
        ctx.shadowColor = 'rgba(0,0,0,0.5)';
        ctx.shadowBlur = 18;
        ctx.shadowOffsetX = 8;
        ctx.shadowOffsetY = 8;

        // Draw Polaroid white frame
        ctx.fillStyle = '#fefefe';
        ctx.fillRect(-pw / 2, -ph / 2, pw, ph);

        // Turn off shadows to draw the image without shadow bleeding over the frame
        ctx.shadowColor = 'transparent';

        // Apply a warm reunion/nostalgia filter
        ctx.filter = "sepia(0.20) contrast(1.1) brightness(1.05)";
        ctx.drawImage(originalImg, -imgW / 2, -ph / 2 + padding, imgW, imgH);
        ctx.filter = "none";

        // Draw Friend's Name as a handwritten marker text at the bottom
        ctx.fillStyle = "#2c3e50";
        ctx.font = "bold 26px 'Comic Sans MS', 'Caveat', cursive, sans-serif";
        ctx.textAlign = "center";
        ctx.textBaseline = "middle";
        ctx.fillText(names[i] || "Друг", 0, ph / 2 - bottomPadding / 2 + 5);

        // Add a piece of holding tape to the top margin of the photo
        ctx.fillStyle = 'rgba(255, 255, 255, 0.4)';
        ctx.translate(0, -ph / 2 + 10);
        ctx.rotate((Math.random() - 0.5) * 0.2); // tape is also slightly angled
        ctx.fillRect(-35, -12, 70, 24);
        
        // Slight tape borders
        ctx.strokeStyle = 'rgba(0,0,0,0.05)';
        ctx.lineWidth = 1;
        ctx.strokeRect(-35, -12, 70, 24);

        ctx.restore();
    }

    // 5. Draw the festive Title Banner at the top
    ctx.save();
    ctx.shadowColor = 'rgba(0,0,0,0.6)';
    ctx.shadowBlur = 20;
    ctx.shadowOffsetY = 10;
    
    // Ribbon banner shape
    ctx.fillStyle = '#ff4757';
    ctx.beginPath();
    const bWidth = Math.min(800, width - 80);
    ctx.moveTo(width / 2 - bWidth / 2, 30);
    ctx.lineTo(width / 2 + bWidth / 2, 30);
    ctx.lineTo(width / 2 + bWidth / 2 - 25, 70);
    ctx.lineTo(width / 2 + bWidth / 2, 110);
    ctx.lineTo(width / 2 - bWidth / 2, 110);
    ctx.lineTo(width / 2 - bWidth / 2 + 25, 70);
    ctx.closePath();
    ctx.fill();

    // Inner decorative dashed/solid line on the banner
    ctx.shadowColor = 'transparent';
    ctx.strokeStyle = '#ff6b81';
    ctx.lineWidth = 3;
    ctx.beginPath();
    ctx.moveTo(width / 2 - bWidth / 2 + 20, 38);
    ctx.lineTo(width / 2 + bWidth / 2 - 20, 38);
    ctx.lineTo(width / 2 + bWidth / 2 - 38, 70);
    ctx.lineTo(width / 2 + bWidth / 2 - 20, 102);
    ctx.lineTo(width / 2 - bWidth / 2 + 20, 102);
    ctx.lineTo(width / 2 - bWidth / 2 + 38, 70);
    ctx.closePath();
    ctx.stroke();

    // Banner Text rendering
    ctx.fillStyle = '#ffffff';
    // Dynamic text sizing based on length limits overflow
    let fontSize = 44;
    if (caption.length > 25) fontSize = 34;
    if (caption.length > 40) fontSize = 26;
    ctx.font = `bold ${fontSize}px 'Arial', sans-serif`;
    ctx.textAlign = "center";
    ctx.textBaseline = "middle";
    ctx.fillText(caption, width / 2, 72);
    
    ctx.restore();

    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

A tool that combines a user’s photo into a nostalgic reunion-themed collage with scattered Polaroid-style frames, festive confetti, and a celebratory banner. Useful for creating personalized greeting cards, social media posts, or digital keepsakes for friend reunions, class get-togethers, or group celebrations.

Leave a Reply

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