Please bookmark this page to avoid losing your image tool!

Image Space Explorer’s Log 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,
    stardate = "Stardate 77492.1",
    location = "Alpha Centauri System",
    subject = "First Contact Protocol",
    logEntry = "Log entry: Encountered an unidentified vessel displaying non-hostile patterns. Attempting to establish communication. The visual data from the main screen has been archived.",
    panelColor = "#00FFFF",      // Cyan for borders, lines
    strongTextColor = "#FFFFFF", // White for labels like "STARDATE:"
    textColor = "#90EE90",       // Light green for values and main text
    backgroundColor = "#0A0A2A", // Very dark blue for background
    fontName = "Orbitron",       // Primary font family name
    baseFontSize = 16            // Base font size in pixels
) {

    // Helper function to load web font (defined inside to be self-contained)
    async function loadWebFont(fontFamilyToLoad, fontUrl) {
        if (!document.fonts) {
             // console.warn("FontFace API not supported. Cannot dynamically load font.");
            return false; // FontFace API not supported
        }
        
        try {
            // Check if font is already available using document.fonts.check()
            if (document.fonts.check(`1em "${fontFamilyToLoad}"`)) {
                // console.log(`Font "${fontFamilyToLoad}" is already available or pre-loaded.`);
                return true;
            }
        } catch (e) {
            // console.warn("Error checking existing fonts with document.fonts.check():", e);
        }
        
        // Fallback or more detailed check: Iterate existing FontFace objects
        // This step might be redundant if document.fonts.check() is reliable.
        try {
            for (const fontFace of document.fonts) {
                if (fontFace.family === fontFamilyToLoad && fontFace.status === 'loaded') {
                    // console.log(`Font "${fontFamilyToLoad}" found in document.fonts as loaded.`);
                    return true;
                }
            }
        } catch (e) {
            // console.warn("Error iterating document.fonts:", e);
        }


        // If not loaded, try to load it via FontFace API
        const font = new FontFace(fontFamilyToLoad, `url(${fontUrl})`);
        try {
            await font.load();
            document.fonts.add(font);
            // console.log(`Font "${fontFamilyToLoad}" loaded and added from ${fontUrl}.`);
            return true;
        } catch (e) {
            console.error(`Failed to load font "${fontFamilyToLoad}" from ${fontUrl}:`, e);
            return false;
        }
    }

    // Helper function for text wrapping (defined inside)
    function getWrappedTextLines(context, text, maxWidth, lineHeight) {
        const words = text.split(' ');
        let line = '';
        const linesArray = [];
        
        for (let n = 0; n < words.length; n++) {
            const testLine = line + words[n] + ' ';
            const metrics = context.measureText(testLine);
            const testWidth = metrics.width;
            if (testWidth > maxWidth && n > 0 && line.length > 0) { // line.length > 0 to handle very long first word
                linesArray.push(line.trim());
                line = words[n] + ' ';
            } else {
                line = testLine;
            }
        }
        if (line.trim().length > 0) { // Push any remaining text
            linesArray.push(line.trim());
        }
        
        const totalHeight = linesArray.length * lineHeight;
        return { lines: linesArray, totalHeight: totalHeight };
    }

    const orbitronFontCdnUrl = "https://cdn.jsdelivr.net/fontsource/fonts/orbitron@5.0.3/latin-400-normal.woff2";
    let actualFontFamilyString = `"${fontName}", Consolas, 'Courier New', monospace`;

    if (fontName.toLowerCase() === "orbitron") {
        const loaded = await loadWebFont("Orbitron", orbitronFontCdnUrl);
        if (!loaded) {
            // console.warn("Orbitron font failed to load, using fallbacks.");
            // actualFontFamilyString will already include fallbacks.
        }
    }
    
    // --- Layout Constants ---
    const mainPadding = 20;
    const sectionSpacing = 15; // Spacing between header/image/log sections
    const smallGap = 5;      // Small gap (e.g., between title and text)
    const imageBorderThickness = 2;
    const minContentWidthForText = 300; // Min width for text readability
    
    const MAX_ALLOWED_IMG_WIDTH = 600;
    const MAX_ALLOWED_IMG_HEIGHT = 400;

    // --- Calculate dynamic dimensions (first pass) ---
    
    // Image dimensions
    let scale = 1.0;
    if (originalImg.naturalWidth > 0 && originalImg.naturalHeight > 0) {
       scale = Math.min(MAX_ALLOWED_IMG_WIDTH / originalImg.naturalWidth, MAX_ALLOWED_IMG_HEIGHT / originalImg.naturalHeight, 1.0);
    } else { 
       scale = 0; // Invalid image, will result in 0x0 display size
    }
    const imgDispWidth = originalImg.naturalWidth * scale;
    const imgDispHeight = originalImg.naturalHeight * scale;

    const contentWidth = Math.max(imgDispWidth, minContentWidthForText);
    const imgXOffset = (contentWidth - imgDispWidth) / 2;

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

    const headerFontSize = baseFontSize;
    tempCtx.font = `${headerFontSize}px ${actualFontFamilyString}`;
    const headerLineHeight = headerFontSize * 1.4; 
    let currentTotalHeight = mainPadding;
    currentTotalHeight += headerLineHeight * 3; // Stardate, Location, Subject

    currentTotalHeight += sectionSpacing;
    currentTotalHeight += imgDispHeight;
    currentTotalHeight += sectionSpacing;

    tempCtx.font = `${headerFontSize}px ${actualFontFamilyString}`;
    currentTotalHeight += headerLineHeight; // For "LOG ENTRY:" title
    currentTotalHeight += smallGap;

    const logEntryFontSize = Math.round(baseFontSize * 0.9);
    tempCtx.font = `${logEntryFontSize}px ${actualFontFamilyString}`;
    const logEntryLineHeight = logEntryFontSize * 1.4;
    const wrappedLogEntry = getWrappedTextLines(tempCtx, logEntry, contentWidth, logEntryLineHeight);
    currentTotalHeight += wrappedLogEntry.totalHeight;

    currentTotalHeight += mainPadding; 

    // --- Final Canvas Setup ---
    const canvas = document.createElement('canvas');
    canvas.width = contentWidth + mainPadding * 2;
    canvas.height = Math.max(currentTotalHeight, 200); // Ensure minimum height
    const ctx = canvas.getContext('2d');

    // --- Drawing Operations (second pass) ---
    ctx.fillStyle = backgroundColor;
    ctx.fillRect(0, 0, canvas.width, canvas.height);

    ctx.strokeStyle = panelColor;
    ctx.lineWidth = 1;
    ctx.strokeRect(mainPadding / 4, mainPadding / 4, canvas.width - mainPadding / 2, canvas.height - mainPadding / 2);
    
    let currentY = mainPadding;
    const textX = mainPadding;

    ctx.font = `${headerFontSize}px ${actualFontFamilyString}`;
    const drawHeaderLine = (label, value) => {
        ctx.fillStyle = strongTextColor;
        ctx.fillText(label, textX, currentY);
        const labelWidth = ctx.measureText(label).width;
        ctx.fillStyle = textColor;
        ctx.fillText(value, textX + labelWidth, currentY);
        currentY += headerLineHeight;
    };

    drawHeaderLine("STARDATE: ", stardate);
    drawHeaderLine("LOCATION: ", location);
    drawHeaderLine("SUBJECT:  ", subject); 

    currentY += sectionSpacing;

    const imgActualX = textX + imgXOffset;
    const imgActualY = currentY;

    if (imgDispWidth > 0 && imgDispHeight > 0) {
        try {
            ctx.drawImage(originalImg, imgActualX, imgActualY, imgDispWidth, imgDispHeight);
            ctx.strokeStyle = panelColor; 
            ctx.lineWidth = imageBorderThickness;
            ctx.strokeRect(
                imgActualX - imageBorderThickness / 2,
                imgActualY - imageBorderThickness / 2,
                imgDispWidth + imageBorderThickness,
                imgDispHeight + imageBorderThickness
            );
        } catch (e) {
            console.error("Error drawing image:", e);
            // Optionally draw a placeholder if image fails
            ctx.fillStyle = textColor;
            ctx.fillText("[Image Error]", imgActualX + imgDispWidth/2 - ctx.measureText("[Image Error]").width/2, imgActualY + imgDispHeight/2);
        }
    }
    currentY += imgDispHeight;
    currentY += sectionSpacing;
    
    ctx.font = `${headerFontSize}px ${actualFontFamilyString}`;
    ctx.fillStyle = strongTextColor; 
    ctx.fillText("LOG ENTRY:", textX, currentY);
    currentY += headerLineHeight;
    currentY += smallGap;

    ctx.font = `${logEntryFontSize}px ${actualFontFamilyString}`;
    ctx.fillStyle = textColor; 
    wrappedLogEntry.lines.forEach(line => {
        if (currentY + logEntryLineHeight < canvas.height - mainPadding / 2) { // Prevent drawing outside canvas
             ctx.fillText(line, textX, currentY);
        }
        currentY += logEntryLineHeight;
    });

    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 Space Explorer’s Log Creator is a tool designed for generating visually appealing logs that combine images and text for documenting significant events in a space exploration context. Users can input details such as stardate, location, subject, and a narrative log entry. The tool creatively overlays an image with this information, using customizable colors and fonts to enhance readability and aesthetics. This tool is ideal for space enthusiasts, educators, or professionals looking to create visually rich documentation or presentations about space missions, exploratory findings, or science fiction-inspired narratives.

Leave a Reply

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

Other Image Tools:

Image Neolithic Petroglyph Frame Creator

Image Ukiyo-e Japanese Woodblock Print Creator

Image Persian Miniature Painting Creator

Image Sci-Fi Movie Poster Template Creator

Image Horror Movie Poster Template

Image Social Media Milestone Certificate Creator

Halloween Death Certificate Template

Image Anatomical Illustration Frame Creator

Image Romance Novel Cover Template Creator

Image Tabloid Headline Template

Image Space Mission Patch Template Creator

Image Cassette Tape Cover Template Creator

Image Passport Page Template Generator

Image Old Map Frame With Compass Rose Decorator

Image Diploma and Degree Certificate Framer

Image Soviet Propaganda Poster Style Generator

Image Yu-Gi-Oh Card Template Creator

Image Ancient Roman Greek Tablet Frame Creator

Image Marriage Certificate Template Creator

Image Video Game Achievement Frame Creator

Image Newspaper Front Page Template Creator

Image Botanical Illustration Frame Creator

Image Vinyl Record Sleeve Template Creator

Vintage Photo Booth Strip Template Generator

Image Cyberpunk Interface Frame Designer

Image Detective Novel Cover Template

Image Achievement Certificate Framer

Image Illuminated Manuscript Frame Generator

Image Art Deco Poster Frame Creator

Image Egyptian Papyrus Scroll Frame Designer

Image Vintage Postage Stamp Frame Creator

Image Magic: The Gathering Card Frame Generator

Image Birth Certificate Template Generator

Image Driver’s License Template Creator

Image Scout Explorer Badge Template Creator

Image Steampunk Document Frame Creator

See All →