Front-end special effects: luminous animation button: upload button
H5+CSS+JS
skeleton+skin+function
Show results
Source code:
H5 part:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<link rel="stylesheet" href="style.css" />
<title>上传按钮-动画</title>
</head>
<body>
<main>
<div class="upload-button">
<svg class="arrow" width="40" height="40" viewBox="0 0 40 40">
<!-- 进度 -->
<circle
cx="50%"
cy="50%"
r="19"
fill="none"
stroke="#ffffff"
stroke-width="2"
></circle>
<!-- 箭头 -->
<!-- 左边的线 -->
<!-- points="6,20 20,6 34,20" -->
<!-- points="8,20 18,30 30, 12" -->
<polyline
points="6,20 20,6 34,20"
stroke="#ffffff"
fill="none"
stroke-width="2"
class="arrow-top"
></polyline>
<polyline
points="8,20 18,30 30,12"
stroke="#ffffff"
fill="none"
stroke-width="2"
class="checkmark"
></polyline>
<!-- 中间的线 -->
<line
x1="50%"
y1="7"
x2="50%"
y2="34"
stroke="#ffffff"
stroke-width="2"
class="middle-line"
></line>
</svg>
<div class="progress-bar"></div>
</div>
</main>
<script src="index.js"></script>
</body>
</html>
CSS part:
html,
body {
margin: 0;
}
* {
box-sizing: border-box;
}
body {
background-color: #2f3542;
}
main {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
}
.cube {
width: 250px;
height: 250px;
transform-style: preserve-3d;
transform-origin: 125px 125px 0;
animation: rotate-cube 10s ease-in-out infinite;
}
.cube > div {
width: 250px;
height: 250px;
background-size: cover;
background-position: center center;
opacity: 0.8;
position: absolute;
box-shadow: inset 0 0 4px 2px rgba(106, 106, 106, 0.4);
}
/* 前 */
.cube .img1 {
background-image: url("https://images.pexels.com/photos/274131/pexels-photo-274131.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940");
transform: rotateY(0deg) translateZ(125px);
}
/* 右 */
.cube .img2 {
background-image: url("https://images.pexels.com/photos/1480690/pexels-photo-1480690.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940");
transform: rotateY(90deg) translateZ(125px);
}
/* 左 */
.cube .img3 {
background-image: url("https://images.pexels.com/photos/36487/above-adventure-aerial-air.jpg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940");
transform: rotateY(-90deg) translateZ(125px);
}
/* 下 */
.cube .img4 {
background-image: url("https://images.pexels.com/photos/338713/pexels-photo-338713.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940");
transform: rotateX(90deg) translateZ(125px);
}
/* 上 */
.cube .img5 {
background-image: url("https://images.pexels.com/photos/325044/pexels-photo-325044.jpeg?cs=srgb&dl=close-up-of-fish-over-black-background-325044.jpg&fm=jpg");
transform: rotateX(-90deg) translateZ(125px);
}
/* 后 */
.cube .img6 {
background-image: url("https://images.pexels.com/photos/404280/pexels-photo-404280.jpeg?auto=compress&cs=tinysrgb&dpr=2&h=650&w=940");
transform: rotateY(180deg) translateZ(125px);
}
@keyframes rotate-cube {
0% {
transform: rotateX(0deg) rotateY(0deg);
}
20% {
/* 右边图片 */
transform: rotateY(-90deg);
}
40% {
/* 上 */
transform: rotateX(-90deg);
}
60% {
/* 左 */
transform: rotateY(90deg);
}
80% {
/* 下 */
transform: rotateX(90deg);
}
100% {
transform: rotateX(0deg) rotateY(0deg);
}
}
js part
// 获取上传按钮和进度条
var uploadButton = document.querySelector(".upload-button");
var progressBar = document.querySelector(".upload-button .progress-bar");
// 进度条完成时的宽度
let width = uploadButton.getBoundingClientRect().width;
// 假定上传时间为5s
let uploadTime = 5000;
uploadButton.addEventListener("click", () => {
// 先移除之前的完成样式
uploadButton.classList.remove("uploaded");
//设置正在上传.uploading样式
uploadButton.classList.add("uploading");
//假设5秒后上传完成
setTimeout(() => {
uploadButton.classList.replace("uploading", "uploaded");
}, uploadTime);
let start = null;
function grow(timestamp) {
// 动画开始时的时间戳
if (!start) start = timestamp;
// 距离开始时已经过的时间戳
let progress = timestamp - start;
//按比例增加进度条宽度
progressBar.style.width = `${Math.min(
width * (progress / uploadTime),
width
)}px`;
// 如果上传未完成,继续执行此函数,递归循环
if (progress < uploadTime) {
window.requestAnimationFrame(grow);
}
}
// 开始执行grow函数
window.requestAnimationFrame(grow);
});