File size: 5,840 Bytes
5e99e2c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37bd27b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5e99e2c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
document.addEventListener('DOMContentLoaded', function() {
    // Update slider values in real-time
    const guidanceSlider = document.getElementById('guidance-scale');
    const guidanceValue = document.getElementById('guidance-value');
    const stepsSlider = document.getElementById('steps');
    const stepsValue = document.getElementById('steps-value');
    const seedSlider = document.getElementById('seed');
    const seedValue = document.getElementById('seed-value');
    const generateBtn = document.getElementById('generate-btn');
    const imagePreview = document.getElementById('image-preview');
    
    guidanceSlider.addEventListener('input', () => {
        guidanceValue.textContent = guidanceSlider.value;
    });
    
    stepsSlider.addEventListener('input', () => {
        stepsValue.textContent = stepsSlider.value;
    });
    
    seedSlider.addEventListener('input', () => {
        seedValue.textContent = seedSlider.value === "-1" ? "Random" : seedSlider.value;
    });
    
    // Generate image function (mock implementation for demo)
    generateBtn.addEventListener('click', async function() {
        const prompt = document.getElementById('prompt-input').value;
        if (!prompt.trim()) {
            alert('Please enter a prompt first!');
            return;
        }
        
        // Show loading state
        generateBtn.disabled = true;
        generateBtn.innerHTML = '<i data-feather="loader" class="spinner mr-2"></i> Generating...';
        feather.replace();
        
        imagePreview.classList.add('loading');
        imagePreview.innerHTML = `
            <div class="absolute inset-0 flex items-center justify-center z-20">
                <div class="text-center p-6">
                    <i data-feather="loader" class="spinner w-12 h-12 mx-auto text-white mb-4"></i>
                    <p class="text-white">Creating your masterpiece...</p>
                </div>
            </div>
        `;
        feather.replace();
        try {
            const prompt = document.getElementById('prompt-input').value;
            const negativePrompt = document.getElementById('negative-prompt').value;
            const model = document.getElementById('model-select').value;
            const size = document.getElementById('size-select').value;
            const guidanceScale = parseFloat(guidanceSlider.value);
            const steps = parseInt(stepsSlider.value);
            const seed = seedSlider.value === "-1" ? Math.floor(Math.random() * 1000000) : parseInt(seedSlider.value);

            // Call Hugging Face API
            const response = await fetch('https://api-inference.huggingface.co/models/stabilityai/stable-diffusion-xl-base-1.0', {
                method: 'POST',
                headers: {
                    'Authorization': 'Bearer YOUR_HUGGINGFACE_API_KEY', // Replace with your actual API key
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    inputs: prompt,
                    parameters: {
                        negative_prompt: negativePrompt,
                        guidance_scale: guidanceScale,
                        num_inference_steps: steps,
                        width: parseInt(size.split('x')[0]),
                        height: parseInt(size.split('x')[1]),
                        seed: seed
                    }
                })
            });

            if (!response.ok) {
                throw new Error(`API request failed with status ${response.status}`);
            }

            const imageBlob = await response.blob();
            const imageUrl = URL.createObjectURL(imageBlob);
            
            // Display the generated image
            imagePreview.classList.remove('loading');
            imagePreview.innerHTML = `<img src="${imageUrl}" alt="Generated image" class="generated-image">`;
            
            // Add to gallery
            const galleryGrid = document.getElementById('gallery-grid');
            const galleryItem = document.createElement('div');
            galleryItem.className = 'bg-gray-100 dark:bg-gray-700 rounded-lg aspect-square overflow-hidden';
            galleryItem.innerHTML = `<img src="${imageUrl}" alt="Gallery item" class="w-full h-full object-cover">`;
            galleryGrid.insertBefore(galleryItem, galleryGrid.firstChild);
            
        } catch (error) {
            console.error('Error generating image:', error);
            imagePreview.classList.remove('loading');
            imagePreview.innerHTML = `
                <div class="text-center p-6">
                    <i data-feather="alert-circle" class="w-12 h-12 mx-auto text-red-500 mb-4"></i>
                    <p class="text-red-500">Error generating image: ${error.message}</p>
                </div>
            `;
galleryGrid.insertBefore(galleryItem, galleryGrid.firstChild);
        
        // Reset button
        generateBtn.disabled = false;
        generateBtn.innerHTML = '<i data-feather="sparkles" class="mr-2"></i> Generate Image';
        feather.replace();
    });
    
    // Theme toggle functionality
    const themeToggleBtn = document.querySelector('.theme-toggle-btn');
    if (themeToggleBtn) {
        themeToggleBtn.addEventListener('click', () => {
            document.documentElement.classList.toggle('dark');
            localStorage.setItem('theme', document.documentElement.classList.contains('dark') ? 'dark' : 'light');
        });
    }
    
    // Check for saved theme preference
    if (localStorage.getItem('theme') === 'dark' || (!localStorage.getItem('theme') && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
        document.documentElement.classList.add('dark');
    } else {
        document.documentElement.classList.remove('dark');
    }
});