-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.js
More file actions
137 lines (124 loc) · 5.99 KB
/
app.js
File metadata and controls
137 lines (124 loc) · 5.99 KB
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
127
128
129
130
131
132
133
134
135
136
137
const promptBtn = document.querySelector('.prompt-btn');
const generateBtn = document.querySelector('.generate-btn');
const promptInput = document.querySelector('.prompt-input');
const modelSelect = document.getElementById('model-select');
const countSelect = document.getElementById('count-select');
const ratioSelect = document.getElementById('ratio-select');
const promptForm = document.querySelector('.prompt-form');
const galleryGrid = document.querySelector('.gallery-grid');
const API_KEY = 'api_key goes here'; // Replace with your actual API key
//ofCourse, you should not hardcode your API key in production code. ^_^
// Array of random prompts to choose from
const randomPrompts = [
"A futuristic cityscape at sunset",
"A serene mountain landscape with a river",
"A bustling market scene in a medieval town",
"A close-up of a vibrant flower in bloom",
"A cozy cabin in a snowy forest",
"A majestic lion resting under a tree",
"A futuristic spaceship flying through space",
"A tranquil beach with palm trees and clear water",
"A colorful underwater scene with coral reefs",
"A dramatic stormy sky over a vast ocean",
"A whimsical fairy tale forest with glowing mushrooms",
]
// Function to Random select a prompt
promptBtn.addEventListener('click', () => {
const prompt = randomPrompts[Math.floor(Math.random() * randomPrompts.length)];
promptInput.value = prompt;
});
// Function to calculate image dimensions based on aspect ratio
const getImageDimentions = (ratio, baseSize = 512) => {
const [width, height] = ratio.split("/").map(Number);
const scale = baseSize / Math.sqrt(width * height);
let calWidth = Math.round(width * scale);
let calHeight = Math.round(height * scale);
// Ensure the dimensions are multiples of 16
calWidth = Math.floor(calWidth / 16) * 16;
calHeight = Math.floor(calHeight / 16) * 16;
return { width: calWidth, height: calHeight };
}
// Function to update the image card with the generated image from the API
const updateImageCards = (imgIndex, imgUrl) => {
const imgCard = document.getElementById(`img-card-${imgIndex}`);
if (!imgCard) return; // Check if the image card exists
// Remove loading class and update the card with the image
imgCard.classList.remove('loading'); //remove loading class to show the image
imgCard.innerHTML = `
<img src="${imgUrl}" class="result-img" alt="Generated Image">
<div class="img-overlay">
<a href="${imgUrl}" class="img-download-btn" download="${Date.now()}.png">
<i class="fa-solid fa-download"></i>
</a>
</div>
`
}
// Function to change the image card to an error state if the image generation fails
const errorCard = (i) =>{
const imgCard = document.getElementById(`img-card-${i}`);
if (!imgCard) return; // Check if the image card exists
imgCard.classList.remove('loading');
imgCard.classList.add('error');
};
// Function to generate images using the Hugging Face API
const generateImages = async (promptText, model, count, ratio) => {
const apiUrl = `https://router.huggingface.co/hf-inference/models/${model}`;// Construct the API URL using the selected model
const { width, height } = getImageDimentions(ratio); //get the image dimensions based on the selected aspect ratio
// array of promises to fetch images based on the count selected by the user
const imgPromises = Array.from({ length: count }, async(_, i) => {
try {
const response = await fetch(apiUrl, {
headers: {
Authorization: `Bearer ${API_KEY}`, // Use ur API key for authorization
"Content-Type": "application/json",
"x-use-cache": "false", // Disable caching to ensure fresh results
},
method: "POST",
// Send the prompt and parameters in the request body
body: JSON.stringify({
inputs: promptText,
parameters: { width, height },
})
})
// Check if the response is not ok (e.g., 404, 500)
if (!response.ok) {
errorCard(i); // Change the image card to an error state if the response is not ok
throw new Error((await response.json())?.error);
}
// If the response is successful, convert it to a blob and update the image card
const result = await response.blob();
updateImageCards(i, URL.createObjectURL(result));
}catch (error) {
console.error('Error generating image:', error);
}})
await Promise.allSettled(imgPromises);
}
const createImageCard = (promptText, model, count, ratio) => {
galleryGrid.innerHTML = "" // Clear the gallery grid before adding new image cards
// Create image cards with loading state based on count selected by the user
for (let i = 0 ; i < count; i++) {
galleryGrid.innerHTML += `
<div class="img-card loading" id="img-card-${i}" style="aspect-ratio: ${ratio};">
<div class="status-container">
<i class="fa-solid fa-triangle-exclamation"></i>
<div class="Spinner"></div>
<p class="status-text">Generating...</p>
</div>
</div>`
}
// Call the function to generate images with the provided prompt, model, count, and ratio
generateImages(promptText, model, count, ratio);
}
// This function is called when the user submits the form to generate images
//u got the data from the form and call the createImageCard function to generate images
const handleFormSubmit = (e) => {
e.preventDefault(); //
const promptText = promptInput.value.trim(); // Get the prompt text from the input field
const selectedModel = modelSelect.value; // Get the selected model from the dropdown
const selectedCount = parseInt(countSelect.value) || 1; // Default to 1 if not selected
const selectedRatio = ratioSelect.value || '1:1'; // Default to '1:1' if not selected
// console.log(`Generating ${selectedCount} images with prompt: "${promptText}", model: "${selectedModel}", ratio: "${selectedRatio}"`);
createImageCard(promptText, selectedModel, selectedCount, selectedRatio);
};
// Add event listener to the form submit event
promptForm.addEventListener('submit', handleFormSubmit);