先看效果:
再看代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>上传</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:opsz,wght,FILL,GRAD@20..48,100..700,0..1,-50..200">
<style>
html, body { height: 100%; }
body {
margin: 0;
padding: 0;
display: flex;
justify-content: center;
align-items: center;
color: lightblue;
}
label {
cursor: pointer;
}
.icon {
font-size: 96px;
font-variation-settings: 'OPSZ' 96, 'FILL' 0.0;
&.uploading {
animation: hithere 1s ease infinite;
}
&.done {
animation: bounce 0.6s ease forwards;
}
}
#f { display: none; }
@keyframes hithere {
30% { transform: scale(1.2); }
40%, 60% { transform: rotate(-20deg) scale(1.2); }
50% { transform: rotate(20deg) scale(1.2); }
70% { transform: rotate(0deg) scale(1.2); }
100% { transform: scale(1); }
}
@keyframes bounce {
0% { transform:translateY(0%); }
20% { transform:translateY(-15%); }
40% { transform:translateY(0%); }
50% { transform:translateY(-7%); }
70% { transform:translateY(0%); }
90% { transform:translateY(-3%); }
100% { transform:translateY(0); }
}
</style>
</head>
<body>
<label for="f">
<span class="material-symbols-outlined icon" id="icon">cloud_upload</span>
</label>
<input type="file" id="f">
</body>
<script>
const slice = (file, start, end) => {
const sliceExec = file.slice || file.mozSlice || file.webkitSlice;
return sliceExec(start, end);
};
const upload = (file) => {
const filename = file.name,
size = file.size,
numSlices = 40,
step = size / numSlices,
totalDemoUploadTime = 4000,
demoUploadTimeout = totalDemoUploadTime / numSlices;
document.getElementById('icon').innerHTML = 'cloud';
document.getElementById('icon').classList.add('uploading');
try {
let sendslice = (start, id = 0) => {
let end = start + step < size ? start + step : size;
let progress = Math.round(end / size * 100) / 100;
document.getElementById('icon').style.fontVariationSettings = `'OPSZ' 96, 'FILL' ${progress}`;
if (end < size) return setTimeout((end, id) => sendslice(end, id), demoUploadTimeout, end, id);
// done
document.getElementById('icon').innerHTML = 'cloud_done';
document.getElementById('icon').classList.remove('uploading');
document.getElementById('icon').classList.add('done');
// 重置
setTimeout(() => {
document.getElementById('icon').style.fontVariationSettings = `'OPSZ' 96, 'FILL' 0.0`;
document.getElementById('icon').innerHTML = 'cloud_upload';
document.getElementById('icon').classList.remove('done');
}, 2000);
};
sendslice(0);
} catch (err) {
document.getElementById('icon').innerHTML = 'cloud_off';
document.getElementById('icon').classList.remove('uploading');
console.warn(err);
}
}
document.getElementById("f").addEventListener("change", (e) => {
if (e.target.files.length == 0) return;
upload(e.target.files[0])
});
</script>
</html>
不要害怕,文件没有传上任何地方,这里只是模拟一下而已~