Please bookmark this page to avoid losing your image tool!

Image Surprise Generator For Boys

(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.
/**
 * Image Surprise Generator for Boys (Сюрприз для мальчиков)
 * Transforms an image into an "Action Figure / Toy Box" graphic.
 * 
 * @param {HTMLImageElement} originalImg - The input image.
 * @param {string} titleText - The main title text.
 * @param {string} themePrefix - The text above the title.
 * @param {string} themeColor - The background color of the box.
 * @param {string} badgeAge - The text for the age recommendation badge.
 * @param {string} stickers - Comma-separated list of emojis to use as stickers.
 */
function processImage(
    originalImg,
    titleText = "МЕГА СЮРПРИЗ!",
    themePrefix = "СУПЕР ГЕРОЙ",
    themeColor = "#e62e00",
    badgeAge = "5+",
    stickers = "⚡,💥,🚀,⚽"
) {
    const canvas = document.createElement("canvas");
    const ctx = canvas.getContext("2d");

    // Polyfill for roundRect if it doesn't exist in older browsers
    if (!ctx.roundRect) {
        ctx.roundRect = function (x, y, width, height, radius) {
            this.beginPath();
            this.moveTo(x + radius, y);
            this.lineTo(x + width - radius, y);
            this.quadraticCurveTo(x + width, y, x + width, y + radius);
            this.lineTo(x + width, y + height - radius);
            this.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
            this.lineTo(x + radius, y + height);
            this.quadraticCurveTo(x, y + height, x, y + height - radius);
            this.lineTo(x, y + radius);
            this.quadraticCurveTo(x, y, x + radius, y);
            this.closePath();
            return this;
        };
    }

    // Determine dimensions responsive to the uploaded image resolution
    const imgW = originalImg.width;
    const imgH = originalImg.height;
    const maxDim = Math.max(imgW, imgH);

    // Dynamic padding calculations
    const padX = maxDim * 0.18;
    const padTop = maxDim * 0.35;
    const padBot = maxDim * 0.25;

    const w = imgW + padX * 2;
    const h = imgH + padTop + padBot;
    
    canvas.width = w;
    canvas.height = h;

    // 1. Draw Box Base Background
    ctx.fillStyle = themeColor;
    ctx.fillRect(0, 0, w, h);

    // Apply a black-and-white gradient overlay to add depth/shading
    const shadeGrad = ctx.createLinearGradient(0, 0, 0, h);
    shadeGrad.addColorStop(0, "rgba(255, 255, 255, 0.25)");
    shadeGrad.addColorStop(0.5, "rgba(0, 0, 0, 0)");
    shadeGrad.addColorStop(1, "rgba(0, 0, 0, 0.6)");
    ctx.fillStyle = shadeGrad;
    ctx.fillRect(0, 0, w, h);

    // 2. Draw Sunburst / Action Lines for that "Comic/Toy" feel
    ctx.save();
    ctx.translate(w / 2, h / 2);
    ctx.fillStyle = "rgba(255, 255, 255, 0.15)";
    const rays = 24;
    for (let i = 0; i < rays; i++) {
        ctx.beginPath();
        ctx.moveTo(0, 0);
        const a1 = (i * Math.PI * 2) / rays;
        const a2 = ((i + 0.5) * Math.PI * 2) / rays;
        // Extend rays beyond the borders
        const rayLen = w + h;
        ctx.lineTo(Math.cos(a1) * rayLen, Math.sin(a1) * rayLen);
        ctx.lineTo(Math.cos(a2) * rayLen, Math.sin(a2) * rayLen);
        ctx.closePath();
        ctx.fill();
    }
    ctx.restore();

    // 3. Draw Peg Hole (the hanger hole at the top of action figure boxes)
    const pegWidth = w * 0.15;
    const pegHeight = maxDim * 0.04;
    const pegY = padTop * 0.25;
    const pegRad = pegHeight / 2;
    
    ctx.fillStyle = "#ffffff";
    ctx.roundRect((w - pegWidth) / 2, pegY, pegWidth, pegHeight, pegRad);
    ctx.fill();
    
    // Cut out the inner part to simulate a hole
    ctx.globalCompositeOperation = 'destination-out';
    ctx.fillStyle = "black";
    ctx.roundRect((w - pegWidth) / 2 + pegHeight/2, pegY + pegHeight/4, pegWidth - pegHeight, pegHeight/2, pegHeight/4);
    ctx.fill();
    ctx.globalCompositeOperation = 'source-over';

    // 4. Draw the Blister Pack dark cardboard background outline
    const blisterPad = maxDim * 0.05;
    const blisterX = padX - blisterPad;
    const blisterY = padTop - blisterPad;
    const blisterW = imgW + blisterPad * 2;
    const blisterH = imgH + blisterPad * 2;

    ctx.fillStyle = "#111111";
    ctx.shadowColor = "rgba(0,0,0,0.8)";
    ctx.shadowBlur = maxDim * 0.02;
    ctx.shadowOffsetY = maxDim * 0.015;
    ctx.roundRect(blisterX, blisterY, blisterW, blisterH, blisterPad);
    ctx.fill();
    ctx.shadowColor = "transparent"; // Reset shadow

    // 5. Draw the Actual Original Image
    ctx.drawImage(originalImg, padX, padTop, imgW, imgH);

    // Apply a white border directly around the image (resembles a card cut inside)
    ctx.lineWidth = maxDim * 0.01;
    ctx.strokeStyle = "#ffffff";
    ctx.strokeRect(padX, padTop, imgW, imgH);

    // 6. Draw Plastic Blister Glare/Highlights (makes it look like a toy window)
    ctx.save();
    ctx.beginPath();
    ctx.roundRect(blisterX, blisterY, blisterW, blisterH, blisterPad);
    ctx.clip(); // Ensure reflections stay inside the blister bounds

    // Main volume glare
    const pGrad = ctx.createLinearGradient(blisterX, blisterY, blisterX + blisterW, blisterY + blisterH);
    pGrad.addColorStop(0, "rgba(255, 255, 255, 0.4)");
    pGrad.addColorStop(0.3, "rgba(255, 255, 255, 0.05)");
    pGrad.addColorStop(0.7, "rgba(255, 255, 255, 0.0)");
    pGrad.addColorStop(1, "rgba(255, 255, 255, 0.2)");
    ctx.fillStyle = pGrad;
    ctx.fill();

    // Sharp diagonal window reflections
    ctx.beginPath();
    ctx.moveTo(blisterX - blisterW, blisterY - blisterH);
    ctx.lineTo(blisterX + blisterW * 2, blisterY + blisterH * 2 - blisterH * 0.4);
    ctx.lineTo(blisterX + blisterW * 2, blisterY + blisterH * 2);
    ctx.lineTo(blisterX - blisterW, blisterY - blisterH + blisterH * 0.4);
    ctx.fillStyle = "rgba(255, 255, 255, 0.12)";
    ctx.fill();
    ctx.restore();

    // 7. Draw Typography / Branding Titles
    const fontSizeTop = maxDim * 0.14;
    ctx.textAlign = "center";
    ctx.textBaseline = "middle";

    ctx.save();
    // Position titles in the header padded area
    ctx.translate(w / 2, padTop * 0.6);
    ctx.rotate(-0.04); // Give it a dynamic, youthful tilt

    // Draw Theme Prefix (e.g. "СУПЕР ГЕРОЙ")
    const subFontSize = fontSizeTop * 0.4;
    ctx.font = `italic 900 ${subFontSize}px Impact, sans-serif`;
    ctx.fillStyle = "#ffffff";
    ctx.shadowColor = "rgba(0,0,0,0.8)";
    ctx.shadowBlur = maxDim * 0.01;
    ctx.fillText(themePrefix, -w * 0.1, -fontSizeTop * 0.4);

    // Draw Main Title 
    ctx.font = `italic 900 ${fontSizeTop}px Impact, sans-serif`;
    ctx.shadowColor = "transparent";
    
    // Thick black outline
    ctx.lineWidth = maxDim * 0.02;
    ctx.strokeStyle = "#000000";
    ctx.strokeText(titleText, 0, 0);

    // Text Inner Gradient
    const textGrad = ctx.createLinearGradient(0, -fontSizeTop / 2, 0, fontSizeTop / 2);
    textGrad.addColorStop(0, "#ffff00");
    textGrad.addColorStop(1, "#ff8800");
    ctx.fillStyle = textGrad;
    ctx.fillText(titleText, 0, 0);

    // White highlight stroke
    ctx.lineWidth = maxDim * 0.006;
    ctx.strokeStyle = "#ffffff";
    ctx.strokeText(titleText, 0, 0);
    ctx.restore();

    // 8. Draw "Ages 5+" circular badge
    ctx.save();
    ctx.translate(w - padX * 0.8, padTop + imgH + padBot * 0.45);
    ctx.rotate(-0.1);
    const r1 = maxDim * 0.08;
    
    // Badge Background
    ctx.beginPath();
    ctx.arc(0, 0, r1, 0, Math.PI * 2);
    ctx.fillStyle = "#ff0000";
    ctx.shadowColor = "rgba(0,0,0,0.6)";
    ctx.shadowBlur = maxDim * 0.01;
    ctx.shadowOffsetY = maxDim * 0.01;
    ctx.fill();
    ctx.shadowColor = "transparent";
    
    // Badge Border
    ctx.lineWidth = maxDim * 0.01;
    ctx.strokeStyle = "#ffffff";
    ctx.stroke();

    // Badge Text
    ctx.fillStyle = "#ffffff";
    ctx.font = `bold ${r1 * 0.35}px Arial, sans-serif`;
    ctx.fillText("AGES", 0, -r1 * 0.2);
    ctx.font = `900 ${r1 * 0.65}px Arial, sans-serif`;
    ctx.fillText(badgeAge, 0, r1 * 0.35);
    ctx.restore();

    // Small Warning Footer Text
    ctx.font = `bold ${maxDim * 0.03}px Arial, sans-serif`;
    ctx.fillStyle = "rgba(255,255,255,0.9)";
    ctx.textAlign = "center";
    ctx.fillText("ВНИМАНИЕ: Зашкаливающий уровень крутости!", w / 2, h - padBot * 0.25);

    // 9. Draw Dynamic Cool Stickers!
    const stickerArr = stickers.split(",").map(s => s.trim()).filter(s => s);
    const s1 = stickerArr[0] || "💥";
    const s2 = stickerArr[1] || "🚀";
    const s3 = stickerArr[2] || "⚡";
    const s4 = stickerArr[3] || "⚽";

    // Helper to draw a sticker circle with emoji
    const drawEmojiSticker = (emoji, x, y, size, rot) => {
        ctx.save();
        ctx.translate(x, y);
        ctx.rotate(rot);

        // White background of the sticker
        ctx.beginPath();
        ctx.arc(0, 0, size * 0.55, 0, Math.PI * 2);
        ctx.fillStyle = "#ffffff";
        ctx.shadowColor = "rgba(0,0,0,0.5)";
        ctx.shadowBlur = size * 0.15;
        ctx.shadowOffsetY = size * 0.1;
        ctx.fill();

        ctx.shadowColor = "transparent";
        ctx.lineWidth = size * 0.04;
        ctx.strokeStyle = "#000000";
        ctx.stroke();

        // Emoji drawing
        ctx.font = `${size * 0.65}px sans-serif`;
        ctx.textAlign = "center";
        ctx.textBaseline = "middle";
        ctx.fillText(emoji, 0, size * 0.04);
        ctx.restore();
    };

    // Distribute stickers around the packaging
    drawEmojiSticker(s1, padX * 0.45, padTop * 0.8, maxDim * 0.16, -0.2);
    drawEmojiSticker(s2, w - padX * 0.45, padTop * 0.6, maxDim * 0.14, 0.25);
    drawEmojiSticker(s3, padX * 0.5, h - padBot * 0.6, maxDim * 0.15, -0.3);
    drawEmojiSticker(s4, w - padX * 0.35, h - padBot * 0.5, maxDim * 0.13, 0.15);

    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 Image Surprise Generator for Boys transforms any uploaded photo into a dynamic, action-figure-style toy box graphic. This tool applies a professional packaging effect, complete with a colorful themed background, comic-style sunburst rays, a simulated plastic blister window with realistic glares, and custom branding text. You can personalize the look by customizing the title, theme colors, age recommendation badges, and adding fun emoji stickers. It is an ideal tool for creating fun, customized digital memorabilia, personalized birthday cards, or playful social media content that makes people look like real-life action figures.

Leave a Reply

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