67

这回试试使用CSS实现抛物线运动效果

 5 years ago
source link: https://www.zhangxinxu.com/wordpress/2018/08/css-css3-抛物线动画/?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

这篇文章发布于 2018年08月11日,星期六,01:03,归类于CSS相关。 阅读 76 次, 今日 75 次

byzhangxinxu from https://www.zhangxinxu.com/wordpress/?p=7934

本文可全文转载,但需得到原作者书面许可,同时保留原作者和出处,摘要引流则随意。

一、回顾之前的JS实现

3An26rB.jpg!web

差不多5年前,写了篇文章,名为“ JavaScript与元素间的抛物线轨迹运动 ”(忽略前面几段的牢骚),然后写个JS方法,可以实现任意元素的抛物线运动效果,兼容到IE6浏览器,语法如下:

funParabola(element, target, options);

就可以实现element元素到target元素的抛物线运动效果,类似这样:

mAFrAjU.gif

具体参数含义见原文,这不不再重复叙述。

实际上,纯CSS也是可以实现DOM元素的抛物线运动效果的。

应该是数年前,我看过一篇外文,就是水平和垂直运动使用不同的 timing-function 可以得到曲线效果,记在了脑子里。然后,这周一例会上的时候,和小伙伴提到直接CSS3 animation 也能实现抛物线效果,感觉大家有些懵,知道可以这样,但完全脑补不出来,我意识到,可以写篇文章再重提此技术tips,相信还是有很多小伙伴不知道。

二、效果抢先体验

您可以狠狠地点击这里: CSS3实现的购物车抛物线运动demo

点击demo页面的“加入购物车”按钮,即可体验抛物线运动效果,如下GIF截屏:

MBfAvmq.gif

此抛物线效果的核心就是CSS代码实现的。原理如下:

抛物线运动元素使用至少内外两层标签,例如,本demo抛物线运动物体是CSS世界这本书的缩略图,我们可以外面一层 <div> ,里面是 <img> 图片:

<div class="fly-item"><img src="./book.jpg"></div>

然后内外两次标签一个负责水平方向的translate移动,一个负责垂直方向的translate移动,然后使用不同的缓动函数,也就是使用不同的 timing-function ,在CSS3 animation 动画效果中是 animation-timing-function 属性,在CSS3 transition 过渡效果中是 transition-timing-function 属性,本demo使用的是 transition 过渡,因此,CSS代码如下:

.fly-item {
    /* 水平移动,线性匀速 */
    transition-timing-function: linear;
}
.fly-item > img {
    /* 垂直移动,先慢后快 */
    transition-timing-function: cubic-bezier(.55,0,.85,.36);
}

然后同时执行 translate 移动,抛物线效果就出现了。

这其实也不难理解,比方说我们扔铅球,其运动轨迹实际上是水平推力和地球引力共同作用的结果,由于空气阻力可以忽略不计,因此,水平方向我们可以看成是匀速运动,而垂直方向由于重力加速度的存在,因此会越来越快。正好和上面CSS代码的缓动曲线是一致的,因此出现了抛物线运动。

还是有些懵?不急,下面的效果分解一定可以让你明白。

三、向量分解与抛物线运动

平常我们是水平垂直位移作用在一个元素上的,例如:

.example {
    transform: translate(100px, 100px);
}

此时,无论你是动画还是过渡效果,元素一定是直线运动,因为x, y方向瞬时速度总是一样的。例如默认 ease 缓动下的x, y分解效果图:

可以看到,虽然运动速度确实有快慢,但是由于x, y同一时间变化的距离是一样的,因此,最后的轨迹是一条直线。

但是,如果我们稍作调整,把水平运动改成 linear ,垂直运动改成 ease-in ,如下:

.ball-x { animation-timing-function: linear; }
.ball-y { animation-timing-function: ease-in; }

我们就可以看到运动轨迹变成弧形了:

是不是有点抛物线的感觉出来了?

ease-in 运动的缓动还不是很强烈,因此,抛物线效果不是很重,我们可以借助 cubic-bezier.com 工具调一个先慢后快很明显的贝塞尔曲线,例如 cubic-bezier(.55, 0, .85, .36) ,如下截图:

RZ3yQzZ.png!web

.ball-x { animation-timing-function: linear; }
.ball-y { animation-timing-function: cubic-bezier(.55, 0, .85, .36); }

此时,分解和组合x,y运动后的实时效果如下:

上面的运动就是本文抛物线demo使用的运动效果,所以抛物线效果的实现的关键就是x,y方向运动分解,同时分别设置不同的缓动。

我们还可以设置 cubic-bezier 值大于1,以得到更强烈的带有弹性效果的运动轨迹,例如:

.ball-x { animation-timing-function: cubic-bezier(0.3, 0.27, 0.07, 1.64); }
.ball-y { animation-timing-function: cubic-bezier(0.02, 0.01, 0.21, 1); }

效果如下,球球直接飞出了田字形区域,还拐了一个弯:

四、没有防备的结语

1. demo页面还有话说

抛物线运动可以纯CSS实现,IE10+浏览器都可以实现,移动端页面可以自如使用。但是,实际开发还是需要JS配合。

demo页面中可以看到一定量的JS代码,这些JS与抛物线效果的运行轨迹并无关系,只是用来确定抛物线运动的起点和终点。

2. 第2个5年

时光荏苒,白驹过隙,五年时光弹指间一飞而过,五年可以改变很多东西,前端圈也不例外,越来越娱乐圈化,PWA,轻应用,小程序,React/Vue.js新技术新应用层出不穷,大家纷纷表示学不动。自己也明显感到上年纪了,和公司小鲜肉们一起打篮球,发现真的不行了,爆发力没有了,以前都是一步过;弹跳力也没有了,以前公认篮板王,弹簧腿;体能也没有了,动作容易变形,不行了不行了,我要找找除了钓鱼意外其他适合老年人的运动了。 zYFzMra.png!web

3. 一开始提到的外文

第一段开头提到一个运动曲线的老外的文章,我谷果了下,找到了: Moving along a curved path in CSS with layered animation

4. 感谢的话语

感谢同事们积极的反馈,让我意识到本文的价值所在,没有他们就没有这篇文章的诞生。

感谢正在阅读本文的你,忍受文章糟糕的版式和啰嗦的话语还能看到这里,我给你比个心。 BnyAV3B.png!web

最后,感谢你对本文的大力转发支持,谢谢!谢谢!

fIFNBvU.png!web

本文为原创文章,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。

本文地址: https://www.zhangxinxu.com/wordpress/?p=7934

(本篇完)


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK