这篇文章发布于 2018年08月11日,星期六,01:03,归类于 CSS相关。 阅读 81318 次, 今日 9 次 25 条评论
by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=7934
本文可全文转载,但需得到原作者书面许可,同时保留原作者和出处,摘要引流则随意。
一、回顾之前的JS实现
差不多5年前,写了篇文章,名为“JavaScript与元素间的抛物线轨迹运动”(忽略前面几段的牢骚),然后写个JS方法,可以实现任意元素的抛物线运动效果,兼容到IE6浏览器,语法如下:
funParabola(element, target, options);
就可以实现element元素到target元素的抛物线运动效果,类似这样:
具体参数含义见原文,这不不再重复叙述。
实际上,纯CSS也是可以实现DOM元素的抛物线运动效果的。
应该是数年前,我看过一篇外文,就是水平和垂直运动使用不同的timing-function
可以得到曲线效果,记在了脑子里。然后,这周一例会上的时候,和小伙伴提到直接CSS3 animation
也能实现抛物线效果,感觉大家有些懵,知道可以这样,但完全脑补不出来,我意识到,可以写篇文章再重提此技术tips,相信还是有很多小伙伴不知道。
二、效果抢先体验
您可以狠狠地点击这里:CSS3实现的购物车抛物线运动demo
点击demo页面的“加入购物车”按钮,即可体验抛物线运动效果,如下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)
,如下截图:
.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新技术新应用层出不穷,大家纷纷表示学不动。自己也明显感到上年纪了,和公司小鲜肉们一起打篮球,发现真的不行了,爆发力没有了,以前都是一步过;弹跳力也没有了,以前公认篮板王,弹簧腿;体能也没有了,动作容易变形,不行了不行了,我要找找除了钓鱼意外其他适合老年人的运动了。
3. 一开始提到的外文
第一段开头提到一个运动曲线的老外的文章,我谷果了下,找到了:Moving along a curved path in CSS with layered animation
4. 感谢的话语
感谢同事们积极的反馈,让我意识到本文的价值所在,没有他们就没有这篇文章的诞生。
感谢正在阅读本文的你,忍受文章糟糕的版式和啰嗦的话语还能看到这里,我给你比个心。
最后,感谢你对本文的大力转发支持,谢谢!谢谢!
本文为原创文章,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。
本文地址:https://www.zhangxinxu.com/wordpress/?p=7934
(本篇完)
- 深入理解SVG feDisplacementMap滤镜及实际应用 (0.420)
- CSS3实现鸡蛋饼饼图loading等待转转转 (0.223)
- 小折腾:JavaScript与元素间的抛物线轨迹运动 (0.210)
- 贝塞尔曲线与CSS3动画、SVG和canvas的基情 (0.147)
- SVG任意图形path曲线路径的面积计算 (0.144)
- CSS3 animation属性中的steps功能符深入介绍 (0.100)
- 我使用CSS模拟个假的数字loading效果 (0.084)
- 深度掌握SVG路径path的贝塞尔曲线指令 (0.060)
- SVG+JS path等值变化实现CSS3兴叹的图形动画 (0.060)
- canvas实现iPhoneX炫彩壁纸屏保外加pixi.js流体动效 (0.060)
- 小tip:CSS3下条纹&方格斜纹背景的实现 (RANDOM - 0.003)
遥想当年看你的第一篇博客的时候,
那时候的我发量还很茂盛,
那时候的我一口气还能爬7层楼,
现在的我。。。
坐电梯都费劲
当初面试时候被问到过怎么在小程序实现抛物线小球运动…终于懂了,谢谢张老师❤️你
总能在张老师的博客中学习一些新东西!
感谢感谢,以前总觉得学习要一丝不苟的全身心投入学习,现在觉得那样的计划九成都会泡汤,或者 hello world 后就放弃了,还是闲暇时间学一点,再学一点,等到用使用场景时,至少能想起来,有这么现有的实现策略。
错别字
我要找找除了钓鱼意外其他适合老年人的运动了。
应为:
我要找找除了钓鱼以外其他适合老年人的运动了。
CSS3写得很详细。但是低版本IE不支持。各浏览器之间要是统一规则就好了!
8012年了,还在纠结低版本IE的公司,或者项目,从公司角度来说可能是要的,但对个人成长来说,帮助不大.
现在ff才是毒瘤
前段时间想用差不多的方式做一个椭圆轨迹,怎么做都感觉效果怪怪的,鑫鑫能给点建议么
正交分解还成……(高中党点进来之前第一想法就是这个
不过三次贝塞尔曲线能出抛物线ma2333
一样
按照上面的实例然后自己操作了一下,出现了一个问题, 生成抛物线时,这里会显示有两个运动, 向右运动,div里面的才会以抛物线的方式运动,感觉很奇怪
请问解决了吗?
给张老师点赞~
超级赞的,大大的学习了
张老师来跳舞
厉害厉害,学习了
【除了钓鱼意外其他适合老年人的运动】,可以买毛笔和墨水练字,刚开始可以练习写【Hello World】这10个字母。
这个在商城网站比较常用
应该是我们感谢你才对呢。
叔叔叔叔,我是看着你钓鱼长大的。。。。
受益匪浅!!
已经是旭叔了 哈哈
感谢旭叔分享自己的知识
旭叔
-=-=-==-
emmmm 扎心了 老铁