Please bookmark this page to avoid losing your image tool!

Image Stranger Things Movie Poster Creator

(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", taglineText = "THE WORLD IS TURNING UPSIDE DOWN", actorNames = "WINONA RYDER, DAVID HARBOUR, FINN WOLFHARD, MILLIE BOBBY BROWN", releaseDate = "JULY 15") {

    const P_WIDTH = 600;
    const P_HEIGHT = 900;
    const mainTitleColor = '#E50914'; // A strong red, similar to Netflix/Stranger Things
    const glowColor = '#FF0000'; // Bright red glow

    // --- Font Loading ---
    // Ensure fonts are loaded. We'll use 'Bungee' for the title and 'Montserrat' for other text.
    // These are Google Fonts and will be imported via a dynamically added style tag.
    let fontsSuccessfullyLoaded = false;
    try {
        if (!document.getElementById('stranger-poster-fonts-style')) {
            const style = document.createElement('style');
            style.id = 'stranger-poster-fonts-style';
            style.innerHTML = `
                @import url('https://fonts.googleapis.com/css2?family=Bungee&family=Montserrat:wght@300;400;700&display=swap');
            `;
            document.head.appendChild(style);
        }
        // Wait for fonts to be available for rendering on canvas
        await document.fonts.load('1em Bungee');
        await document.fonts.load('1em Montserrat'); // Check for regular weight
        await document.fonts.load('bold 1em Montserrat'); // Check for bold
        await document.fonts.load('300 1em Montserrat'); // Check for light
        fontsSuccessfullyLoaded = true;
    } catch (e) {
        console.warn("Font loading failed or document.fonts API not fully supported. Using fallback fonts.", e);
        // The script will continue with browser default fonts if this fails.
    }

    const titleFontName = fontsSuccessfullyLoaded ? 'Bungee' : 'sans-serif';
    const textFontName = fontsSuccessfullyLoaded ? 'Montserrat' : 'sans-serif';

    // --- Canvas Setup ---
    const canvas = document.createElement('canvas');
    canvas.width = P_WIDTH;
    canvas.height = P_HEIGHT;
    const ctx = canvas.getContext('2d');

    // --- Draw Background Image (Cover and Center) ---
    ctx.fillStyle = '#000000'; // Fallback background color
    ctx.fillRect(0, 0, P_WIDTH, P_HEIGHT);

    if (originalImg && originalImg.width > 0 && originalImg.height > 0) {
        const imgAspect = originalImg.width / originalImg.height;
        const canvasAspect = P_WIDTH / P_HEIGHT;
        let sx = 0, sy = 0, sWidth = originalImg.width, sHeight = originalImg.height;

        if (imgAspect > canvasAspect) { // Image wider than canvas: crop image sides
            sWidth = originalImg.height * canvasAspect;
            sx = (originalImg.width - sWidth) / 2;
        } else if (imgAspect < canvasAspect) { // Image taller than canvas: crop image top/bottom
            sHeight = originalImg.width / canvasAspect;
            sy = (originalImg.height - sHeight) / 2;
        }
        ctx.drawImage(originalImg, sx, sy, sWidth, sHeight, 0, 0, P_WIDTH, P_HEIGHT);
    }

    // Dark overlay for mood
    ctx.fillStyle = 'rgba(0, 0, 0, 0.4)'; // Adjust opacity as needed
    ctx.fillRect(0, 0, P_WIDTH, P_HEIGHT);

    // --- Title Text Styling and Drawing ---
    let titleLine1 = "";
    let titleLine2 = "";
    const words = titleText.toUpperCase().split(" ");

    if (titleText.toUpperCase() === "STRANGER THINGS") { // Specific handling for the classic
        titleLine1 = "STRANGER";
        titleLine2 = "THINGS";
    } else if (words.length === 1) {
        titleLine1 = words[0];
    } else if (words.length >= 2) { // Split into two lines for other titles
        const splitPoint = Math.ceil(words.length / 2);
        titleLine1 = words.slice(0, splitPoint).join(" ");
        titleLine2 = words.slice(splitPoint).join(" ");
    }
    
    // Calculate Title Font Size dynamically
    let FONT_SIZE_TITLE = 90; // Initial large size
    const maxTitleWidth = P_WIDTH * 0.90; // Title should occupy max 90% of poster width
    ctx.textAlign = 'center';
    
    const textToMeasureForSize = titleLine2 && titleLine2.length > titleLine1.length ? titleLine2 : titleLine1;
    
    ctx.font = `${FONT_SIZE_TITLE}px ${titleFontName}`;
    while (ctx.measureText(textToMeasureForSize).width > maxTitleWidth && FONT_SIZE_TITLE > 15) {
        FONT_SIZE_TITLE--;
        ctx.font = `${FONT_SIZE_TITLE}px ${titleFontName}`;
    }
    // If split, ensure the other line also fits with the determined font size (if it was longer)
    if (titleLine2 && titleLine1.length > titleLine2.length) {
         while (ctx.measureText(titleLine1).width > maxTitleWidth && FONT_SIZE_TITLE > 15) {
            FONT_SIZE_TITLE--;
            ctx.font = `${FONT_SIZE_TITLE}px ${titleFontName}`;
        }
    }


    const drawStyledTitleLine = (text, yPos, currentFontSize, font, color, shadowColor, context) => {
        context.textBaseline = 'middle'; // Critical for vertical centering
        const isSpecialStrangerThingsWord = (text === "STRANGER" || text === "THINGS");

        if (isSpecialStrangerThingsWord && text.length > 2) { // Apply special S-T-Y-L-E
            const scaleFactor = 1.2; // First/last letters larger
            const parts = [];
            parts.push({ char: text[0], size: currentFontSize * scaleFactor });
            parts.push({ char: text.substring(1, text.length - 1), size: currentFontSize });
            parts.push({ char: text[text.length - 1], size: currentFontSize * scaleFactor });

            let totalWidth = 0;
            parts.forEach(part => {
                context.font = `${part.size}px ${font}`;
                totalWidth += context.measureText(part.char).width;
            });

            let currentX = (P_WIDTH - totalWidth) / 2;
            context.textAlign = 'left'; // Temporarily switch for piece-by-piece drawing

            parts.forEach(part => {
                context.font = `${part.size}px ${font}`;
                // Draw shadow/glow layer
                context.shadowColor = shadowColor;
                context.shadowBlur = 20; // Adjust glow intensity
                context.shadowOffsetX = 0;
                context.shadowOffsetY = 0;
                context.fillStyle = color; // Glow color for shadowed text
                context.fillText(part.char, currentX, yPos);

                // Draw main text layer (crisp, on top)
                context.shadowColor = 'transparent';
                context.fillStyle = color;
                context.fillText(part.char, currentX, yPos);
                
                currentX += context.measureText(part.char).width;
            });
            context.textAlign = 'center'; // Reset textAlign
        } else { // Standard drawing for other titles
            context.font = `${currentFontSize}px ${font}`;
            context.shadowColor = shadowColor;
            context.shadowBlur = 20;
            context.shadowOffsetX = 0;
            context.shadowOffsetY = 0;
            context.fillStyle = color;
            context.fillText(text, P_WIDTH / 2, yPos);

            context.shadowColor = 'transparent';
            context.fillStyle = color;
            context.fillText(text, P_WIDTH / 2, yPos);
        }
    };
    
    // Position and draw title lines
    const titleY1 = P_HEIGHT * (titleLine2 ? 0.18 : 0.22); // Adjust based on 1 or 2 lines
    const titleLineHeight = FONT_SIZE_TITLE * (titleLine2 ? 1.0 : 1.0); // Compact for Bungee

    drawStyledTitleLine(titleLine1, titleY1, FONT_SIZE_TITLE, titleFontName, mainTitleColor, glowColor, ctx);
    if (titleLine2) {
        const titleY2 = titleY1 + titleLineHeight;
        drawStyledTitleLine(titleLine2, titleY2, FONT_SIZE_TITLE, titleFontName, mainTitleColor, glowColor, ctx);
    }
    ctx.shadowColor = 'transparent'; // Reset all shadows

    // --- Draw Tagline ---
    const taglineFontSize = Math.max(12, P_WIDTH / 38);
    ctx.font = `italic ${taglineFontSize}px ${textFontName}`;
    ctx.fillStyle = '#FFFFFF';
    const taglineY = (titleLine2 ? titleY1 + titleLineHeight : titleY1) + FONT_SIZE_TITLE * 0.7 + taglineFontSize;
    ctx.fillText(taglineText.toUpperCase(), P_WIDTH / 2, taglineY);

    // --- Draw Actor Names (Billing Block Style) ---
    const actorsFontSize = Math.max(8, P_WIDTH / 60);
    ctx.font = `300 ${actorsFontSize}px ${textFontName}`; // Light weight
    ctx.fillStyle = '#B0B0B0'; // Light Grey
    const actorsArray = actorNames.split(',').map(name => name.trim().toUpperCase());
    const actorsLine = actorsArray.join('   '); // Typical billing block uses spaces, not dots usually
    const actorsY = P_HEIGHT - P_HEIGHT * 0.10;
    
    // Simple fit for actors line, reduce font size if too long
    let finalActorsFontSize = actorsFontSize;
    while(ctx.measureText(actorsLine).width > P_WIDTH * 0.95 && finalActorsFontSize > 6) {
        finalActorsFontSize--;
        ctx.font = `300 ${finalActorsFontSize}px ${textFontName}`;
    }
    ctx.fillText(actorsLine, P_WIDTH / 2, actorsY);


    // --- Draw Release Date ---
    const releaseFontSize = Math.max(10, P_WIDTH / 48);
    ctx.font = `normal ${releaseFontSize}px ${textFontName}`; // Normal weight, or bold
    ctx.fillStyle = '#FFFFFF';
    const releaseY = actorsY + finalActorsFontSize * 1.8;
    ctx.fillText(releaseDate.toUpperCase(), P_WIDTH / 2, releaseY);

    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 Stranger Things Movie Poster Creator allows users to create custom movie posters inspired by the popular ‘Stranger Things’ series. Users can upload an image and personalize the poster by adding a title, tagline, actor names, and a release date. The tool features a visually appealing design, using thematic colors and fonts that evoke the show’s atmosphere. Real-world use cases include creating fan art, promoting events, or designing unique gifts for fans of the series.

Leave a Reply

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