Hosdroid commited on
Commit
36c3d1b
·
verified ·
1 Parent(s): fbbefab

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +368 -18
index.html CHANGED
@@ -1,19 +1,369 @@
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
+ <!DOCTYPE html>
2
+ <html lang="fa" dir="rtl">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>سازنده هوشمند استیکر ایتا</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fontsource/vazirmatn@5.0.19/index.css">
9
+ <style>
10
+ body {
11
+ font-family: 'Vazirmatn', sans-serif;
12
+ background: linear-gradient(135deg, #fff7ed 0%, #ffedd5 50%, #fed7aa 100%);
13
+ min-height: 100vh;
14
+ }
15
+ .glass-panel {
16
+ background: rgba(255, 255, 255, 0.85);
17
+ backdrop-filter: blur(12px);
18
+ -webkit-backdrop-filter: blur(12px);
19
+ border: 1px solid rgba(255, 255, 255, 0.5);
20
+ }
21
+ .upload-zone {
22
+ background-image: url("data:image/svg+xml,%3csvg width='100%25' height='100%25' xmlns='http://www.w3.org/2000/svg'%3e%3crect width='100%25' height='100%25' fill='none' rx='16' ry='16' stroke='%23EA580C' stroke-width='2' stroke-dasharray='12%2c 12' stroke-dashoffset='0' stroke-linecap='square'/%3e%3c/svg%3e");
23
+ transition: all 0.3s ease;
24
+ }
25
+ .upload-zone:hover {
26
+ background-color: rgba(234, 88, 12, 0.05);
27
+ transform: translateY(-2px);
28
+ }
29
+ .upload-zone.dragover {
30
+ background-color: rgba(234, 88, 12, 0.1);
31
+ transform: scale(1.02);
32
+ }
33
+ .fade-in {
34
+ animation: fadeIn 0.5s ease-out forwards;
35
+ }
36
+ .slide-up {
37
+ animation: slideUp 0.5s ease-out forwards;
38
+ }
39
+ @keyframes fadeIn {
40
+ from { opacity: 0; }
41
+ to { opacity: 1; }
42
+ }
43
+ @keyframes slideUp {
44
+ from { opacity: 0; transform: translateY(20px); }
45
+ to { opacity: 1; transform: translateY(0); }
46
+ }
47
+ .spinner {
48
+ border: 3px solid rgba(234, 88, 12, 0.1);
49
+ border-left-color: #ea580c;
50
+ border-radius: 50%;
51
+ width: 24px;
52
+ height: 24px;
53
+ animation: spin 1s linear infinite;
54
+ }
55
+ @keyframes spin {
56
+ to { transform: rotate(360deg); }
57
+ }
58
+ .btn-eitaa {
59
+ background: linear-gradient(135deg, #ea580c 0%, #c2410c 100%);
60
+ transition: all 0.3s ease;
61
+ }
62
+ .btn-eitaa:hover {
63
+ transform: translateY(-2px);
64
+ box-shadow: 0 10px 20px -5px rgba(234, 88, 12, 0.4);
65
+ }
66
+ .btn-eitaa:active {
67
+ transform: translateY(0);
68
+ }
69
+ </style>
70
+ </head>
71
+ <body class="flex items-center justify-center p-4">
72
+
73
+ <main class="w-full max-w-lg glass-panel rounded-3xl shadow-2xl p-6 md:p-8 slide-up">
74
+ <!-- Header -->
75
+ <div class="text-center mb-8">
76
+ <div class="inline-flex items-center justify-center w-16 h-16 rounded-2xl bg-orange-100 text-orange-600 mb-4 shadow-sm">
77
+ <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">
78
+ <path d="M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z"/>
79
+ <path d="M19 10v2a7 7 0 0 1-14 0v-2"/>
80
+ <line x1="12" y1="19" x2="12" y2="22"/>
81
+ </svg>
82
+ </div>
83
+ <h1 class="text-2xl md:text-3xl font-bold text-gray-800 mb-2">سازنده هوشمند استیکر ایتا</h1>
84
+ <p class="text-gray-500 text-sm md:text-base">تبدیل حرفه‌ای و سریع تصاویر به فرمت WebP با کیفیت بالا</p>
85
+ </div>
86
+
87
+ <!-- Upload Zone -->
88
+ <div id="uploadZone" class="upload-zone rounded-2xl p-8 text-center cursor-pointer mb-6 relative">
89
+ <input type="file" id="fileInput" accept="image/*" class="absolute inset-0 w-full h-full opacity-0 cursor-pointer">
90
+ <div class="pointer-events-none">
91
+ <svg class="mx-auto h-12 w-12 text-orange-400 mb-3" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
92
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5" d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" />
93
+ </svg>
94
+ <p class="text-gray-700 font-medium mb-1">برای انتخاب تصویر کلیک کنید</p>
95
+ <p class="text-gray-400 text-xs">پشتیبانی از تمام فرمت‌های تصویری (JPG, PNG, WEBP, BMP, TIFF و...)</p>
96
+ </div>
97
+ </div>
98
+
99
+ <!-- Loading State -->
100
+ <div id="loadingState" class="hidden flex-col items-center justify-center py-8">
101
+ <div class="spinner mb-4"></div>
102
+ <p class="text-orange-600 font-medium animate-pulse">در حال تحلیل و تبدیل حرفه‌ای به WebP...</p>
103
+ </div>
104
+
105
+ <!-- Error State -->
106
+ <div id="errorState" class="hidden bg-red-50 border border-red-200 rounded-2xl p-4 mb-6 fade-in">
107
+ <div class="flex items-start">
108
+ <svg class="h-6 w-6 text-red-500 ml-3 mt-0.5" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
109
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
110
+ </svg>
111
+ <div>
112
+ <h3 class="text-red-800 font-bold text-sm mb-1">خطا در پردازش</h3>
113
+ <p id="errorMessage" class="text-red-600 text-sm"></p>
114
+ </div>
115
+ </div>
116
+ <button id="resetBtn" class="mt-4 w-full py-2 bg-red-100 text-red-700 rounded-xl font-medium hover:bg-red-200 transition-colors text-sm">
117
+ تلاش مجدد
118
+ </button>
119
+ </div>
120
+
121
+ <!-- Success State -->
122
+ <div id="successState" class="hidden fade-in">
123
+ <div class="bg-green-50 border border-green-200 rounded-2xl p-4 mb-6 flex items-center">
124
+ <svg class="h-6 w-6 text-green-500 ml-3" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
125
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
126
+ </svg>
127
+ <div>
128
+ <p class="text-green-800 font-bold text-sm">تبدیل با موفقیت انجام شد!</p>
129
+ <p class="text-green-600 text-xs mt-1" id="fileInfo"></p>
130
+ </div>
131
+ </div>
132
+
133
+ <div class="relative rounded-2xl overflow-hidden shadow-lg mb-6 bg-gray-100 border border-gray-200">
134
+ <img id="previewImage" class="w-full h-auto object-contain max-h-96" alt="پیش‌نمایش استیکر">
135
+ <div class="absolute bottom-2 left-2 bg-black/60 text-white text-xs px-2 py-1 rounded-lg backdrop-blur-sm">
136
+ فرمت: WEBP
137
+ </div>
138
+ </div>
139
+
140
+ <div class="space-y-3">
141
+ <button id="shareBtn" class="btn-eitaa w-full py-3.5 rounded-xl text-white font-bold text-base flex items-center justify-center gap-2 shadow-lg shadow-orange-200">
142
+ <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
143
+ <path d="M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8"/>
144
+ <polyline points="16 6 12 2 8 6"/>
145
+ <line x1="12" y1="2" x2="12" y2="15"/>
146
+ </svg>
147
+ اشتراک‌گذاری و ارسال به ایتا
148
+ </button>
149
+
150
+ <button id="downloadBtn" class="w-full py-3 rounded-xl bg-gray-100 text-gray-700 font-bold text-base flex items-center justify-center gap-2 hover:bg-gray-200 transition-colors border border-gray-200">
151
+ <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
152
+ <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
153
+ <polyline points="7 10 12 15 17 10"/>
154
+ <line x1="12" y1="15" x2="12" y2="3"/>
155
+ </svg>
156
+ دانلود فایل WebP
157
+ </button>
158
+
159
+ <p class="text-center text-xs text-gray-400 mt-4 leading-relaxed">
160
+ نکته: در صورت عدم پشتیبانی مرورگر از اشتراک‌گذاری مستقیم، فایل به صورت خودکار دانلود شده و ایتا باز می‌شود.
161
+ <br>
162
+ <a href="https://www.eitaa.com/share/url?url=" target="_blank" class="text-orange-500 hover:underline mt-1 inline-block">قالب اشتراک‌گذاری ایتا</a>
163
+ </p>
164
+ </div>
165
+ </div>
166
+ </main>
167
+
168
+ <script>
169
+ const fileInput = document.getElementById('fileInput');
170
+ const uploadZone = document.getElementById('uploadZone');
171
+ const loadingState = document.getElementById('loadingState');
172
+ const errorState = document.getElementById('errorState');
173
+ const errorMessage = document.getElementById('errorMessage');
174
+ const successState = document.getElementById('successState');
175
+ const previewImage = document.getElementById('previewImage');
176
+ const fileInfo = document.getElementById('fileInfo');
177
+ const resetBtn = document.getElementById('resetBtn');
178
+ const shareBtn = document.getElementById('shareBtn');
179
+ const downloadBtn = document.getElementById('downloadBtn');
180
+
181
+ let convertedBlob = null;
182
+ let convertedFileName = 'sticker.webp';
183
+
184
+ // Drag and Drop effects
185
+ uploadZone.addEventListener('dragover', (e) => {
186
+ e.preventDefault();
187
+ uploadZone.classList.add('dragover');
188
+ });
189
+
190
+ uploadZone.addEventListener('dragleave', () => {
191
+ uploadZone.classList.remove('dragover');
192
+ });
193
+
194
+ uploadZone.addEventListener('drop', (e) => {
195
+ e.preventDefault();
196
+ uploadZone.classList.remove('dragover');
197
+ if (e.dataTransfer.files.length) {
198
+ handleFile(e.dataTransfer.files[0]);
199
+ }
200
+ });
201
+
202
+ fileInput.addEventListener('change', (e) => {
203
+ if (e.target.files.length) {
204
+ handleFile(e.target.files[0]);
205
+ }
206
+ });
207
+
208
+ resetBtn.addEventListener('click', () => {
209
+ errorState.classList.add('hidden');
210
+ uploadZone.classList.remove('hidden');
211
+ fileInput.value = '';
212
+ });
213
+
214
+ function formatBytes(bytes, decimals = 2) {
215
+ if (bytes === 0) return '0 بایت';
216
+ const k = 1024;
217
+ const dm = decimals < 0 ? 0 : decimals;
218
+ const sizes = ['بایت', 'کیلوبایت', 'مگابایت'];
219
+ const i = Math.floor(Math.log(bytes) / Math.log(k));
220
+ return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
221
+ }
222
+
223
+ function showError(msg) {
224
+ uploadZone.classList.add('hidden');
225
+ loadingState.classList.add('hidden');
226
+ errorState.classList.remove('hidden');
227
+ errorMessage.textContent = msg;
228
+ }
229
+
230
+ function handleFile(file) {
231
+ uploadZone.classList.add('hidden');
232
+ errorState.classList.add('hidden');
233
+ successState.classList.add('hidden');
234
+ loadingState.classList.remove('hidden');
235
+ loadingState.classList.add('flex');
236
+
237
+ // Validation
238
+ if (!file.type.startsWith('image/')) {
239
+ showError('این ممکن نیست آن تصویری نیست !');
240
+ return;
241
+ }
242
+
243
+ if (file.type === 'image/gif' || file.type.startsWith('video/')) {
244
+ showError('ایتا قابليت استیکر ویدئویی را ندارد !');
245
+ return;
246
+ }
247
+
248
+ // Process Image
249
+ const reader = new FileReader();
250
+ reader.onload = (event) => {
251
+ const img = new Image();
252
+ img.onload = () => {
253
+ processImage(img, file.name);
254
+ };
255
+ img.onerror = () => {
256
+ showError('خطا در خواندن فایل تصویر. لطفاً فایل دیگری انتخاب کنید.');
257
+ };
258
+ img.src = event.target.result;
259
+ };
260
+ reader.readAsDataURL(file);
261
+ }
262
+
263
+ function processImage(img, originalName) {
264
+ const canvas = document.createElement('canvas');
265
+ const ctx = canvas.getContext('2d');
266
+
267
+ // Professional resizing: maintain aspect ratio, max dimension 512px (optimal for stickers)
268
+ // If user wants original size, we can skip, but 512px is professional standard for Eitaa stickers.
269
+ // The prompt says: "اگر اندازه تصویر 512 پیکسل در کل نبود هیچ اشکالی نیست و خروجی می دهد ایتا به اندازه کاری ندارد"
270
+ // So we will keep original size but cap at 1024 to prevent browser crash, and ensure high quality.
271
+ let width = img.width;
272
+ let height = img.height;
273
+ const maxDimension = 1024;
274
+
275
+ if (width > maxDimension || height > maxDimension) {
276
+ if (width > height) {
277
+ height = Math.round((height * maxDimension) / width);
278
+ width = maxDimension;
279
+ } else {
280
+ width = Math.round((width * maxDimension) / height);
281
+ height = maxDimension;
282
+ }
283
+ }
284
+
285
+ canvas.width = width;
286
+ canvas.height = height;
287
+
288
+ // High quality rendering
289
+ ctx.imageSmoothingEnabled = true;
290
+ ctx.imageSmoothingQuality = 'high';
291
+ ctx.drawImage(img, 0, 0, width, height);
292
+
293
+ // Convert to WebP with high quality (0.95)
294
+ canvas.toBlob((blob) => {
295
+ if (blob) {
296
+ convertedBlob = blob;
297
+ convertedFileName = originalName.replace(/\.[^/.]+$/, '') + '.webp';
298
+
299
+ const objectUrl = URL.createObjectURL(blob);
300
+ previewImage.src = objectUrl;
301
+
302
+ fileInfo.textContent = `ابعاد: ${width}×${height} پیکسل | حجم: ${formatBytes(blob.size)}`;
303
+
304
+ loadingState.classList.add('hidden');
305
+ loadingState.classList.remove('flex');
306
+ successState.classList.remove('hidden');
307
+ } else {
308
+ showError('خطا در تبدیل فرمت تصویر. لطفاً دوباره تلاش کنید.');
309
+ }
310
+ }, 'image/webp', 0.95);
311
+ }
312
+
313
+ downloadBtn.addEventListener('click', () => {
314
+ if (!convertedBlob) return;
315
+ const url = URL.createObjectURL(convertedBlob);
316
+ const a = document.createElement('a');
317
+ a.href = url;
318
+ a.download = convertedFileName;
319
+ document.body.appendChild(a);
320
+ a.click();
321
+ document.body.removeChild(a);
322
+ URL.revokeObjectURL(url);
323
+ });
324
+
325
+ shareBtn.addEventListener('click', async () => {
326
+ if (!convertedBlob) return;
327
+
328
+ const file = new File([convertedBlob], convertedFileName, { type: 'image/webp' });
329
+ const shareData = {
330
+ files: [file],
331
+ title: 'استیکر ایتا',
332
+ text: 'این استیکر را با سازنده هوشمند استیکر ایتا ساختم!'
333
+ };
334
+
335
+ // Check if Web Share API with files is supported
336
+ if (navigator.share && navigator.canShare && navigator.canShare(shareData)) {
337
+ try {
338
+ await navigator.share(shareData);
339
+ } catch (err) {
340
+ if (err.name !== 'AbortError') {
341
+ fallbackShare();
342
+ }
343
+ }
344
+ } else {
345
+ fallbackShare();
346
+ }
347
+ });
348
+
349
+ function fallbackShare() {
350
+ // Fallback: Download the file and open Eitaa share URL
351
+ const url = URL.createObjectURL(convertedBlob);
352
+ const a = document.createElement('a');
353
+ a.href = url;
354
+ a.download = convertedFileName;
355
+ document.body.appendChild(a);
356
+ a.click();
357
+ document.body.removeChild(a);
358
+ URL.revokeObjectURL(url);
359
+
360
+ // Show alert and open Eitaa
361
+ setTimeout(() => {
362
+ alert('فایل استیکر دانلود شد.\nاکنون می‌توانید آن را در ایتا ضمیمه کنید.\n\nلینک اشتراک‌گذاری ایتا: https://www.eitaa.com/share/url?url=');
363
+ window.open('https://eitaa.com/', '_blank');
364
+ }, 500);
365
+ }
366
+ </script>
367
+ </body>
368
  </html>
369
+