【CSS3动画】从简单动画到实现平抛运动和弹跳效果-贝塞尔曲线的利用

基础概念

如果你几乎不了解CCS3动画,下面会介绍一些基本概念,熟悉的朋友可以跳过基础概念部分。

假想想要一个正方形的盒子动起来,我们分别需要在html和css文件中进行设置。html比较简单,创建一个div随意class命名即可。接下来来看CSS,加入动画就需要给盒子设置几个关键帧,而CSS中的@keyframe可以把多个关键帧整合到一起,叫做一个动画序列。它需要一个自定义动画名称起始状态终止状态的信息。以下是模版。

@keyframe animationName {
    0% {
        ...;
    }
    100% {
        ...;
    }
}

需要注意的是,0%和100%就指的是起始位置和终止位置,分别代表两个关键帧,当然在其中也可以插入更多的关键帧,需要用百分比表示。如果单纯只需要起始位置和终止位置两个关键帧,也可以用from和to来分别代替0%和100%。其次,关键帧中间的内容可以自由定义

这里我想实现小盒子放大成两倍的动画。我选择使用transform: scale()去实现,这个也是CSS3新增的特性,不了解也没关系,可以直接设置起始宽高为50px,终止宽高为100px,也是同样的效果。

然后我们就可以把我们的动画序列赋予到html元素上去啦~

@keyframes zoom{
    0%{
        transform: scale(1);
    }
    100%{
        transform: scale(2);
    }
}
.box {
    margin: 200px 200px;
    width: 50px;
    height: 50px;
    background-color: green;
    animation-name: zoom; /*上面设置的动画名称*/
    animation-duration: 1s; /*动画总共时间*/
    animation-timing-function: linear; /*动画速度曲线*/
    animation-fill-mode: forwards; /*动画结束时的样式,这里为保留最后一帧的样式*/
    animation-delay: 2s; /*加载网页后显示动画的时间*/
    animation-iteration-count: infinite; /*动画迭代次数,这里是无限次*/
    animation-direction: alternate; /*动画正反向或来回,这里是来回*/
}

/*简写及顺序*/
/*animation: name duration timing-function delay iteration-count direction fill-mode play-state*/
/*这里没写play-state,有兴趣的同学可以看看文档*/

.box {
    width: 50px;
    height: 50px;
    background-color: green;
    animation: zoom 2s linear 2s forwards infinite alternate;
}

当然最后的结果会比自己的想要的结果更复杂,最终的样式是,小盒子在2秒后开始匀速放大,时长1秒,接着匀速缩小,无限循环,因为没有最后一帧,所以forwards放在这里没有意义,主要是为了演示常用的属性。好了,了解了用CSS3实现简单的动画,你可以继续往下看了。

效果演示

【CSS3动画】从简单动画到实现平抛运动和弹跳效果-贝塞尔曲线的利用_第1张图片

平抛运动理解

物体水平抛出,具有一定的初速度,垂直方向只受到重力影响。如果你熟悉平抛运动的性质,可以跳过这一部分。

【CSS3动画】从简单动画到实现平抛运动和弹跳效果-贝塞尔曲线的利用_第2张图片

 图片来源:sohu

但在实际动画中,如果出现这样的运动轨迹会十分的不自然,因为对不是那么重的物体来说,空气阻力常常无法忽略,为了尽量模拟物体在现实生活中的运动,我们假设水平方向上会有一个固定向左的阻力f,垂直方向上只有一个重力G,那么根据牛顿第二定律,水平方向上会做有初速度的匀减速运动,而垂直方向上做初速度为0的匀加速运动。

小球弹跳demo的思路与理解

这里我想做一个模拟小球弹跳的动画,假定小球是以平抛运动为初始状态。那么除了上述平抛运动的规则外,还需要考虑弹跳的部分。我们知道,小球在第一次落地的时候,会失去所有动能并转化为弹性势能,然后弹力给到小球一个向上的加速度N,当这个加速度大与重力加速度G时,小球重新弹起,但是因为各种能量损失,高度会比之前低。这里也可以去模拟弹性的动画,但是逻辑实现难度会上涨不少,所以我们暂时忽略弹性的动画,只考虑小球落地反弹一次再到达顶峰的情景。

因为在CSS动画中,我们无法为一个对象的多个属性在同一个动画序列中进行控制,于是我们的动画序列可以分为3步来实现。

  1. 落下和弹起时,水平向右匀减速运动(假设空气阻力一定)
  2. 落下时,垂直向下匀加速运动
  3. 弹起时,垂直向上匀减速运动

由于CSS动画无法像JS这种编程语言一样可以自己设置函数,我们只能靠animation自带的功能去实现动画曲线,也就是animation-timing-function属性。然而它自带的属性值默认是ease,并不能很好的实现我们想要的效果。这时候就要用到三次方贝塞尔曲线函数,cubic-bezier(),需要四个参数,用来精确定义曲线,广泛运用于计算机图形中。贝塞尔三次方公式如下:

图片来源:百度百科

当然,这里我们不用管如此复杂的公式,只需要知道,通过调节四个点的参数,可以绘制出精确的曲线就好。这里我推荐一个快速生成css贝塞尔函数结果的网站,非常方便:

cubic-bezier.com

代码思路

HTML:需要一个大盒子作为背景并确定底部地面。需要一个小球,从大盒子左上角出发。因为分解的运动方向有两个,所以要创建两个div,并进行嵌套,然后给最内部的div设置小球的基本属性。

CSS:

  1. 设置背景布,以及地面。
  2. 设置三个动画序列,确定关键帧所在的小球位置,一共三个点。
  3. 设置小球,利用CSS3新特性border-radius生成2D小球。
  4. 设置三个动画序列的具体属性,一个水平向右移动1秒,一个垂直下落0.65秒,一个上升0.35秒。(注意要保证下落上升的时间的和,与水平移动的时间相等,否则动画的轨迹会发生变化。)
  5. 调节贝塞尔曲线函数参数,让小球运动看起来更加自然,符合平抛运动规律和弹跳规律。
  6. 保证小球最后停止,给水平运动和上升运动添加forwards属性值
  7. 保证小球的上升动画必须衔接在下落动画之后,需要添加一个时间间隔,为下降的时间,0.65秒
*{
    margin: 0;
    padding: 0;
}
.canvas{
    margin: 100px auto;
    width: 1000px;
    height: 500px;
    border-bottom: 4px solid gray;
}
@keyframes Hori{
    0% {
        transform: translateX(0);
    }
    100% {
        transform: translateX(450px);
    }
}
@keyframes fallVert{
    0%{
        transform: translateY(0);
    }
    100% {
        transform: translateY(450px);
    }
}
@keyframes riseVert{
    0% {
        transform: translateY(450px);
    }
    100% {
        transform: translateY(250px);
    }
}
.obj{
    width: 50px;
    height: 50px;
    background-color: salmon;
    border-radius: 50%;
}
.horizontal{
    animation: Hori 1s forwards cubic-bezier(.21,.22,.69,.83);
}
.vertical{
    animation: fallVert 0.65s cubic-bezier(.55, .2, .82, .43),
    riseVert 0.35s forwards 0.65s cubic-bezier(.14,.57,.5,.91);
}

结果展示

【CSS3动画】从简单动画到实现平抛运动和弹跳效果-贝塞尔曲线的利用_第3张图片

总结

目前来看,用纯CSS实现完整的弹跳动画会有很冗长的代码量,因为我们无法设置速度,只能设置位置和时间,也无法自定义函数来实现我们想要的结果,但好在CSS3的贝塞尔曲线能够帮我们实现部分功能,做一个demo还是没问题的。

笔者是新手,有理解错误的地方请多多包涵,如果能指出,本人一定不吝赐教。

原创不易,请给作者一点鼓励吧~谢谢~~

你可能感兴趣的:(css3,动画,css,贝塞尔曲线)