Please bookmark this page to avoid losing your image tool!

Photo Creation With Stranger Things Themed Background And Text

(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, titleText = 'STRANGER THINGS', subtitleText = 'CHAPTER FIVE', characterCount = 4, particleCount = 300) {

    /**
     * Dynamically loads the 'Benguiat' font from Google Fonts.
     * This is the iconic font used for the Stranger Things title.
     */
    const loadStrangerFont = async () => {
        const fontName = 'Benguiat';
        const styleId = 'google-font-stranger-things';

        if (!document.getElementById(styleId)) {
            const fontUrl = `https://fonts.googleapis.com/css2?family=${fontName}:wght@700&display=swap`;
            const style = document.createElement('style');
            style.id = styleId;
            style.innerHTML = `@import url('${fontUrl}');`;
            document.head.appendChild(style);
        }

        try {
            await document.fonts.load(`700 10px "${fontName}"`);
        } catch (e) {
            console.error("Font could not be loaded.", e);
            // The function will continue with a default font if Benguiat fails to load.
        }
        return fontName;
    };

    const fontName = await loadStrangerFont();

    // Setup canvas with a 16:9 aspect ratio
    const canvas = document.createElement('canvas');
    canvas.width = 1280;
    canvas.height = 720;
    const ctx = canvas.getContext('2d');

    const rand = (min, max) => Math.random() * (max - min) + min;

    // 1. Draw Background and Atmosphere
    const drawBackground = () => {
        // Dark red/black gradient for an ominous sky
        const bgGradient = ctx.createRadialGradient(canvas.width / 2, canvas.height, 0, canvas.width / 2, canvas.height, canvas.width * 0.8);
        bgGradient.addColorStop(0, '#1a0000');
        bgGradient.addColorStop(1, '#000000');
        ctx.fillStyle = bgGradient;
        ctx.fillRect(0, 0, canvas.width, canvas.height);
    };

    // 2. Draw Mind Flayer (procedurally)
    const drawMindFlayer = () => {
        ctx.save();
        ctx.strokeStyle = 'rgba(20, 0, 0, 0.8)';
        ctx.fillStyle = 'rgba(10, 0, 0, 0.7)';
        ctx.lineWidth = 2;
        const centerX = canvas.width / 2;
        const centerY = canvas.height * 0.2;

        // Draw multiple legs/tentacles
        for (let i = 0; i < 7; i++) {
            ctx.beginPath();
            ctx.moveTo(centerX + rand(-30, 30), centerY + rand(-30, 30));

            const endX = rand(0, canvas.width);
            const endY = rand(canvas.height * 0.6, canvas.height * 1.2);
            const cp1x = centerX + rand(-250, 250);
            const cp1y = centerY + rand(100, 300);
            const cp2x = (centerX + endX) / 2 + rand(-200, 200);
            const cp2y = (centerY + endY) / 2 + rand(-100, 200);

            ctx.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, endX, endY);
            ctx.stroke();

            // Draw smaller branches off the main tentacles
            for (let j = 0; j < 2; j++) {
                const branchStartT = rand(0.3, 0.7);
                const t = branchStartT; const u = 1 - t;
                const tu = u*u; const tt = t*t;
                const pX = u*tu*centerX + 3*u*t*cp1x + 3*u*tt*cp2x + t*tt*endX;
                const pY = u*tu*centerY + 3*u*t*cp1y + 3*u*tt*cp2y + t*tt*endY;
                
                ctx.moveTo(pX, pY);
                ctx.quadraticCurveTo(
                    pX + rand(-100, 100), pY + rand(50, 100),
                    pX + rand(-150, 150), pY + rand(100, 200)
                );
                ctx.stroke();
            }
        }
        ctx.restore();
    };
    
    // 3. Draw floating ember-like particles from the Upside Down
    const drawParticles = () => {
        for (let i = 0; i < particleCount; i++) {
            ctx.beginPath();
            const x = rand(0, canvas.width);
            const y = rand(0, canvas.height);
            const size = rand(1, 3);
            const opacity = rand(0.1, 0.7);
            ctx.fillStyle = `rgba(255, 30, 30, ${opacity})`;
            ctx.arc(x, y, size, 0, Math.PI * 2);
            ctx.fill();
        }
    };

    // 4. Draw character silhouettes
    const drawSilhouette = (x, y, scale = 1) => {
        const headR = 8 * scale;
        const bodyW = 18 * scale;
        const bodyH = 25 * scale;
        const legH = 22 * scale;
        const legSpread = 15 * scale;

        const neckY = y - legH - bodyH;
        const hipY = y - legH;

        ctx.fillStyle = '#000';
        
        ctx.beginPath();
        ctx.arc(x, neckY - headR, headR, 0, Math.PI * 2);
        ctx.fill();
        ctx.fillRect(x - bodyW / 2, neckY, bodyW, bodyH);
        
        ctx.beginPath();
        ctx.moveTo(x, hipY);
        ctx.lineTo(x - legSpread / 2, y);
        ctx.moveTo(x, hipY);
        ctx.lineTo(x + legSpread / 2, y);
        ctx.strokeStyle = '#000';
        ctx.lineWidth = 6 * scale;
        ctx.stroke();
    };

    // 5. Draw the user's image and blend it into the scene
    const drawUserImage = () => {
        const imgMaxHeight = canvas.height * 0.6;
        const imgMaxWidth = canvas.width * 0.4;
        let imgHeight = originalImg.height;
        let imgWidth = originalImg.width;

        const ratio = imgWidth / imgHeight;
        if (imgHeight > imgMaxHeight) {
            imgHeight = imgMaxHeight;
            imgWidth = imgHeight * ratio;
        }
        if (imgWidth > imgMaxWidth) {
            imgWidth = imgMaxWidth;
            imgHeight = imgWidth / ratio;
        }

        const imgX = (canvas.width - imgWidth) / 2;
        const imgY = canvas.height - imgHeight;

        ctx.drawImage(originalImg, imgX, imgY, imgWidth, imgHeight);

        // Apply a red tint to make the image fit the environment
        ctx.globalCompositeOperation = 'color';
        ctx.fillStyle = 'rgba(180, 20, 20, 0.7)';
        ctx.fillRect(imgX, imgY, imgWidth, imgHeight);
        ctx.globalCompositeOperation = 'source-over';
        
        return { imgX, imgWidth };
    };

    // 6. Draw the iconic text
    const drawText = () => {
        const primaryRed = '#e62e25';
        ctx.fillStyle = primaryRed;
        ctx.textAlign = 'center';
        ctx.textBaseline = 'middle';
        
        // Add the signature red glow
        ctx.shadowColor = primaryRed;
        ctx.shadowBlur = 25;

        // Draw title with larger first and last letters
        const y = canvas.height * 0.18;
        const baseFontSize = canvas.width / 13;
        const smallFontSize = baseFontSize * 0.85;
        const firstChar = titleText.substring(0, 1).toUpperCase();
        const lastChar = titleText.substring(titleText.length - 1).toUpperCase();
        const middleText = titleText.substring(1, titleText.length - 1).toUpperCase();

        ctx.font = `700 ${baseFontSize}px "${fontName}"`;
        const firstCharWidth = ctx.measureText(firstChar).width;
        const lastCharWidth = ctx.measureText(lastChar).width;

        ctx.font = `700 ${smallFontSize}px "${fontName}"`;
        const middleTextWidth = ctx.measureText(middleText).width;

        const totalWidth = firstCharWidth + middleTextWidth + lastCharWidth;
        let currentX = (canvas.width - totalWidth) / 2;

        ctx.font = `700 ${baseFontSize}px "${fontName}"`;
        ctx.fillText(firstChar, currentX + firstCharWidth / 2, y);
        currentX += firstCharWidth;

        ctx.font = `700 ${smallFontSize}px "${fontName}"`;
        ctx.fillText(middleText, currentX + middleTextWidth / 2, y);
        currentX += middleTextWidth;

        ctx.font = `700 ${baseFontSize}px "${fontName}"`;
        ctx.fillText(lastChar, currentX + lastCharWidth / 2, y);

        // Draw subtitle
        const subtitleFontSize = canvas.width / 40;
        ctx.font = `700 ${subtitleFontSize}px "${fontName}"`;
        const subtitleY = y + baseFontSize * 0.6;
        ctx.fillText(subtitleText.toUpperCase(), canvas.width / 2, subtitleY);

        // Reset shadow for subsequent drawings
        ctx.shadowColor = 'transparent';
        ctx.shadowBlur = 0;
    };


    // --- Main Drawing Execution ---
    
    drawBackground();
    drawMindFlayer();
    drawParticles();
    
    // Draw a black ground plane
    ctx.fillStyle = '#000';
    ctx.fillRect(0, canvas.height * 0.95, canvas.width, canvas.height * 0.05);

    const { imgX, imgWidth } = drawUserImage();

    // Place character silhouettes around the user image
    const groundY = canvas.height - (canvas.height * 0.05);
    const leftCount = Math.ceil(characterCount / 2);
    const rightCount = Math.floor(characterCount / 2);
    
    for (let i = 0; i < leftCount; i++) {
        const x = rand(canvas.width * 0.05, imgX - 50);
        const scale = rand(0.7, 1.1);
        drawSilhouette(x, groundY, scale);
    }
    for (let i = 0; i < rightCount; i++) {
       const x = rand(imgX + imgWidth + 50, canvas.width * 0.95);
       const scale = rand(0.7, 1.1);
       drawSilhouette(x, groundY, scale);
    }

    drawText();

    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 ‘Photo Creation with Stranger Things Themed Background and Text’ tool allows users to create unique images that incorporate a themed background inspired by the popular series ‘Stranger Things’. Users can upload their own images, which will be blended into a dramatic scene complete with ominous backgrounds, floating particles, and character silhouettes. The tool provides customization options such as title and subtitle text, as well as the number of character silhouettes, allowing for personalization in the design. This tool is ideal for fans of ‘Stranger Things’ looking to create stylized images for social media, digital art projects, or themed events.

Leave a Reply

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