-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.html
369 lines (353 loc) · 18.4 KB
/
index.html
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
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<link href="recycle-icon.png" rel="icon">
<meta name="viewport" content="width=device-width">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
<title>RecycleSorter</title>
<style>
@font-face {
font-family: nougat;
src: url(Nougat-ExtraBlack.ttf);
}
main {
margin: 0;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
body {
font-family: nougat;
background-color: #35393E;
color: white;
}
.hide-nav {
opacity: 0;
visibility: hidden;
transform: scale(1.1);
transition: visibility 0s linear 0.25s, opacity 0.25s 0s, transform 0.25s;
}
#title {
font-size: min(8vw, 50px);
}
a {
color: white;
text-decoration: none;
}
.btn {
justify-content: center;
font-size: min(5vw, 20px);
border: 1px solid white;
padding: 10px;
border-radius: 5px;
transition: .2s;
display: inline;
margin-top: 100px;
margin-bottom: 100px;
}
.btn:hover {
background-color: white;
color: #35393E;
cursor: pointer;
}
canvas {
border-radius: 10px;
margin-bottom: 50px;
}
#label-container {
margin-top: 30px;
}
h1 {
opacity: 1;
animation: fade 1s linear;
}
#startSorting {
opacity: 1;
animation: fade 2s linear;
display: table;
margin-left: auto;
margin-right: auto;
}
@keyframes fade {
0%, 50%{ opacity: 0 }
100% { opacity: 1 }
}
.modal {
position: fixed;
left: 2;
top: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
opacity: 0;
visibility: hidden;
transform: scale(1.1);
transition: visibility 0s linear 0.25s, opacity 0.25s 0s, transform 0.25s;
}
.modal-content {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: white;
padding: 1rem 1.5rem;
width: 24rem;
border-radius: 0.5rem;
color: black;
}
.close-button {
float: right;
width: 1.5rem;
line-height: 1.5rem;
text-align: center;
cursor: pointer;
border-radius: 0.25rem;
background-color: lightgray;
}
.close-button:hover {
background-color: darkgray;
}
.show-modal {
opacity: 1;
visibility: visible;
transform: scale(1.0);
transition: visibility 0s linear 0s, opacity 0.25s 0s, transform 0.25s;
}
.topnav {
margin: 0;
top: 0;
overflow: hidden;
background-color: #333;
}
.topnav a {
float: left;
display: block;
color: #f2f2f2;
text-align: center;
padding: 14px 16px;
text-decoration: none;
font-size: 17px;
}
.topnav a:hover {
background-color: #ddd;
color: black;
}
.topnav a.active {
background-color: #04AA6D;
color: white;
}
.topnav .icon {
display: none;
}
@media screen and (max-width: 600px) {
.topnav a:not(:first-child) {display: none;}
.topnav a.icon {
float: right;
display: block;
}
}
@media screen and (max-width: 600px) {
.topnav.responsive {position: relative;}
.topnav.responsive .icon {
position: absolute;
right: 0;
top: 0;
}
.topnav.responsive a {
float: none;
display: block;
text-align: left;
}
}
.new_footer_top {
padding: 60px 0px 160px;
position: relative;
overflow-x: hidden;
}
.new_footer_area {
padding-top: 5px;
padding-bottom: 50px;
margin-top: 80vh;
}
.new_footer_top .footer_bg {
position: absolute;
bottom: 0;
background: url("./footer_bg.png") no-repeat scroll center 0;
width: 100%;
height: 266px;
}
.new_footer_top .footer_bg .footer_bg_one {
background: url("./volks.gif") no-repeat center center;
width: 330px;
height: 105px;
background-size:100%;
position: absolute;
bottom: 0;
left: 30%;
-webkit-animation: myfirst 22s linear infinite;
animation: myfirst 22s linear infinite;
}
.new_footer_top .footer_bg .footer_bg_two {
background: url("./cyclist.gif") no-repeat center center;
width: 88px;
height: 100px;
background-size:100%;
bottom: 0;
left: 38%;
position: absolute;
-webkit-animation: myfirst 30s linear infinite;
animation: myfirst 30s linear infinite;
}
@-moz-keyframes myfirst {
0% {left: -25%;}
100% {left: 100%;}
}
@-webkit-keyframes myfirst {
0% {left: -25%;}
100% {left: 100%;}
}
@keyframes myfirst {
0% {left: -25%;}
100% {left: 100%; }
}
</style>
</head>
<body>
<div class="topnav" id="myTopnav">
<a href="#" class="active">Web App</a>
<a href="https://github.com/iancheung0202/RecycleSorter" target="_blank">Github Repo</a>
<a href="https://discord.com/api/oauth2/authorize?client_id=1057333274449547354&permissions=51200&scope=bot">Discord Bot Extension</a>
<a href="javascript:void(0);" class="icon" onclick="responsiveNav()">
<i class="fa fa-bars"></i>
</a>
</div>
<main>
<div class="modal">
<div class="modal-content">
<span class="close-button">×</span>
<div id="modal-content" style="font-family: Arial, Helvetica, sans-serif;"></div>
</div>
</div>
<div id="startScreen">
<div id="title"><h1><img src="recycle-icon.png" style="height: min(10vw, 100px);margin-left: 15%;margin-top: 55px;"> <span style="font-size: min(6.5vw, 37px);"><a href="https://gunnhacks.com">GunnHacks 9.0</a></span><br><a href="https://linktr.ee/RecycleSorter" target="_blank">RecycleSorter</a><br><span style="font-size: min(6vw, 30px);margin-left: 30%;margin-top: -555px;"><i>By The Re-Cyclists</i></span></h1></div>
<span class="btn" onclick="init('environment')" id="startSorting">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-search" viewBox="0 0 16 16">
<path d="M11.742 10.344a6.5 6.5 0 1 0-1.397 1.398h-.001c.03.04.062.078.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1.007 1.007 0 0 0-.115-.1zM12 6.5a5.5 5.5 0 1 1-11 0 5.5 5.5 0 0 1 11 0z"/>
</svg> Start Sorting</span>
</div>
<div id="sortScreen" style="visibility: hidden; display: none;">
<div id="webcam-container"></div>
<div id="sortBtn"></div>
<div id="label-container"></div>
</div>
</main>
<footer class="new_footer_area" width="100%">
<div class="new_footer_top">
<div class="container">
</div>
<div class="footer_bg">
<div class="footer_bg_one"></div>
<div class="footer_bg_two"></div>
</div>
</div>
</footer>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@1.3.1/dist/tf.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/@teachablemachine/image@0.8/dist/teachablemachine-image.min.js"></script>
<script type="text/javascript">
startScreen = document.getElementById("startScreen");
sortScreen = document.getElementById("sortScreen");
const modal = document.querySelector(".modal");
// const trigger = document.querySelector(".trigger");
const closeButton = document.querySelector(".close-button");
const URL = "https://teachablemachine.withgoogle.com/models/CgTV5zJeZ/";
let model, webcam, labelContainer, maxPredictions;
// Load the image model and setup the webcam
async function init(arg) {
while (document.getElementById("webcam-container").firstChild) {
document.getElementById("webcam-container").removeChild(document.getElementById("webcam-container").firstChild);
} // Remove all previous webcams
document.getElementById("webcam-container").innerHTML = `
<img src="loading.gif" height="40px" width="40px" style="margin: 40px;" />` // Loading Icon
startScreen.style.visibility = "hidden";
startScreen.style.display = "none";
sortScreen.style.visibility = "visible";
sortScreen.style.display = "block";
const modelURL = URL + "model.json";
const metadataURL = URL + "metadata.json";
model = await tmImage.load(modelURL, metadataURL);
maxPredictions = model.getTotalClasses();
// const isMobile = navigator.userAgentData.mobile;
// console.log(isMobile);
// if (isMobile) {
// alert("You are using mobile!");
// }
const flip = false;
var next = 'self';
// if (isMobile) {
// flip = false;
// }
webcam = new tmImage.Webcam(300, 300, flip); // width, height, flip
if (arg == 'environment') {
await webcam.setup({facingMode: "environment"}); // request access to the webcam
} else if (arg == 'self') {
await webcam.setup();
next = 'environment';
}
await webcam.play();
window.requestAnimationFrame(loop);
// append elements to the DOM
document.getElementById("webcam-container").innerHTML = ""
document.getElementById("webcam-container").appendChild(webcam.canvas);
document.getElementById("sortBtn").innerHTML = `<span class="btn" id="sortBtn" onclick="predict()"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-display" viewBox="0 0 16 16"> <path d="M0 4s0-2 2-2h12s2 0 2 2v6s0 2-2 2h-4c0 .667.083 1.167.25 1.5H11a.5.5 0 0 1 0 1H5a.5.5 0 0 1 0-1h.75c.167-.333.25-.833.25-1.5H2s-2 0-2-2V4zm1.398-.855a.758.758 0 0 0-.254.302A1.46 1.46 0 0 0 1 4.01V10c0 .325.078.502.145.602.07.105.17.188.302.254a1.464 1.464 0 0 0 .538.143L2.01 11H14c.325 0 .502-.078.602-.145a.758.758 0 0 0 .254-.302 1.464 1.464 0 0 0 .143-.538L15 9.99V4c0-.325-.078-.502-.145-.602a.757.757 0 0 0-.302-.254A1.46 1.46 0 0 0 13.99 3H2c-.325 0-.502.078-.602.145z"/> </svg> Sort</span> <span class="btn" id="flipCamera" onclick="init('${next}')"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-camera-fill" viewBox="0 0 16 16"> <path d="M10.5 8.5a2.5 2.5 0 1 1-5 0 2.5 2.5 0 0 1 5 0z"/> <path d="M2 4a2 2 0 0 0-2 2v6a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2h-1.172a2 2 0 0 1-1.414-.586l-.828-.828A2 2 0 0 0 9.172 2H6.828a2 2 0 0 0-1.414.586l-.828.828A2 2 0 0 1 3.172 4H2zm.5 2a.5.5 0 1 1 0-1 .5.5 0 0 1 0 1zm9 2.5a3.5 3.5 0 1 1-7 0 3.5 3.5 0 0 1 7 0z"/> </svg> Flip Camera</span>`
}
async function loop() {
webcam.update(); // update the webcam frame
// await predict();
window.requestAnimationFrame(loop);
}
async function predict() {
const prediction = await model.predict(webcam.canvas);
const probabilities = [];
for (let i = 0; i < maxPredictions; i++) {
// const classPrediction = prediction[i].className + ": " + prediction[i].probability.toFixed(2);
// labelContainer.childNodes[i].innerHTML = classPrediction;
const classPrediction = probabilities.push(prediction[i].probability)
}
largestProbability = Math.max.apply(Math, probabilities)
const index = probabilities.indexOf(largestProbability);
toggleModal();
var canvases = document.getElementsByTagName('canvas');
const dataURL = canvases[0].toDataURL();
closeButton.addEventListener("click", toggleModal);
if (prediction[index].className == "Plastic") {
document.getElementById("modal-content").innerHTML = `<img src="${dataURL}" width="100%"> <br><br><b>Category:</b> <span style="color: blue;">${prediction[index].className}</span> <br><b>Confidence Level:</b> ${prediction[index].probability.toFixed(2)*100}%<br><br>Make sure all of your plastics are properly sorted and separated by type before being recycled. Different types of plastic require different recycling processes, so make sure to separate items like plastic bottles from plastic bags, containers, and other types of packaging.<br><br>Additionally, it's important to make sure that any plastic items you plan to recycle are clean and dry. `;
} else if (prediction[index].className == "Metals") {
document.getElementById("modal-content").innerHTML = `<img src="${dataURL}" width="100%"> <br><br><b>Category:</b> <span style="color: brown;">${prediction[index].className}</span> <br><b>Confidence Level:</b> ${prediction[index].probability.toFixed(2)*100}%<br><br>Make sure to sort the metals you have into their specific categories. For example, separate aluminum cans from steel cans. This makes it easier to recycle the metals separately and properly. Additionally, make sure to clean off any food residue from the metals so it will be easier to be recycled. <br><br>Furthermore, make sure to properly dispose of any hazardous metals such as lead or mercury. These metals can be harmful to the environment and should never be put in the recycling bin. `;
} else if (prediction[index].className == "Glass") {
document.getElementById("modal-content").innerHTML = `<img src="${dataURL}" width="100%"> <br><br><b>Category:</b> <span style="color: skyblue;">${prediction[index].className}</span> <br><b>Confidence Level:</b> ${prediction[index].probability.toFixed(2)*100}%<br><br> When recycling glass, it is important to rinse it out before putting it in the recycling bin. This will prevent contamination of other materials in the recycling bin and will ensure that the glass can be recycled properly. Furthermore, it is important to remove any lids, caps or labels from the glass before recycling. This will help speed up the process of sorting and recycling the glass.`;
} else if (prediction[index].className == "Paper") {
document.getElementById("modal-content").innerHTML = `<img src="${dataURL}" width="100%"> <br><br><b>Category:</b> <span style="color: purple;">${prediction[index].className}</span> <br><b>Confidence Level:</b> ${prediction[index].probability.toFixed(2)*100}%<br><br>When it comes to recycling paper, it is important to avoid recycling paper with food, liquids, or other contaminants on the paper as these can contaminate the recycling process. Additionally, make sure to remove staples, paperclips, and other non-paper items. You should also always break down larger pieces of paper, such as cardboard boxes, before recycling them. Breaking down these items helps to ensure that they can be recycled more effectively. `;
} else if (prediction[index].className == "Battery") {
document.getElementById("modal-content").innerHTML = `<img src="${dataURL}" width="100%"> <br><br><b>Category:</b> <span style="color: green;">${prediction[index].className}</span> <br><b>Confidence Level:</b> ${prediction[index].probability.toFixed(2)*100}%<br><br>It is important to remember that different types of batteries require different methods of disposal and recycling. For example, regular alkaline batteries are considered non-toxic and can be thrown away with regular household waste, while rechargeable batteries contain hazardous materials that require special disposal. To ensure proper disposal, take the batteries to your local recycling center or visit the website of the battery manufacturer for more information on how to properly recycle them.`;
} else if (prediction[index].className == "Unrecyclable") {
document.getElementById("modal-content").innerHTML = `<img src="${dataURL}" width="100%"> <br><br><b>Category:</b> <span style="color: red;">${prediction[index].className}</span> <br><b>Confidence Level:</b> ${prediction[index].probability.toFixed(2)*100}%<br><br>When it comes to items that cannot be recycled, the best thing to do is to try and find a way to reuse them. For example, if you have a wooden container, you can cut the top off and use it as a container for plants. Other items like old clothes can be donated or repurposed into something else, such as a new quilt or bag. If the item is still usable, consider donating it to a charity or local thrift store. If the item is no longer usable, it should be disposed of responsibly and taken to a local landfill or waste management facility.`;
}
}
function toggleModal() {
modal.classList.toggle("show-modal");
document.getElementById("myTopnav").classList.toggle("hide-nav");
}
function responsiveNav() {
var x = document.getElementById("myTopnav");
if (x.className === "topnav") {
x.className += " responsive";
} else {
x.className = "topnav";
}
}
</script>
</body>
</html>