-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.html
More file actions
167 lines (154 loc) · 12.3 KB
/
Copy pathindex.html
File metadata and controls
167 lines (154 loc) · 12.3 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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Wasm Studio | Professional Background Removal</title>
<link rel="stylesheet" href="./src/style.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;600;800&family=JetBrains+Mono:wght@400;700&display=swap" rel="stylesheet">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js"></script>
<!-- Vercel Web Analytics -->
<script>
window.va = window.va || function () { (window.vaq = window.vaq || []).push(arguments); };
</script>
<script defer src="/_vercel/insights/script.js"></script>
</head>
<body class="bg-[#0f172a] text-slate-100 min-h-screen font-['Outfit'] antialiased">
<!-- Main App Container -->
<div id="app" class="h-screen flex flex-col overflow-hidden">
<!-- Header -->
<header class="h-16 border-b border-slate-800 bg-[#0f172a] flex items-center justify-between px-8 z-50">
<div class="flex items-center gap-3">
<div class="w-10 h-10 bg-indigo-600 rounded-xl flex items-center justify-center shadow-lg shadow-indigo-500/20">
<svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2.5" d="M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10"></path></svg>
</div>
<h1 class="text-xl font-black">Wasm<span class="text-indigo-500">Studio</span></h1>
</div>
<div class="flex gap-4">
<button id="batchProcessBtn" class="hidden px-6 py-2 bg-indigo-600 hover:bg-indigo-500 rounded-full font-bold transition-all shadow-lg active:scale-95 text-sm">
Process All & Download ZIP
</button>
<button id="clearAllBtn" class="hidden px-4 py-2 bg-slate-800 hover:bg-slate-700 rounded-full text-xs font-bold text-slate-400">
Clear Queue
</button>
</div>
</header>
<main class="flex-1 flex overflow-hidden">
<!-- Sidebar: Navigation & Queue -->
<aside class="w-[340px] border-r border-slate-800 flex flex-col bg-slate-900/20">
<div class="p-6">
<h2 class="text-xs font-black uppercase tracking-widest text-slate-500 mb-4">Batch Queue</h2>
<div class="flex items-center justify-between bg-slate-800/40 p-3 rounded-xl border border-slate-800">
<span id="queueCount" class="text-xs font-bold text-slate-400">0 / 50 Images</span>
<button id="addImagesBtn" class="bg-indigo-600 hover:bg-indigo-500 p-1.5 rounded-lg text-white transition-colors">
<svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path d="M12 4v16m8-8H4" stroke-width="2.5"/></svg>
</button>
</div>
<input type="file" id="fileInput" class="hidden" accept="image/*" multiple>
</div>
<div id="imageQueue" class="flex-1 overflow-y-auto px-6 pb-6 space-y-3 cursor-pointer">
<!-- Cards will be injected here -->
<div id="emptyState" class="h-40 border-2 border-dashed border-slate-800 rounded-3xl flex flex-col items-center justify-center text-slate-600">
<svg class="w-8 h-8 mb-2 opacity-50" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path 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" stroke-width="2"/></svg>
<span class="text-[10px] font-black uppercase">Drop Images</span>
</div>
</div>
</aside>
<!-- Center: Canvas Area -->
<section id="dropZone" class="flex-1 bg-slate-950 flex flex-col items-center justify-center relative p-8">
<!-- Large Checkerboard Canvas -->
<div class="relative max-w-full max-h-full flex items-center justify-center shadow-2xl">
<canvas id="mainCanvas" class="max-w-full max-h-[70vh] rounded-lg shadow-2xl transition-transform cursor-crosshair"></canvas>
<!-- No Image Overlay -->
<div id="noImageOverlay" class="absolute inset-0 bg-[#0f172a] flex flex-center items-center justify-center text-center p-12">
<div class="max-w-md">
<h2 class="text-3xl font-black mb-4">Ready to start?</h2>
<p class="text-slate-500 text-sm leading-relaxed mb-8">Upload multiple photos to remove backgrounds in bulk. Click anywhere on the image once uploaded to select a background color.</p>
<button onclick="document.getElementById('fileInput').click()" class="px-8 py-3 bg-indigo-600 rounded-2xl font-black shadow-lg shadow-indigo-500/20 hover:scale-105 active:scale-95 transition-all">Upload First Image</button>
</div>
</div>
</div>
<!-- Canvas Footer Stats -->
<div class="absolute bottom-10 left-10 flex gap-6 items-center">
<div class="flex flex-col">
<span id="canvasRes" class="text-[10px] font-black text-slate-500 uppercase">Res: ---</span>
<span id="canvasFormat" class="text-[10px] font-black text-indigo-500 uppercase">Fidelity: Original</span>
</div>
</div>
</section>
<!-- Right Sidebar: Configuration -->
<aside class="w-[360px] border-l border-slate-800 bg-[#0f172a] p-8 flex flex-col gap-8">
<div class="space-y-6">
<div class="flex items-center gap-2">
<div class="w-2 h-2 bg-indigo-500 rounded-full"></div>
<h2 class="text-xs font-black uppercase tracking-[0.2em] text-slate-400">Removal Tool</h2>
</div>
<div class="p-6 bg-slate-800/40 rounded-3xl border border-slate-800 space-y-6">
<div class="flex justify-between items-center">
<label class="text-xs font-bold text-slate-500 uppercase">Target Color</label>
<div class="flex items-center gap-3">
<div id="colorPreview" class="w-10 h-10 rounded-xl border border-white/10 shadow-lg relative overflow-hidden">
<div class="absolute inset-0 opacity-20 bg-[url('./checkerboard.png')]"></div>
</div>
<input type="color" id="removeColorPicker" value="#00FF00" class="w-10 h-10 rounded-xl bg-slate-900 border-none cursor-pointer">
</div>
</div>
<div class="space-y-3">
<div class="flex justify-between items-center text-[10px] font-black uppercase text-slate-600 tracking-widest">
<label>Sensitivity</label>
<span id="thresholdVal" class="text-indigo-400">30</span>
</div>
<input type="range" id="thresholdSlider" min="0" max="255" value="30" class="w-full h-1.5 bg-slate-900 rounded-full appearance-none cursor-pointer accent-indigo-500">
</div>
<div class="pt-4 space-y-3">
<button id="applyAllSettingsBtn" class="w-full py-3 bg-slate-100 text-slate-950 rounded-2xl font-black text-xs uppercase tracking-widest hover:bg-white transition-all">
Apply to all images
</button>
<button id="removeBgBtn" class="w-full py-4 bg-indigo-600 hover:bg-indigo-500 rounded-2xl font-black text-sm shadow-xl shadow-indigo-600/20 transition-all active:translate-y-0.5">
Process Current
</button>
</div>
</div>
</div>
<div class="mt-auto p-4 bg-indigo-500/5 rounded-2xl border border-indigo-500/10">
<p class="text-[10px] font-bold text-indigo-400 leading-relaxed uppercase italic">
"Your original images are never modified. Backgrounds are removed using high-precision Euclidean distance in Wasm."
</p>
</div>
</aside>
</main>
<!-- Footer Credits -->
<footer class="h-10 border-t border-slate-800 bg-[#0f172a] flex items-center justify-between px-8 text-[10px] font-bold tracking-widest uppercase text-slate-500">
<div class="flex items-center gap-1">
BUILD WITH <span class="text-red-500 animate-pulse">❤️</span> BY <span class="text-slate-300">NOOR UL HASSAN</span>
</div>
<div class="flex items-center gap-6">
<a href="https://linkedin.com/in/codewithnuh" target="_blank" class="flex items-center gap-2 hover:text-indigo-400 transition-colors">
<svg class="w-3.5 h-3.5" fill="currentColor" viewBox="0 0 24 24"><path d="M19 0h-14c-2.761 0-5 2.239-5 5v14c0 2.761 2.239 5 5 5h14c2.762 0 5-2.239 5-5v-14c0-2.761-2.238-5-5-5zm-11 19h-3v-11h3v11zm-1.5-12.268c-.966 0-1.75-.79-1.75-1.764s.784-1.764 1.75-1.764 1.75.79 1.75 1.764-.783 1.764-1.75 1.764zm13.5 12.268h-3v-5.604c0-3.368-4-3.113-4 0v5.604h-3v-11h3v1.765c1.396-2.586 7-2.777 7 2.476v6.759z"/></svg>
LINKEDIN
</a>
<a href="https://github.com/codewithnuh/img-processor" target="_blank" class="flex items-center gap-2 hover:text-indigo-400 transition-colors">
<svg class="w-3.5 h-3.5" fill="currentColor" viewBox="0 0 24 24"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.042-1.416-4.042-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/></svg>
GITHUB
</a>
</div>
</footer>
<!-- Progress Modal -->
<div id="progressOverlay" class="hidden fixed inset-0 bg-[#0f172a]/95 backdrop-blur-2xl z-[100] items-center justify-center flex-col">
<div class="relative w-64 h-64 flex items-center justify-center flex-col">
<svg class="absolute inset-0 w-full h-full -rotate-90" viewBox="0 0 100 100">
<circle class="text-slate-800" stroke-width="6" stroke="currentColor" fill="transparent" r="45" cx="50" cy="50"/>
<circle id="progressCircle" class="text-indigo-500 transition-all duration-300" stroke-width="6" stroke-dasharray="283" stroke-dashoffset="283" stroke-linecap="round" stroke="currentColor" fill="transparent" r="45" cx="50" cy="50"/>
</svg>
<span id="progressPercent" class="text-5xl font-black italic">0%</span>
<span id="queueIndex" class="text-[10px] font-bold text-slate-500 uppercase mt-2">Processing 1/1</span>
</div>
<p id="progressDetail" class="text-indigo-400 font-bold mt-8 text-sm uppercase tracking-widest">engine starting...</p>
</div>
</div>
<script type="module" src="/src/main.ts"></script>
<script src="/processor.js"></script>
</body>
</html>