Skip to content

001 #320

Description

@poommiphatkakaew-tech

!DOCTYPE html>

<title>Cinematic Concept: Stone Giant</title> <script src="https://cdn.tailwindcss.com"></script> <style> .aspect-9-16 { aspect-ratio: 9 / 16; }
    /* Simulates the camera slowly moving backward while looking up */
    @keyframes cameraMoveBackward {
        0% { 
            transform: scale(1.15) translateY(-2%); 
            filter: brightness(1.1);
        }
        100% { 
            transform: scale(1) translateY(0%); 
            filter: brightness(1);
        }
    }
    
    .cinematic-zoom {
        animation: cameraMoveBackward 5s ease-out forwards;
    }
    
    /* Loading spinner */
    .loader {
        border-top-color: #f97316; /* Orange for glowing eyes vibe */
        -webkit-animation: spinner 1.5s linear infinite;
        animation: spinner 1.5s linear infinite;
    }
    
    @keyframes spinner {
        0% { transform: rotate(0deg); }
        100% { transform: rotate(360deg); }
    }
</style>
<div class="max-w-sm w-full bg-gray-900 rounded-2xl overflow-hidden shadow-2xl border border-gray-800 flex flex-col">
    <div class="p-4 border-b border-gray-800 bg-gray-900/80 backdrop-blur z-10">
        <h1 class="text-lg font-bold text-center tracking-wide text-gray-100">Shot 01: The Morning Commute</h1>
        <p class="text-xs text-gray-400 text-center mt-1">5-Second Cinematic Camera Pull-Back</p>
    </div>

    <!-- Video/Scene Container -->
    <div id="media-container" class="relative w-full aspect-9-16 bg-black overflow-hidden flex items-center justify-center">
        <!-- Loading State -->
        <div id="loading-state" class="flex flex-col items-center justify-center space-y-4 absolute inset-0 bg-gray-900 z-10">
            <div class="loader ease-linear rounded-full border-4 border-t-4 border-gray-700 h-10 w-10 mb-2"></div>
            <p class="text-xs font-medium animate-pulse text-gray-400 tracking-wider uppercase">Rendering Frame...</p>
        </div>
    </div>

    <!-- Controls -->
    <div class="p-4 bg-gray-900 flex justify-center border-t border-gray-800 hidden relative z-10" id="controls">
        <button onclick="replayAnimation()" class="bg-orange-600 hover:bg-orange-500 text-white p-3 rounded-full transition-all focus:outline-none focus:ring-4 focus:ring-orange-500/50 shadow-lg shadow-orange-900/50 flex items-center justify-center group" title="Replay 5s Scene">
            <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="currentColor" class="translate-x-[2px] group-hover:scale-110 transition-transform"><polygon points="5 3 19 12 5 21 5 3"></polygon></svg>
        </button>
    </div>
</div>

<script>
    const apiKey = "";
    // Condensed prompt per instructions
    const promptText = "Vertical 9:16. Low angle backward track. Giant muscular dark-gray stone warrior walks through morning SE Asian traffic. Glowing orange eyes, serious. Realistic cars, morning sun, cinematic depth. No text/watermarks.";

    // Exponential backoff retry logic for API calls
    async function fetchWithRetry(url, options, retries = 5) {
        const delays = [1000, 2000, 4000, 8000, 16000];
        for (let i = 0; i < retries; i++) {
            try {
                const response = await fetch(url, options);
                if (!response.ok) {
                    throw new Error(`HTTP error! status: ${response.status}`);
                }
                const data = await response.json();
                if (data.error) {
                    throw new Error(data.error.message);
                }
                return data;
            } catch (error) {
                if (i === retries - 1) throw error;
                await new Promise(res => setTimeout(res, delays[i]));
            }
        }
    }

    async function generateScene() {
        const container = document.getElementById('media-container');
        const loading = document.getElementById('loading-state');
        const controls = document.getElementById('controls');

        try {
            const data = await fetchWithRetry(`https://generativelanguage.googleapis.com/v1beta/models/imagen-4.0-generate-001:predict?key=${apiKey}`, {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({
                    instances: { prompt: promptText },
                    parameters: { sampleCount: 1 }
                })
            });

            if (data.predictions && data.predictions[0]) {
                const imageUrl = `data:image/png;base64,${data.predictions[0].bytesBase64Encoded}`;
                
                // Fade out loading, insert image, and start animation
                loading.classList.add('hidden');
                
                // The origin-bottom ensures the camera looks up from the street level while zooming out
                const imgElement = document.createElement('img');
                imgElement.id = 'scene-image';
                imgElement.src = imageUrl;
                imgElement.alt = "Stone Giant in Traffic";
                imgElement.className = "w-full h-full object-cover cinematic-zoom origin-bottom";
                
                container.appendChild(imgElement);
                controls.classList.remove('hidden');
            } else {
                throw new Error('No image generated.');
            }
        } catch (error) {
            loading.innerHTML = `
                <div class="text-red-500 mb-2">
                    <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="mx-auto"><circle cx="12" cy="12" r="10"></circle><line x1="12" y1="8" x2="12" y2="12"></line><line x1="12" y1="16" x2="12.01" y2="16"></line></svg>
                </div>
                <p class="text-sm text-red-400 text-center px-4 font-semibold">Failed to render scene.</p>
                <p class="text-xs text-red-400/80 text-center px-4 mt-1">Please try again later.</p>
            `;
        }
    }

    function replayAnimation() {
        const img = document.getElementById('scene-image');
        if (img) {
            // Trigger reflow to restart the 5-second CSS animation
            img.classList.remove('cinematic-zoom');
            void img.offsetWidth; // magic reflow trick
            img.classList.add('cinematic-zoom');
        }
    }

    // Start generation immediately upon load
    window.onload = generateScene;
</script>

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions