WEB加载动画之小球弹跳

这是我参与11月更文挑战的第21天,活动详情查看:2021最后一次更文挑战

介绍

很早之前,大概15年刚入行的时候看到国外大佬在codepen上写了一个css弹跳动画这是我看到的第一个纯css实现的动画非常感兴趣所以一直记得,这不最近在做web加载动画的短篇题材,就做了一个这样的案例。所以,本期我们将用scss不借助js来完成一个小球弹跳的加载动画。

我们先看一下效果吧~

VID_20211120_204509.gif

不知道你看完有想法了么,还算比较简单吧,接下来,我们就讲解怎么实现它。

正文

基础界面

<div id="app">
    <div class="loading">
        <div class="balls">
            <div class="ball"></div>
            <div class="ball"></div>
            <div class="ball"></div>
        </div>
        <p class="txt"></p>
    </div>
</div>
复制代码
@import url("https://fonts.googleapis.com/css?family=Baloo+Bhaijaan&display=swap");

#app{
    width:100%;
    height:100vh;
    overflow: hidden;
    background:radial-gradient(#8f44ad,#6e3662);
    display: flex;
    align-items: center;
    justify-content: center;
}

.loading{
    width: 200px;
    height: 4em;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: space-between;
    position: relative;
    .txt{
        display: block;
        &::after{
            content: "Loading";
            font-family: "Baloo Bhaijaan", cursive;
            color: white;
            font-size: 1.8em;
            display: block;
            text-shadow: 0 0 10px white;
            letter-spacing: .1em;
        }
    }
}
复制代码

这个结构很简单,就是div#app将做一个圆形渐变铺满全屏,然后用弹性布局将div.loading居中到屏幕上,然后我们在其下面有个p.txt,其loading文字我们用他伪类的content做显示,另外我们用 text-shadow加了写发光的效果这样显得更醒目。当然你也可以直接在p.txt里面不用伪类,我这里之所以用伪类是因为我的一个早期版本对文字也做了打字动画,但是感觉动的地方太多显得过于混乱,而且也不是本期的重地就移除掉了这部分。

微信截图_20211120222830.png

小球绘制

.balls{
    width: 100%;
    height: 2em;
    box-sizing: border-box;
    padding: 0 1.2em;
    display: flex;
    align-items: center;
    justify-content: space-around;
    position: relative;
    .ball{
        position: relative;
        left: -.5em;
        &::before{
            content: "";
            display: block;
            width:1em;
            height:1em;
            border-radius: 50%;
            background-color: white;
            transform-origin: 50%;
            position: absolute;
            box-shadow: 0 0 10px white;
        }
        &::after{
            content: "";
            display: block;
            width:1em;
            height:4px;
            border-radius: 50%;
            background-color: rgba(0,0,0,.3);
            transform-origin: 50%;
            filter: blur(2px);
            position: absolute;
            top: 5px;
        }
    }
}
复制代码

这里我们之前在div.balls放了三个小球div.ball。每个小球会分为两部分:

  • 小球本体:用伪类before去完成,就是绘制一个圆形再用box-shadow做一个外发光的效果。
  • 小球阴影:用伪类after去完成,这里我们要做小球的影子为了有立体感要绘制一个黑色半透明的小椭圆,最后再模糊处理一下,显得更真实。

微信截图_20211120224934.png

弹跳动画

我们先来分析一下,小球弹跳会分为两个动画,即,小球从上往下落碰触地面发生的形变这个动画,和因小球下落的阴影放大缩小动画。因为这连个动画是想关联的,所以,我们先定义一个时间变量去控制他,然后再去一一完成他。

$t:0.5s;
.balls{            
	&::before{
    	// ...
    	animation: pellet $t alternate infinite linear;
    }
    &::after{
        // ...
        animation: shadow $t alternate infinite linear;
    }
}
@keyframes pellet{
    0%{
        border-radius: 50%;
        transform: translateY(-50px) scaleX(1);
    }
    60%{
        border-radius: 50%;
        transform: translateY(-20px) scaleX(1);
    }
    100%{
        border-radius: 50% 25%;
        height: .4em;
        transform: translateY(0px) scaleX(1.7);
    }
}

@keyframes shadow{
    0%{
        transform: scaleX(.2);
        opacity: .1 ;      
    }
    60%{
        transform: scaleX(1);
        opacity: .7;
    }
    100%{
        transform: scaleX(1.5);
    }
}
复制代码

这里其实也没啥好讲的,就是通过border-radius在动画中做出一个椭圆来模仿这个时刻触碰到了地面发生了弹性形变。我们唯一要注意的是这两个动画相应的位置大小一定要一一对应,毕竟是相关联的动画。

对了,还有一点,我们不想让这三个小球同时弹起,期望让他每一个都带点延迟,这样让其出现错位效果。

$n:3;
.balls{               
	@for $i from 1 through $n {
        &:nth-child(#{$i}) {
            &::before,
            &::after{
                animation-delay: -#{$i * .1s};
            }

        }
     }
}
复制代码

这里我们使用scss遍历他每一个小球,给他设置animation-delay动画延迟,记住一定要加"-"号,因为这样会让他直接预先执行,不用在一开始等待,不然这个动画都是失败的显得很奇怪。

VID_20211120_204509.gif

这样这个动画才算完成了,是不是非常的简单,在线演示

结语

本次并没有什么花花的技巧,主要是通过动画改变border-radius来模仿弹性形变,算是一种障眼法。当然,css障眼法本身也算是个奇思妙想吧,很多效果都能让用户眼前一亮。所以 ,一起发挥想象,创作出更有创意的动画吧~

おすすめ

転載: juejin.im/post/7032836348616802341