DotSlashGabut commited on
Commit
dc21927
·
verified ·
1 Parent(s): 425f7c1

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +690 -19
index.html CHANGED
@@ -1,19 +1,690 @@
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="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>QR Code Generator Pro</title>
7
+ <script src="https://cdn.jsdelivr.net/npm/[email protected]/build/qrcode.min.js"></script>
8
+ <style>
9
+ * {
10
+ margin: 0;
11
+ padding: 0;
12
+ box-sizing: border-box;
13
+ }
14
+
15
+ body {
16
+ font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
17
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
18
+ min-height: 100vh;
19
+ display: flex;
20
+ align-items: center;
21
+ justify-content: center;
22
+ padding: 10px;
23
+ }
24
+
25
+ .container {
26
+ background: rgba(255, 255, 255, 0.95);
27
+ backdrop-filter: blur(10px);
28
+ border-radius: 20px;
29
+ box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
30
+ padding: 30px;
31
+ max-width: 500px;
32
+ width: 100%;
33
+ animation: slideUp 0.8s ease-out;
34
+ }
35
+
36
+ @keyframes slideUp {
37
+ from {
38
+ opacity: 0;
39
+ transform: translateY(30px);
40
+ }
41
+ to {
42
+ opacity: 1;
43
+ transform: translateY(0);
44
+ }
45
+ }
46
+
47
+ .header {
48
+ text-align: center;
49
+ margin-bottom: 25px;
50
+ }
51
+
52
+ .title {
53
+ font-size: 28px;
54
+ font-weight: 700;
55
+ background: linear-gradient(135deg, #667eea, #764ba2);
56
+ -webkit-background-clip: text;
57
+ -webkit-text-fill-color: transparent;
58
+ background-clip: text;
59
+ margin-bottom: 8px;
60
+ }
61
+
62
+ .subtitle {
63
+ color: #666;
64
+ font-size: 14px;
65
+ }
66
+
67
+ .category-selector {
68
+ display: grid;
69
+ grid-template-columns: repeat(auto-fit, minmax(80px, 1fr));
70
+ gap: 8px;
71
+ margin-bottom: 20px;
72
+ }
73
+
74
+ .category-btn {
75
+ padding: 10px 8px;
76
+ border: none;
77
+ border-radius: 12px;
78
+ background: #f8f9ff;
79
+ color: #666;
80
+ font-size: 12px;
81
+ font-weight: 500;
82
+ cursor: pointer;
83
+ transition: all 0.3s ease;
84
+ text-align: center;
85
+ display: flex;
86
+ flex-direction: column;
87
+ align-items: center;
88
+ gap: 4px;
89
+ }
90
+
91
+ .category-btn:hover {
92
+ background: #e8f0ff;
93
+ transform: translateY(-2px);
94
+ }
95
+
96
+ .category-btn.active {
97
+ background: linear-gradient(135deg, #667eea, #764ba2);
98
+ color: white;
99
+ box-shadow: 0 5px 15px rgba(102, 126, 234, 0.4);
100
+ }
101
+
102
+ .category-icon {
103
+ font-size: 16px;
104
+ }
105
+
106
+ .input-group {
107
+ margin-bottom: 15px;
108
+ }
109
+
110
+ .input-label {
111
+ display: block;
112
+ margin-bottom: 6px;
113
+ font-weight: 600;
114
+ color: #333;
115
+ font-size: 13px;
116
+ }
117
+
118
+ .input-field {
119
+ width: 100%;
120
+ padding: 12px 16px;
121
+ border: 2px solid #e9ecef;
122
+ border-radius: 12px;
123
+ font-size: 14px;
124
+ transition: all 0.3s ease;
125
+ background: #fafbff;
126
+ }
127
+
128
+ .input-field:focus {
129
+ outline: none;
130
+ border-color: #667eea;
131
+ box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
132
+ background: white;
133
+ }
134
+
135
+ .input-row {
136
+ display: grid;
137
+ grid-template-columns: 1fr 1fr;
138
+ gap: 12px;
139
+ }
140
+
141
+ .customization {
142
+ background: #f8f9ff;
143
+ border-radius: 12px;
144
+ padding: 20px;
145
+ margin-bottom: 20px;
146
+ }
147
+
148
+ .custom-title {
149
+ font-weight: 600;
150
+ color: #333;
151
+ margin-bottom: 15px;
152
+ font-size: 14px;
153
+ }
154
+
155
+ .color-controls {
156
+ display: grid;
157
+ grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
158
+ gap: 15px;
159
+ margin-bottom: 15px;
160
+ }
161
+
162
+ .color-group {
163
+ display: flex;
164
+ align-items: center;
165
+ gap: 10px;
166
+ }
167
+
168
+ .color-input {
169
+ width: 40px;
170
+ height: 40px;
171
+ border: none;
172
+ border-radius: 8px;
173
+ cursor: pointer;
174
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
175
+ }
176
+
177
+ .size-control {
178
+ display: flex;
179
+ align-items: center;
180
+ gap: 10px;
181
+ margin-bottom: 10px;
182
+ }
183
+
184
+ .size-slider {
185
+ flex: 1;
186
+ height: 6px;
187
+ background: #e9ecef;
188
+ border-radius: 3px;
189
+ outline: none;
190
+ cursor: pointer;
191
+ }
192
+
193
+ .generate-btn {
194
+ width: 100%;
195
+ padding: 15px;
196
+ background: linear-gradient(135deg, #667eea, #764ba2);
197
+ color: white;
198
+ border: none;
199
+ border-radius: 12px;
200
+ font-size: 16px;
201
+ font-weight: 600;
202
+ cursor: pointer;
203
+ transition: all 0.3s ease;
204
+ margin-bottom: 20px;
205
+ }
206
+
207
+ .generate-btn:hover {
208
+ transform: translateY(-2px);
209
+ box-shadow: 0 10px 25px rgba(102, 126, 234, 0.3);
210
+ }
211
+
212
+ .generate-btn:active {
213
+ transform: translateY(0);
214
+ }
215
+
216
+ .qr-output {
217
+ text-align: center;
218
+ padding: 20px;
219
+ background: white;
220
+ border-radius: 12px;
221
+ box-shadow: 0 5px 15px rgba(0, 0, 0, 0.08);
222
+ }
223
+
224
+ .qr-canvas {
225
+ max-width: 100%;
226
+ border-radius: 8px;
227
+ margin-bottom: 15px;
228
+ }
229
+
230
+ .download-controls {
231
+ display: flex;
232
+ gap: 10px;
233
+ justify-content: center;
234
+ flex-wrap: wrap;
235
+ }
236
+
237
+ .download-btn {
238
+ padding: 10px 20px;
239
+ border: 2px solid #667eea;
240
+ background: white;
241
+ color: #667eea;
242
+ border-radius: 8px;
243
+ font-size: 13px;
244
+ font-weight: 500;
245
+ cursor: pointer;
246
+ transition: all 0.3s ease;
247
+ }
248
+
249
+ .download-btn:hover {
250
+ background: #667eea;
251
+ color: white;
252
+ }
253
+
254
+ .hidden {
255
+ display: none;
256
+ }
257
+
258
+ .error {
259
+ color: #e74c3c;
260
+ font-size: 12px;
261
+ margin-top: 5px;
262
+ }
263
+
264
+ @media (max-width: 480px) {
265
+ .container {
266
+ padding: 20px;
267
+ margin: 10px;
268
+ }
269
+
270
+ .category-selector {
271
+ grid-template-columns: repeat(3, 1fr);
272
+ }
273
+
274
+ .input-row {
275
+ grid-template-columns: 1fr;
276
+ }
277
+
278
+ .color-controls {
279
+ grid-template-columns: 1fr;
280
+ }
281
+ }
282
+ </style>
283
+ </head>
284
+ <body>
285
+ <div class="container">
286
+ <div class="header">
287
+ <h1 class="title">QR Generator Pro</h1>
288
+ <p class="subtitle">Create professional QR codes with advanced customization</p>
289
+ </div>
290
+
291
+ <div class="category-selector">
292
+ <button class="category-btn active" data-type="text">
293
+ <span class="category-icon">📝</span>
294
+ <span>Text</span>
295
+ </button>
296
+ <button class="category-btn" data-type="url">
297
+ <span class="category-icon">🔗</span>
298
+ <span>URL</span>
299
+ </button>
300
+ <button class="category-btn" data-type="email">
301
+ <span class="category-icon">✉️</span>
302
+ <span>Email</span>
303
+ </button>
304
+ <button class="category-btn" data-type="phone">
305
+ <span class="category-icon">📞</span>
306
+ <span>Phone</span>
307
+ </button>
308
+ <button class="category-btn" data-type="sms">
309
+ <span class="category-icon">💬</span>
310
+ <span>SMS</span>
311
+ </button>
312
+ <button class="category-btn" data-type="wifi">
313
+ <span class="category-icon">📶</span>
314
+ <span>WiFi</span>
315
+ </button>
316
+ <button class="category-btn" data-type="vcard">
317
+ <span class="category-icon">👤</span>
318
+ <span>vCard</span>
319
+ </button>
320
+ <button class="category-btn" data-type="location">
321
+ <span class="category-icon">📍</span>
322
+ <span>Location</span>
323
+ </button>
324
+ <button class="category-btn" data-type="event">
325
+ <span class="category-icon">📅</span>
326
+ <span>Event</span>
327
+ </button>
328
+ </div>
329
+
330
+ <div id="input-forms">
331
+ <!-- Text Form -->
332
+ <div id="text-form" class="form-section">
333
+ <div class="input-group">
334
+ <label class="input-label">Enter your text</label>
335
+ <textarea class="input-field" id="text-input" rows="3" placeholder="Type your message here..."></textarea>
336
+ </div>
337
+ </div>
338
+
339
+ <!-- URL Form -->
340
+ <div id="url-form" class="form-section hidden">
341
+ <div class="input-group">
342
+ <label class="input-label">Website URL</label>
343
+ <input type="url" class="input-field" id="url-input" placeholder="https://example.com">
344
+ </div>
345
+ </div>
346
+
347
+ <!-- Email Form -->
348
+ <div id="email-form" class="form-section hidden">
349
+ <div class="input-group">
350
+ <label class="input-label">Email Address</label>
351
+ <input type="email" class="input-field" id="email-input" placeholder="[email protected]">
352
+ </div>
353
+ <div class="input-group">
354
+ <label class="input-label">Subject (Optional)</label>
355
+ <input type="text" class="input-field" id="email-subject" placeholder="Email subject">
356
+ </div>
357
+ <div class="input-group">
358
+ <label class="input-label">Message (Optional)</label>
359
+ <textarea class="input-field" id="email-body" rows="2" placeholder="Email message"></textarea>
360
+ </div>
361
+ </div>
362
+
363
+ <!-- Phone Form -->
364
+ <div id="phone-form" class="form-section hidden">
365
+ <div class="input-group">
366
+ <label class="input-label">Phone Number</label>
367
+ <input type="tel" class="input-field" id="phone-input" placeholder="+1234567890">
368
+ </div>
369
+ </div>
370
+
371
+ <!-- SMS Form -->
372
+ <div id="sms-form" class="form-section hidden">
373
+ <div class="input-group">
374
+ <label class="input-label">Phone Number</label>
375
+ <input type="tel" class="input-field" id="sms-phone" placeholder="+1234567890">
376
+ </div>
377
+ <div class="input-group">
378
+ <label class="input-label">Message</label>
379
+ <textarea class="input-field" id="sms-message" rows="2" placeholder="SMS message"></textarea>
380
+ </div>
381
+ </div>
382
+
383
+ <!-- WiFi Form -->
384
+ <div id="wifi-form" class="form-section hidden">
385
+ <div class="input-group">
386
+ <label class="input-label">Network Name (SSID)</label>
387
+ <input type="text" class="input-field" id="wifi-ssid" placeholder="My WiFi Network">
388
+ </div>
389
+ <div class="input-row">
390
+ <div class="input-group">
391
+ <label class="input-label">Password</label>
392
+ <input type="text" class="input-field" id="wifi-password" placeholder="password123">
393
+ </div>
394
+ <div class="input-group">
395
+ <label class="input-label">Security</label>
396
+ <select class="input-field" id="wifi-security">
397
+ <option value="WPA">WPA/WPA2</option>
398
+ <option value="WEP">WEP</option>
399
+ <option value="nopass">None</option>
400
+ </select>
401
+ </div>
402
+ </div>
403
+ </div>
404
+
405
+ <!-- vCard Form -->
406
+ <div id="vcard-form" class="form-section hidden">
407
+ <div class="input-row">
408
+ <div class="input-group">
409
+ <label class="input-label">First Name</label>
410
+ <input type="text" class="input-field" id="vcard-firstname" placeholder="John">
411
+ </div>
412
+ <div class="input-group">
413
+ <label class="input-label">Last Name</label>
414
+ <input type="text" class="input-field" id="vcard-lastname" placeholder="Doe">
415
+ </div>
416
+ </div>
417
+ <div class="input-group">
418
+ <label class="input-label">Organization</label>
419
+ <input type="text" class="input-field" id="vcard-org" placeholder="Company Name">
420
+ </div>
421
+ <div class="input-row">
422
+ <div class="input-group">
423
+ <label class="input-label">Phone</label>
424
+ <input type="tel" class="input-field" id="vcard-phone" placeholder="+1234567890">
425
+ </div>
426
+ <div class="input-group">
427
+ <label class="input-label">Email</label>
428
+ <input type="email" class="input-field" id="vcard-email" placeholder="[email protected]">
429
+ </div>
430
+ </div>
431
+ </div>
432
+
433
+ <!-- Location Form -->
434
+ <div id="location-form" class="form-section hidden">
435
+ <div class="input-row">
436
+ <div class="input-group">
437
+ <label class="input-label">Latitude</label>
438
+ <input type="number" class="input-field" id="location-lat" placeholder="40.7128" step="any">
439
+ </div>
440
+ <div class="input-group">
441
+ <label class="input-label">Longitude</label>
442
+ <input type="number" class="input-field" id="location-lng" placeholder="-74.0060" step="any">
443
+ </div>
444
+ </div>
445
+ </div>
446
+
447
+ <!-- Event Form -->
448
+ <div id="event-form" class="form-section hidden">
449
+ <div class="input-group">
450
+ <label class="input-label">Event Title</label>
451
+ <input type="text" class="input-field" id="event-title" placeholder="Meeting with Team">
452
+ </div>
453
+ <div class="input-row">
454
+ <div class="input-group">
455
+ <label class="input-label">Start Date</label>
456
+ <input type="datetime-local" class="input-field" id="event-start">
457
+ </div>
458
+ <div class="input-group">
459
+ <label class="input-label">End Date</label>
460
+ <input type="datetime-local" class="input-field" id="event-end">
461
+ </div>
462
+ </div>
463
+ <div class="input-group">
464
+ <label class="input-label">Location (Optional)</label>
465
+ <input type="text" class="input-field" id="event-location" placeholder="Conference Room A">
466
+ </div>
467
+ </div>
468
+ </div>
469
+
470
+ <div class="customization">
471
+ <div class="custom-title">🎨 Customization</div>
472
+ <div class="color-controls">
473
+ <div class="color-group">
474
+ <input type="color" class="color-input" id="fg-color" value="#000000">
475
+ <span>Foreground</span>
476
+ </div>
477
+ <div class="color-group">
478
+ <input type="color" class="color-input" id="bg-color" value="#ffffff">
479
+ <span>Background</span>
480
+ </div>
481
+ </div>
482
+ <div class="size-control">
483
+ <span>Size:</span>
484
+ <input type="range" class="size-slider" id="size-slider" min="128" max="400" value="256">
485
+ <span id="size-display">256px</span>
486
+ </div>
487
+ </div>
488
+
489
+ <button class="generate-btn" onclick="generateQR()">
490
+ Generate QR Code
491
+ </button>
492
+
493
+ <div id="qr-output" class="qr-output hidden">
494
+ <canvas id="qr-canvas" class="qr-canvas"></canvas>
495
+ <div class="download-controls">
496
+ <button class="download-btn" onclick="downloadQR('png')">PNG</button>
497
+ <button class="download-btn" onclick="downloadQR('jpg')">JPG</button>
498
+ <button class="download-btn" onclick="downloadQR('svg')">SVG</button>
499
+ </div>
500
+ </div>
501
+ </div>
502
+
503
+ <script>
504
+ let currentType = 'text';
505
+ let currentQRData = '';
506
+
507
+ // Category switching
508
+ document.querySelectorAll('.category-btn').forEach(btn => {
509
+ btn.addEventListener('click', () => {
510
+ document.querySelectorAll('.category-btn').forEach(b => b.classList.remove('active'));
511
+ btn.classList.add('active');
512
+
513
+ const type = btn.dataset.type;
514
+ currentType = type;
515
+
516
+ document.querySelectorAll('.form-section').forEach(form => form.classList.add('hidden'));
517
+ document.getElementById(`${type}-form`).classList.remove('hidden');
518
+ });
519
+ });
520
+
521
+ // Size slider
522
+ document.getElementById('size-slider').addEventListener('input', (e) => {
523
+ document.getElementById('size-display').textContent = e.target.value + 'px';
524
+ });
525
+
526
+ function generateQRData() {
527
+ switch (currentType) {
528
+ case 'text':
529
+ return document.getElementById('text-input').value;
530
+
531
+ case 'url':
532
+ const url = document.getElementById('url-input').value;
533
+ return url.startsWith('http') ? url : `https://${url}`;
534
+
535
+ case 'email':
536
+ const email = document.getElementById('email-input').value;
537
+ const subject = document.getElementById('email-subject').value;
538
+ const body = document.getElementById('email-body').value;
539
+ let mailto = `mailto:${email}`;
540
+ const params = [];
541
+ if (subject) params.push(`subject=${encodeURIComponent(subject)}`);
542
+ if (body) params.push(`body=${encodeURIComponent(body)}`);
543
+ if (params.length) mailto += '?' + params.join('&');
544
+ return mailto;
545
+
546
+ case 'phone':
547
+ return `tel:${document.getElementById('phone-input').value}`;
548
+
549
+ case 'sms':
550
+ const smsPhone = document.getElementById('sms-phone').value;
551
+ const smsMessage = document.getElementById('sms-message').value;
552
+ return `sms:${smsPhone}${smsMessage ? `?body=${encodeURIComponent(smsMessage)}` : ''}`;
553
+
554
+ case 'wifi':
555
+ const ssid = document.getElementById('wifi-ssid').value;
556
+ const password = document.getElementById('wifi-password').value;
557
+ const security = document.getElementById('wifi-security').value;
558
+ return `WIFI:T:${security};S:${ssid};P:${password};;`;
559
+
560
+ case 'vcard':
561
+ const firstName = document.getElementById('vcard-firstname').value;
562
+ const lastName = document.getElementById('vcard-lastname').value;
563
+ const org = document.getElementById('vcard-org').value;
564
+ const phone = document.getElementById('vcard-phone').value;
565
+ const vcardEmail = document.getElementById('vcard-email').value;
566
+
567
+ return `BEGIN:VCARD
568
+ VERSION:3.0
569
+ FN:${firstName} ${lastName}
570
+ N:${lastName};${firstName};;;
571
+ ORG:${org}
572
+ TEL:${phone}
573
+ EMAIL:${vcardEmail}
574
+ END:VCARD`;
575
+
576
+ case 'location':
577
+ const lat = document.getElementById('location-lat').value;
578
+ const lng = document.getElementById('location-lng').value;
579
+ return `geo:${lat},${lng}`;
580
+
581
+ case 'event':
582
+ const title = document.getElementById('event-title').value;
583
+ const start = document.getElementById('event-start').value;
584
+ const end = document.getElementById('event-end').value;
585
+ const location = document.getElementById('event-location').value;
586
+
587
+ const formatDate = (dateStr) => {
588
+ return new Date(dateStr).toISOString().replace(/[-:]/g, '').split('.')[0] + 'Z';
589
+ };
590
+
591
+ return `BEGIN:VEVENT
592
+ SUMMARY:${title}
593
+ DTSTART:${formatDate(start)}
594
+ DTEND:${formatDate(end)}
595
+ LOCATION:${location}
596
+ END:VEVENT`;
597
+
598
+ default:
599
+ return '';
600
+ }
601
+ }
602
+
603
+ function generateQR() {
604
+ const data = generateQRData();
605
+
606
+ if (!data.trim()) {
607
+ alert('Please enter some data to generate QR code');
608
+ return;
609
+ }
610
+
611
+ currentQRData = data;
612
+ const canvas = document.getElementById('qr-canvas');
613
+ const fgColor = document.getElementById('fg-color').value;
614
+ const bgColor = document.getElementById('bg-color').value;
615
+ const size = parseInt(document.getElementById('size-slider').value);
616
+
617
+ QRCode.toCanvas(canvas, data, {
618
+ width: size,
619
+ height: size,
620
+ color: {
621
+ dark: fgColor,
622
+ light: bgColor
623
+ },
624
+ errorCorrectionLevel: 'M',
625
+ margin: 2
626
+ }, (error) => {
627
+ if (error) {
628
+ console.error(error);
629
+ alert('Error generating QR code');
630
+ } else {
631
+ document.getElementById('qr-output').classList.remove('hidden');
632
+ canvas.scrollIntoView({ behavior: 'smooth', block: 'center' });
633
+ }
634
+ });
635
+ }
636
+
637
+ function downloadQR(format) {
638
+ const canvas = document.getElementById('qr-canvas');
639
+
640
+ if (format === 'svg') {
641
+ // Generate SVG version
642
+ QRCode.toString(currentQRData, {
643
+ type: 'svg',
644
+ width: parseInt(document.getElementById('size-slider').value),
645
+ color: {
646
+ dark: document.getElementById('fg-color').value,
647
+ light: document.getElementById('bg-color').value
648
+ }
649
+ }, (err, string) => {
650
+ if (!err) {
651
+ const blob = new Blob([string], { type: 'image/svg+xml' });
652
+ const url = URL.createObjectURL(blob);
653
+ const a = document.createElement('a');
654
+ a.href = url;
655
+ a.download = `qrcode.svg`;
656
+ a.click();
657
+ URL.revokeObjectURL(url);
658
+ }
659
+ });
660
+ } else {
661
+ // PNG or JPG
662
+ const mimeType = format === 'png' ? 'image/png' : 'image/jpeg';
663
+ const url = canvas.toDataURL(mimeType, 0.9);
664
+ const a = document.createElement('a');
665
+ a.href = url;
666
+ a.download = `qrcode.${format}`;
667
+ a.click();
668
+ }
669
+ }
670
+
671
+ // Auto-generate on input for better UX
672
+ document.addEventListener('input', (e) => {
673
+ if (e.target.classList.contains('input-field') || e.target.id === 'size-slider') {
674
+ // Debounce auto-generation
675
+ clearTimeout(window.autoGenTimeout);
676
+ window.autoGenTimeout = setTimeout(() => {
677
+ const data = generateQRData();
678
+ if (data.trim()) {
679
+ generateQR();
680
+ }
681
+ }, 500);
682
+ }
683
+ });
684
+
685
+ // Initialize with sample data
686
+ document.getElementById('text-input').value = 'Hello, World! 👋';
687
+ generateQR();
688
+ </script>
689
+ </body>
690
+ </html>