如何制作 CSS 旋转加载动画?
How to create a CSS spinning loading animation?
我想创建一个 css(或 JS)加载动画,如下图所示:
应该有一个包含 class 的容器矩形。然后应该将一些 css 应用于该矩形,以便有一些覆盖。首先它是全黑的,透明度为 50%。然后随着时间的推移,黑色会随着顺时针旋转而减少,直到不再有黑色为止。如果我给它100的值,它应该是全黑的,如果我给它0,它应该没有黑色,完全显示底层图像。
有人知道任何教程或如何创建它吗?
无疑是困难的,但有可能。经过大约一个小时的磨合,我想出了很多 div 和一些工作代码:
const inner = document.getElementById('inner');
const black = document.getElementById('black');
const cover = document.getElementById('cover');
const overlay = document.getElementById('overlay');
const block = document.getElementById('block');
inner.addEventListener('animationend', e => {
inner.style.display = 'none';
block.style.display = 'block';
});
cover.addEventListener('animationend', e => {
alert('done!');
});
#wrapper {
height: 100px;
width: 100px;
border: 5px solid black;
position: relative;
overflow: hidden;
}
#wrapper > div {
position: absolute;
height: 300%;
width: 300%;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
#cover {
background-color: white;
animation: spin 5s linear 5s forwards;
}
#overlay {
background-color: black;
width: 50%;
height: 100%;
position: absolute;
left: 0;
top: 0;
}
#inner {
animation: spin 5s linear forwards;
}
#black {
background-color: black;
width: 50%;
height: 100%;
position: absolute;
right: 0;
top: 0;
}
@keyframes spin {
from {
transform: translate(-50%, -50%) rotate(0);
}
to {
transform: translate(-50%, -50%) rotate(180deg);
}
}
#block {
display: none;
background-color: white;
height: 100%!important;
width: 50%!important;
transform: translate(0, 0)!important;
position: absolute;
top: 0!important;
right: 0!important;
z-index: 10
}
/*Just for the demo*/
body, html {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
}
<div id="wrapper">
<div id="cover">
<div id="overlay"></div>
</div>
<div id="inner">
<div id="black"></div>
</div>
<div id="block"></div>
</div>
中间的小方块代表#wrapper
。它周围较大的正方形是它的 child #inner
。在 #inner
的右侧(带条纹)是 #black
,它占据了 parent 的一半。 #inner
旋转 180 度,消失,然后 #cover
在另一侧基本上做同样的事情。 #block
让 #cover
的黑色部分不显示在另一边。 *哇*,真有趣!
我用 canvas 弄明白了。
var canvas = document.getElementById('loading_animation');
var ctx = canvas.getContext('2d');
ctx.fillStyle = '#00000088';
var final = [];
var list1 = [
[Math.floor(canvas.width / 2), 0],
[Math.floor(canvas.width / 2), Math.floor(canvas.height / 2)]
];
var list2 = [
[canvas.width - 1, 0],
[canvas.width - 1, canvas.height - 1],
[0, canvas.height - 1],
[0, 0]
];
var last = [Math.floor(canvas.width / 2), 0];
for (var x = Math.floor(canvas.width / 2); x < canvas.width; x += 1) {
var path = list1.concat([[x, 0]]).concat(list2).concat([last]);
final.push(path);
}
list2.shift();
for (var y = 1; y < canvas.height; y += 1) {
var path = list1.concat([[canvas.width - 1, y]]).concat(list2).concat([last]);
final.push(path);
}
list2.shift();
for (var x = canvas.width - 2; x >= 0; x -= 1) {
var path = list1.concat([[x, canvas.height - 1]]).concat(list2).concat([last]);
final.push(path);
}
list2.shift();
for (var y = canvas.height - 2; y >= 0; y -= 1) {
var path = list1.concat([[0, y]]).concat(list2).concat([last]);
final.push(path);
}
list2.shift();
for (var x = 1; x < Math.floor(canvas.width / 2); x += 1) {
var path = list1.concat([[x, 0]]).concat(list2).concat([last]);
final.push(path);
}
function RenderAnimation() {
var path = final.shift();
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.beginPath();
ctx.moveTo(path[0][0], path[0][1]);
for (let i = 1; i < path.length; i++) {
ctx.lineTo(path[i][0], path[i][1]);
}
ctx.closePath();
ctx.fill();
if (final.length > 0) {
window.requestAnimationFrame(RenderAnimation);
} else {
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
}
RenderAnimation();
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
<style>
canvas {
background-image: url('https://media.wired.com/photos/5d09594a62bcb0c9752779d9/125:94/w_1994,h_1500,c_limit/Transpo_G70_TA-518126.jpg');
background-size: 100% 100%;
background-repeat: no-repeat;
}
</style>
</head>
<body>
<canvas id="loading_animation" width="300px" height="200px"></canvas>
</body>
</html>
我想创建一个 css(或 JS)加载动画,如下图所示:
应该有一个包含 class 的容器矩形。然后应该将一些 css 应用于该矩形,以便有一些覆盖。首先它是全黑的,透明度为 50%。然后随着时间的推移,黑色会随着顺时针旋转而减少,直到不再有黑色为止。如果我给它100的值,它应该是全黑的,如果我给它0,它应该没有黑色,完全显示底层图像。
有人知道任何教程或如何创建它吗?
无疑是困难的,但有可能。经过大约一个小时的磨合,我想出了很多 div 和一些工作代码:
const inner = document.getElementById('inner');
const black = document.getElementById('black');
const cover = document.getElementById('cover');
const overlay = document.getElementById('overlay');
const block = document.getElementById('block');
inner.addEventListener('animationend', e => {
inner.style.display = 'none';
block.style.display = 'block';
});
cover.addEventListener('animationend', e => {
alert('done!');
});
#wrapper {
height: 100px;
width: 100px;
border: 5px solid black;
position: relative;
overflow: hidden;
}
#wrapper > div {
position: absolute;
height: 300%;
width: 300%;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
#cover {
background-color: white;
animation: spin 5s linear 5s forwards;
}
#overlay {
background-color: black;
width: 50%;
height: 100%;
position: absolute;
left: 0;
top: 0;
}
#inner {
animation: spin 5s linear forwards;
}
#black {
background-color: black;
width: 50%;
height: 100%;
position: absolute;
right: 0;
top: 0;
}
@keyframes spin {
from {
transform: translate(-50%, -50%) rotate(0);
}
to {
transform: translate(-50%, -50%) rotate(180deg);
}
}
#block {
display: none;
background-color: white;
height: 100%!important;
width: 50%!important;
transform: translate(0, 0)!important;
position: absolute;
top: 0!important;
right: 0!important;
z-index: 10
}
/*Just for the demo*/
body, html {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
}
<div id="wrapper">
<div id="cover">
<div id="overlay"></div>
</div>
<div id="inner">
<div id="black"></div>
</div>
<div id="block"></div>
</div>
中间的小方块代表#wrapper
。它周围较大的正方形是它的 child #inner
。在 #inner
的右侧(带条纹)是 #black
,它占据了 parent 的一半。 #inner
旋转 180 度,消失,然后 #cover
在另一侧基本上做同样的事情。 #block
让 #cover
的黑色部分不显示在另一边。 *哇*,真有趣!
我用 canvas 弄明白了。
var canvas = document.getElementById('loading_animation');
var ctx = canvas.getContext('2d');
ctx.fillStyle = '#00000088';
var final = [];
var list1 = [
[Math.floor(canvas.width / 2), 0],
[Math.floor(canvas.width / 2), Math.floor(canvas.height / 2)]
];
var list2 = [
[canvas.width - 1, 0],
[canvas.width - 1, canvas.height - 1],
[0, canvas.height - 1],
[0, 0]
];
var last = [Math.floor(canvas.width / 2), 0];
for (var x = Math.floor(canvas.width / 2); x < canvas.width; x += 1) {
var path = list1.concat([[x, 0]]).concat(list2).concat([last]);
final.push(path);
}
list2.shift();
for (var y = 1; y < canvas.height; y += 1) {
var path = list1.concat([[canvas.width - 1, y]]).concat(list2).concat([last]);
final.push(path);
}
list2.shift();
for (var x = canvas.width - 2; x >= 0; x -= 1) {
var path = list1.concat([[x, canvas.height - 1]]).concat(list2).concat([last]);
final.push(path);
}
list2.shift();
for (var y = canvas.height - 2; y >= 0; y -= 1) {
var path = list1.concat([[0, y]]).concat(list2).concat([last]);
final.push(path);
}
list2.shift();
for (var x = 1; x < Math.floor(canvas.width / 2); x += 1) {
var path = list1.concat([[x, 0]]).concat(list2).concat([last]);
final.push(path);
}
function RenderAnimation() {
var path = final.shift();
ctx.clearRect(0, 0, canvas.width, canvas.height);
ctx.beginPath();
ctx.moveTo(path[0][0], path[0][1]);
for (let i = 1; i < path.length; i++) {
ctx.lineTo(path[i][0], path[i][1]);
}
ctx.closePath();
ctx.fill();
if (final.length > 0) {
window.requestAnimationFrame(RenderAnimation);
} else {
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
}
RenderAnimation();
<!DOCTYPE html>
<html>
<head>
<title>Title of the document</title>
<style>
canvas {
background-image: url('https://media.wired.com/photos/5d09594a62bcb0c9752779d9/125:94/w_1994,h_1500,c_limit/Transpo_G70_TA-518126.jpg');
background-size: 100% 100%;
background-repeat: no-repeat;
}
</style>
</head>
<body>
<canvas id="loading_animation" width="300px" height="200px"></canvas>
</body>
</html>