1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 【CSS3动画】从简单动画到实现平抛运动和弹跳效果-贝塞尔曲线的利用

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

时间:2021-07-21 01:22:32

相关推荐

【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实现简单的动画,你可以继续往下看了。

效果演示

平抛运动理解

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

图片来源:sohu

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

小球弹跳demo的思路与理解

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

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

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

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

图片来源:百度百科

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

cubic-

代码思路

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

<div class="canvas"><div class="horizontal"><div class="obj vertical"></div></div></div>

CSS:

设置背景布,以及地面。设置三个动画序列,确定关键帧所在的小球位置,一共三个点。设置小球,利用CSS3新特性border-radius生成2D小球。设置三个动画序列的具体属性,一个水平向右移动1秒,一个垂直下落0.65秒,一个上升0.35秒。(注意要保证下落上升的时间的和,与水平移动的时间相等,否则动画的轨迹会发生变化。)调节贝塞尔曲线函数参数,让小球运动看起来更加自然,符合平抛运动规律和弹跳规律。保证小球最后停止,给水平运动和上升运动添加forwards属性值保证小球的上升动画必须衔接在下落动画之后,需要添加一个时间间隔,为下降的时间,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);}

结果展示

总结

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

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

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

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。