aheedsajid commited on
Commit
cb83d91
·
verified ·
1 Parent(s): 7fc5d02

Upload 3 files

Browse files
Files changed (3) hide show
  1. index.html +79 -19
  2. script.js +106 -0
  3. tailwind.config.js +20 -0
index.html CHANGED
@@ -1,19 +1,79 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <html lang="en">
2
+ <head>
3
+ <meta charset="UTF-8">
4
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
5
+ <title>AI Face Generator</title>
6
+ <script src="https://cdn.tailwindcss.com"></script>
7
+ <script src="tailwind.config.js"></script>
8
+ <script src="script.js" defer></script>
9
+ </head>
10
+ <body class="bg-gray-50 min-h-screen">
11
+ <div class="max-w-7xl mx-auto px-4 py-8 sm:px-6 lg:px-8">
12
+ <h1 class="text-4xl font-bold text-center text-indigo-600 mb-12">AI Face Generator</h1>
13
+
14
+ <div class="bg-white rounded-xl shadow-md p-6 mb-8">
15
+ <h2 class="text-2xl font-semibold text-gray-800 mb-6 text-center">How it works</h2>
16
+ <div class="flex flex-col md:flex-row items-center justify-center gap-8">
17
+ <div class="text-center">
18
+ <h3 class="text-lg font-medium text-gray-700 mb-3">Reference Image</h3>
19
+ <img src="https://picfy.xyz/api/taylor.webp" alt="Reference Image Example"
20
+ class="rounded-lg shadow-lg max-w-[300px] w-full">
21
+ </div>
22
+ <div class="text-4xl text-indigo-600 font-bold hidden md:block">→</div>
23
+ <div class="text-4xl text-indigo-600 font-bold md:hidden">↓</div>
24
+ <div class="text-center">
25
+ <h3 class="text-lg font-medium text-gray-700 mb-3">Generated Result</h3>
26
+ <img src="https://picfy.xyz/api/generated_images/679b6f0d954c5.png" alt="Generated Image Example"
27
+ class="rounded-lg shadow-lg max-w-[300px] w-full">
28
+ <p class="mt-3 text-gray-600 italic">"as a robotic"</p>
29
+ </div>
30
+ </div>
31
+ </div>
32
+
33
+ <div class="bg-white rounded-xl shadow-md p-6 mb-8">
34
+ <div class="flex flex-col sm:flex-row gap-4 items-start sm:items-center">
35
+ <input type="password" id="apiKey" placeholder="Enter your RapidAPI Key"
36
+ class="flex-1 w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500">
37
+ <button onclick="saveApiKey()"
38
+ class="w-full sm:w-auto px-6 py-2 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition-colors">
39
+ Save API Key
40
+ </button>
41
+ </div>
42
+ <div class="mt-4 text-sm text-gray-600">
43
+ Get your API key from:
44
+ <a href="https://rapidapi.com/projectunpack/api/text-to-image-api-with-face/pricing"
45
+ target="_blank"
46
+ class="text-indigo-600 hover:text-indigo-800 transition-colors">RapidAPI</a>
47
+ </div>
48
+ </div>
49
+
50
+ <div class="bg-white rounded-xl shadow-md p-6">
51
+ <div class="space-y-4 mb-8">
52
+ <input type="text" id="referenceImageUrl" placeholder="Reference Image URL"
53
+ class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500">
54
+ <input type="text" id="prompt" placeholder="Enter your prompt"
55
+ class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500">
56
+ <select id="imageSize"
57
+ class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-indigo-500 focus:border-indigo-500">
58
+ <option value="square_hd">Square HD</option>
59
+ <option value="portrait_4_3">Portrait 4:3</option>
60
+ <option value="portrait_16_9">Portrait 16:9</option>
61
+ <option value="landscape_4_3">Landscape 4:3</option>
62
+ <option value="landscape_16_9">Landscape 16:9</option>
63
+ </select>
64
+ <button onclick="generateImage()" id="generateBtn"
65
+ class="w-full px-6 py-2 bg-indigo-600 text-white rounded-lg hover:bg-indigo-700 transition-colors">
66
+ Generate Image
67
+ </button>
68
+ </div>
69
+
70
+ <div class="bg-gray-50 rounded-lg min-h-[300px] flex items-center justify-center p-4">
71
+ <div id="loadingSpinner" class="hidden">
72
+ <div class="w-12 h-12 border-4 border-indigo-600 border-t-transparent rounded-full animate-spin"></div>
73
+ </div>
74
+ <img id="resultImage" class="hidden max-w-full max-h-[500px] rounded-lg">
75
+ </div>
76
+ </div>
77
+ </div>
78
+ </body>
79
+ </html>
script.js ADDED
@@ -0,0 +1,106 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const API_KEY_STORAGE_KEY = 'rapidapi_key';
2
+
3
+ document.addEventListener('DOMContentLoaded', () => {
4
+ const savedApiKey = localStorage.getItem(API_KEY_STORAGE_KEY);
5
+ if (savedApiKey) {
6
+ document.getElementById('apiKey').value = savedApiKey;
7
+ }
8
+ });
9
+
10
+ function saveApiKey() {
11
+ const apiKey = document.getElementById('apiKey').value.trim();
12
+ if (apiKey) {
13
+ localStorage.setItem(API_KEY_STORAGE_KEY, apiKey);
14
+ showNotification('API key saved successfully!');
15
+ } else {
16
+ showNotification('Please enter a valid API key', true);
17
+ }
18
+ }
19
+
20
+ function showNotification(message, isError = false) {
21
+ const notification = document.createElement('div');
22
+ notification.className = `fixed top-4 right-4 px-6 py-3 rounded-lg text-white ${
23
+ isError ? 'bg-red-500' : 'bg-green-500'
24
+ } shadow-lg transform transition-transform duration-300 ease-in-out`;
25
+ notification.textContent = message;
26
+ document.body.appendChild(notification);
27
+
28
+ setTimeout(() => {
29
+ notification.style.transform = 'translateY(-100%)';
30
+ setTimeout(() => notification.remove(), 300);
31
+ }, 3000);
32
+ }
33
+
34
+ async function generateImage() {
35
+ const apiKey = document.getElementById('apiKey').value.trim();
36
+ const referenceImageUrl = document.getElementById('referenceImageUrl').value.trim();
37
+ const prompt = document.getElementById('prompt').value.trim();
38
+ const imageSize = document.getElementById('imageSize').value;
39
+
40
+ if (!apiKey) {
41
+ showNotification('Please enter your RapidAPI key', true);
42
+ return;
43
+ }
44
+
45
+ if (!referenceImageUrl) {
46
+ showNotification('Please enter a reference image URL', true);
47
+ return;
48
+ }
49
+
50
+ if (!prompt) {
51
+ showNotification('Please enter a prompt', true);
52
+ return;
53
+ }
54
+
55
+ const generateBtn = document.getElementById('generateBtn');
56
+ const loadingSpinner = document.getElementById('loadingSpinner');
57
+ const resultImage = document.getElementById('resultImage');
58
+
59
+ generateBtn.disabled = true;
60
+ loadingSpinner.classList.remove('hidden');
61
+ resultImage.classList.add('hidden');
62
+
63
+ try {
64
+ const response = await fetch('https://text-to-image-api-with-face.p.rapidapi.com/face-ai.php', {
65
+ method: 'POST',
66
+ headers: {
67
+ 'Content-Type': 'application/json',
68
+ 'x-rapidapi-host': 'text-to-image-api-with-face.p.rapidapi.com',
69
+ 'x-rapidapi-key': apiKey
70
+ },
71
+ body: JSON.stringify({
72
+ reference_images: [{
73
+ image_url: referenceImageUrl
74
+ }],
75
+ prompt: prompt,
76
+ image_size: imageSize
77
+ })
78
+ });
79
+
80
+ const data = await response.json();
81
+
82
+ if (data.url) {
83
+ resultImage.src = data.url;
84
+ resultImage.classList.remove('hidden');
85
+ } else {
86
+ throw new Error('No image URL in response');
87
+ }
88
+ } catch (error) {
89
+ showNotification('Error generating image: ' + error.message, true);
90
+ } finally {
91
+ generateBtn.disabled = false;
92
+ loadingSpinner.classList.add('hidden');
93
+ }
94
+ }
95
+
96
+ document.querySelectorAll('input').forEach(input => {
97
+ input.addEventListener('keypress', (e) => {
98
+ if (e.key === 'Enter') {
99
+ if (input.id === 'apiKey') {
100
+ saveApiKey();
101
+ } else {
102
+ generateImage();
103
+ }
104
+ }
105
+ });
106
+ });
tailwind.config.js ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ tailwind.config = {
2
+ theme: {
3
+ extend: {
4
+ colors: {
5
+ indigo: {
6
+ 50: '#eef2ff',
7
+ 100: '#e0e7ff',
8
+ 200: '#c7d2fe',
9
+ 300: '#a5b4fc',
10
+ 400: '#818cf8',
11
+ 500: '#6366f1',
12
+ 600: '#4f46e5',
13
+ 700: '#4338ca',
14
+ 800: '#3730a3',
15
+ 900: '#312e81',
16
+ },
17
+ },
18
+ },
19
+ },
20
+ }