仅作学习记录用,先上图,实现如图所示的效果
主要用到了SVG和C3的帧动画
此处用到的svg形状其实就是下边这个东东
在下边water这个盒子里面use两次这个svg矢量图,给其设置不同的填充色,并且给它加上动画,给其中一个加上translate属性让它向右无限做位移动画,另一个向左,那么当两个矢量图做相对运动的时候,就会产生视觉上的欺骗,让人感觉就像水在动一样
此处是单独一个向右移动(下边蓝色色块是父容器的背景色)
当它俩做相对移动的时候,就会产生右图这种效果(通过C3动画实现) 此处两个同时移动
然后此处数字以及水动画的动态变化就可以通过定时器+递归来实现
<script>
window.onload = () => {
let water = document.getElementById('water')
let percentNum = document.querySelector('.percent .percentNum')
let count = 0
let c = 100
function egg() {
setTimeout(function () {
if (count < 100) {
count++
c--
water.style.transform = `translate(0,${c}%)`//修改盒子的y轴位移
percentNum.innerHTML = count
egg()
}
}, 50)
}
egg()
}
</script>
或者使用requestAnimationFrame也可以,都是一个道理
<script>
window.onload = () => {
let water = document.getElementById('water')
let percentNum = document.querySelector('.percent .percentNum')
let count = 0
let c = 100
window.requestAnimationFrame(egg)
function egg() {
if (count < 100) {
count++
c--
water.style.transform = `translate(0,${c}%)`
percentNum.innerHTML = count
window.requestAnimationFrame(egg)
}
}
}
</script>
到这儿就可以实现一个文章开头一样的数据动态变化的水球加载动画,下边贴出完整代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
*,
*:before,
*:after {
box-sizing: border-box;
outline: none;
}
body {
background: #020438;
font: 14px/1 'Open Sans', helvetica, sans-serif;
}
.box {
height: 280px;
width: 280px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: #020438;
border-radius: 100%;
overflow: hidden;
}
.box .percent {
position: absolute;
left: 0;
top: 0;
z-index: 3;
width: 100%;
height: 100%;
display: -webkit-box;
display: -ms-flexbox;
display: flex;
display: -webkit-flex;
align-items: center;
justify-content: center;
color: #fff;
font-size: 64px;
}
.box .water {
position: absolute;
left: 0;
top: 0;
z-index: 2;
width: 100%;
height: 100%;
/* transform: translate(0, 100%); */
background: #4d6de3;
}
.box .water_wave {
width: 200%;
position: absolute;
bottom: 100%;
}
.box .water_wave_back {
right: 0;
fill: #c7eeff;
animation: moveWave 1.7s infinite linear;
}
.box .water_wave_front {
left: 0;
fill: #4d6de3;
margin-bottom: -1px;
animation: moveWave1 0.9s infinite linear;
}
@keyframes moveWave {
0% {
transform: 0;
}
100% {
transform: translateX(50%);
}
}
@keyframes moveWave1 {
0% {
transform: 0;
}
100% {
transform: translateX(-50%);
}
}
</style>
</head>
<body>
<div class="water-ball">
<svg
version="1.1"
xmlns="https://www.w3.org/2000/svg"
xmlns:xlink="https://www.w3.org/1999/xlink"
x="0px"
y="0px"
style="display: none"
>
<symbol id="wave">
<path
d="M420,20c21.5-0.4,38.8-2.5,51.1-4.5c13.4-2.2,26.5-5.2,27.3-5.4C514,6.5,518,4.7,528.5,2.7c7.1-1.3,17.9-2.8,31.5-2.7c0,0,0,0,0,0v20H420z"
></path>
<path
d="M420,20c-21.5-0.4-38.8-2.5-51.1-4.5c-13.4-2.2-26.5-5.2-27.3-5.4C326,6.5,322,4.7,311.5,2.7C304.3,1.4,293.6-0.1,280,0c0,0,0,0,0,0v20H420z"
></path>
<path
d="M140,20c21.5-0.4,38.8-2.5,51.1-4.5c13.4-2.2,26.5-5.2,27.3-5.4C234,6.5,238,4.7,248.5,2.7c7.1-1.3,17.9-2.8,31.5-2.7c0,0,0,0,0,0v20H140z"
></path>
<path
d="M140,20c-21.5-0.4-38.8-2.5-51.1-4.5c-13.4-2.2-26.5-5.2-27.3-5.4C46,6.5,42,4.7,31.5,2.7C24.3,1.4,13.6-0.1,0,0c0,0,0,0,0,0l0,20H140z"
></path>
</symbol>
</svg>
<div class="box">
<div class="percent">
<div class="percentNum" id="count">0</div>
<div class="percentB">%</div>
</div>
<div id="water" class="water">
<svg viewBox="0 0 560 20" class="water_wave water_wave_back">
<use xlink:href="#wave"></use>
</svg>
<svg viewBox="0 0 560 20" class="water_wave water_wave_front">
<use xlink:href="#wave"></use>
</svg>
</div>
</div>
</div>
<script>
window.onload = () => {
let water = document.getElementById('water')
let percentNum = document.querySelector('.percent .percentNum')
let count = 0
let c = 100
function egg() {
setTimeout(function () {
if (count < 100) {
count++
c--
water.style.transform = `translate(0,${c}%)`
percentNum.innerHTML = count
egg()
}
}, 50)
}
egg()
}
</script>
</body>
</html>