-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathoptim.html
112 lines (100 loc) · 2.58 KB
/
optim.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
<input type="file" id="input" multiple accept="image/jpeg,image/png">
<output id="output">
Drop/select some jpegs/pngs you want to optimise
</output>
<style>
svg,
img {
width: 200px;
}
input[type=file] {
display: block;
}
input,
svg,
img,
textarea,
output {
margin: 1em;
}
body {
font-family: Arial;
}
td {
border: 1px solid rgba(0, 0, 0, .1);
padding: 4px 8px;
}
@keyframes loader {
0% {
content: "";
}
25% {
content: ".";
}
50% {
content: "..";
}
75% {
content: "...";
}
100% {
content: "...";
}
}
.loader::after {
content: "";
animation: loader 2s linear infinite;
display: inline-block;
}
</style>
<script>
document.body.ondragover = e => {
if (e.dataTransfer.types.includes('Files')) {
e.preventDefault();
document.body.style.outline = 'lightgreen auto 5px';
}
}
document.body.ondragend = document.body.ondragleave = e => {
document.body.style.outline = '';
}
document.body.ondrop = e => {
e.preventDefault();
processFiles(Array.from(e.dataTransfer.files).filter(o=>/^image\/(jpeg|png)/.test(o.type)));
document.body.style.outline = '';
}
input.onchange = e => {
processFiles(Array.from(input.files).filter(o=>/^image\/(jpeg|png)/.test(o.type)));
}
function processFiles(files) {
output.innerHTML = '';
const table = output.appendChild(document.createElement('table'));
files.forEach(async(file, i) => {
const row = table.insertRow();
const ori = row.insertCell(); // original file
ori.textContent = `${file.name}: ${Math.round(file.size/1000)}KB`;
const xx = row.insertCell(); // processed by server
xx.innerHTML = `<span class="loader"></span>`;
const newFile = await optimize(file);
//console.log(file, blob);
xx.innerHTML = `<a href="${URL.createObjectURL(newFile)}" download="${newFile.name}">optimized in browser</a>: ${Math.round(newFile.size/1000)}KB`;
});
}
const workerCode = `importScripts('https://unpkg.com/mozjpeg-js', 'https://cdn.rawgit.com/psych0der/pngquantjs/master/demo/js/pngquant.min.js');
onmessage = function(event) {
var {args, type, data} = event.data,
optimize = type=='image/png' ? pngquant : mozjpeg.encode;
var result = optimize(data, args, console.log);
postMessage(result);
};`;
const workerUrl = URL.createObjectURL(new Blob([workerCode], {type: 'application/javascript'}));
function optimize(file) {
const worker = new Worker(workerUrl);
return new Promise(resolve => {
worker.onmessage = event => {
resolve(new File([event.data.data], file.name, {type: file.type}));
worker.terminate();
};
file.arrayBuffer().then(buf => worker.postMessage({data: new Uint8Array(buf), type: file.type}));
})
}
</script>