🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
## 动画 ### 谈用户界面设计 用户界面设计是要围绕着好用的,围绕着用户体验的,它可以有固定的规范,又可以没有既定的形式,是灵活的,多变的,可以墨守成规,也可以天马行空,任何时候不能太过死板,死板是阻碍创新最大的障碍力量,不论如何,不论何时,只要是好用的、对用户友好的设计就是好的设计。 2017-10-2 13:53:25 * * * * * [干货教程!12个常用动画原理(官方全系列)](http://www.365yg.com/item/6466630715202077197/) * * * * * ### 动画浅析 赖来看一个 模态窗的(位置)状态案列: 1. 进入前 `……进入过程` 2. 已进入 `……离开过程` 3. 已离开 **这三个状态都是稳定的状态**,只有中间的两个过程是动态的,也就是我们所看到的动画效果。 动画总是从一个状态(形态)到另一个状态(形态),也就是从一个点到另一点,这几个点就是骨架,就是顶点,是稳定的,每一个点都是一个要着重表现的状态。中间变化轨迹的就是具体的过度动画了。 动画的本质也就是过度,从一帧过度到另一帧,只不过由于人眼的视觉暂留原理,是我们感觉这种帧的切换很流畅,也就是我们所说的动画。 理解这些,理解顶点,理解状态变化,我们就明白了为什么要在程序中设计动画交互了,因为状态的变化传达出了UI的状态,也就是那些顶点。而中间的动画也是有重要意义的,因为人是情感动物,是带着情感去理解事物的,所以动画的过程细腻地表现了程序的交互状态,帮助使用者更好的理解程序所表达的意图,使其有更好的交互体验。 * * * * * ### 动画效果 屏幕视口就是一个舞台。 入场:缩小、淡入。 出场:放大、淡出。 锤子科技的设计还是挺有品味的。 * * * * * ### 动画思考 **元素动画体现有三点:** 1. 位置改变 2. 大小改变(宽高、内外边距、边框) 3. 外观改变(背景颜色、透明度、旋转、变形、阴影等效果) **动画根据影响分类,有两种:** 1. 会影响DOM布局的变化的(布局有害) 2. 不会影响DOM布局的变化的(布局无害) 一般,`位置改变`、`大小改变`也有“会影响DOM布局的变化”和“不会影响DOM布局的变化”的两种方式。 想要不改变DOM布局(元素在文档流文档流内的布局,或影响其他元素的布局),就不能使用常规的手段去改变元素,比如使用css3放大来代替传统宽高的改变,使用css3偏移来代替传统的使用边距的方式来改变元素位置。 不过有的动画也可能使用了 会影响DOM布局的变化 的方式,不过这样性能低一些,动画时会改变其他元素的位置,页面布局,会发生重绘,但是有些时候这样动画场景会更生动,具体看情况。只要知道DOM布局在动画中有这两种方式表现即可。 **布局有害的例子:** ``` display width、margin、padding、border ``` **布局无害的例子:** ``` visibility、opacity transform、outline ``` * * * * * ### 动画的本质 动画:会动的画面,即切换的帧。 动画的本质就是帧的切换,而实际上我们所说的动画就是那些比较自然流畅的帧切换。所以动画的本质就是帧的过度了 —— 动画的本质就是过度。动画效果就是过渡效果。 过度的平稳,细腻,那么这个动画就更流畅,真实。 * * * * * ### 动画实现 [layer弹层组件移动版](http://layer.layui.com/mobile/) 底部对话框: `layui-m-anim-up` ```css /* el class: layui-m-layerchild layui-m-layer-footer layui-m-anim-up */ body .layui-m-layer .layui-m-layer-footer { position: fixed; width: 95%; max-width: 100%; margin: 0 auto; left: 0; right: 0; bottom: 10px; background: 0 0; } @-webkit-keyframes layui-m-anim-up { 0% { opacity: 0; -webkit-transform: translateY(800px); transform: translateY(800px) } 100% { opacity: 1; -webkit-transform: translateY(0); transform: translateY(0) } } .layui-m-anim-up { -webkit-animation-name: layui-m-anim-up; animation-name: layui-m-anim-up } ``` 询问框: `layui-m-anim-scale` ```css /* el class: layui-m-layerchild layui-m-anim-scale */ .layui-m-anim-scale { animation-name: layui-m-anim-scale; -webkit-animation-name: layui-m-anim-scale; } @keyframes layui-m-anim-scale { 0% { opacity: 0; -webkit-transform: scale(.5); transform: scale(.5) } 100% { opacity: 1; -webkit-transform: scale(1); transform: scale(1) } } .layui-m-anim-scale { animation-name: layui-m-anim-scale; -webkit-animation-name: layui-m-anim-scale; } ``` * * * * * [WeUI](https://weui.io/#actionsheet):`weui-actionsheet weui-animate-slide-up` 不同设备,动画效果与样式不同(ios:`up/down`、android:`in/out`)。 ~~~html <script type="text/javascript"> // ios $(function(){ var $iosActionsheet = $('#iosActionsheet'); var $iosMask = $('#iosMask'); function hideActionSheet() { $iosActionsheet.removeClass('weui-actionsheet_toggle'); $iosMask.fadeOut(200); } $iosMask.on('click', hideActionSheet); $('#iosActionsheetCancel').on('click', hideActionSheet); $("#showIOSActionSheet").on("click", function(){ $iosActionsheet.addClass('weui-actionsheet_toggle'); $iosMask.fadeIn(200); }); }); // android $(function(){ var $androidActionSheet = $('#androidActionsheet'); var $androidMask = $androidActionSheet.find('.weui-mask'); $("#showAndroidActionSheet").on('click', function(){ $androidActionSheet.fadeIn(200); $androidMask.on('click',function () { $androidActionSheet.fadeOut(200); }); }); }); </script> ~~~ 出场时直接添加出场类。 也是在出场动画结束时移除节点的。 ```javascript $actionSheet.addClass(isAndroid ? 'weui-animate-fade-out' : 'weui-animate-slide-down'); $actionSheetMask.addClass('weui-animate-fade-out').on('animationend webkitAnimationEnd', function () { $actionSheetWrap.remove(); _sington = false; callback && callback(); }); ``` ```css @keyframes a { 0% { -webkit-transform: translate3d(0,100%,0); transform: translate3d(0,100%,0) } to { -webkit-transform: translateZ(0); transform: translateZ(0) } } .weui-animate-slide-up { -webkit-animation: a ease .3s forwards; animation: a ease .3s forwards } @keyframes b { 0% { -webkit-transform: translateZ(0); transform: translateZ(0) } to { -webkit-transform: translate3d(0,100%,0); transform: translate3d(0,100%,0) } } .weui-animate-slide-down { -webkit-animation: b ease .3s forwards; animation: b ease .3s forwards } @keyframes c { 0% { opacity: 0 } to { opacity: 1 } } .weui-animate-fade-in { -webkit-animation: c ease .3s forwards; animation: c ease .3s forwards } @keyframes d { 0% { opacity: 1 } to { opacity: 0 } } .weui-animate-fade-out { -webkit-animation: d ease .3s forwards; animation: d ease .3s forwards } ``` * * * * * 有弹性感觉的动画: ```css @-webkit-keyframes showSweetAlert{0%{-webkit-transform:scale(.7);transform:scale(.7)} 45%{-webkit-transform:scale(1.05);transform:scale(1.05)} 80%{-webkit-transform:scale(.95);transform:scale(.95)} to{-webkit-transform:scale(1);transform:scale(1)} } @keyframes showSweetAlert{0%{-webkit-transform:scale(.7);transform:scale(.7)} 45%{-webkit-transform:scale(1.05);transform:scale(1.05)} 80%{-webkit-transform:scale(.95);transform:scale(.95)} to{-webkit-transform:scale(1);transform:scale(1)} } @-webkit-keyframes hideSweetAlert{0%{-webkit-transform:scale(1);transform:scale(1);ovisibility: visible;} to{-webkit-transform:scale(.5);transform:scale(.5);visibility: hidden;} } @keyframes hideSweetAlert{0%{-webkit-transform:scale(1);transform:scale(1);visibility: visible;} to{-webkit-transform:scale(.5);transform:scale(.5);visibility: hidden;} } ``` **注意:元素的display发生改变(显示与不显示切换时),动画会重新运行一遍** ```css display: none; /* display: block; */ visibility: hide; /* 不会这样 */ ``` * * * * * **分析:** 可以看到所有的动画,都被定义了,**每个动画定义了一个专门的类,将动画定义部分都单独剥离出来了,这样方便使用,能提高可维护性。** 比如:`[class~=anim]` 都为动画定义类。(**动画帧名 和 动画类名 相同**) 而动画的原理为:不应用动画时,**默认就是元素最终的位置**(动画类只是通过 变形/放大/偏移 等方式改变元素的形态和空间位置,**并不会对元素的文档流布局产生任何影响,这点很重要**,所以任何元素都可以添加动画类,并且是无害的),动画的`0% 帧`**把元素置为动画帧起点**(起点位置一般会隐藏元素,元素的初始状态),而`100% 帧`将元素所有转换(位移,变换等)效果移除,**恢复为正常状态,即为默认状态 —— 元素最终的位置。** (`@keyframes`自带过渡效果,所以帧的变换就成了动画了) 元素类定义只定义最终的,动画类 专门定义动画,开始到结束。定义部分 无需关心 动画部分,只关心元素本身就可以了,这样就相当于解耦了,也就是实现**关注点分离。** * * * * * ### 关于动画类的细节 如果一个动画处于未完成的状态,突然将类移去,那么元素就立即恢复原样,失去动画效果,所以如果要去掉动画类,必须等到动画运行完毕后再去除。 并且重复添加动画类,也只会触发一次动画。 所以如果要多次运行动画效果,就只能**安全的移除动画类**,然后再添加。 那么问题来了,要怎么铺捉到动画完成呢? https://daneden.github.io/animate.css/ demo上有个例子: ```javascript function testAnim(x) { $('#animationSandbox').removeClass().addClass(x + ' animated').one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function(){ $(this).removeClass(); }); }; $(document).ready(function(){ $('.js--triggerAnimation').click(function(e){ e.preventDefault(); var anim = $('.js--animations').val(); testAnim(anim); }); $('.js--animations').change(function(){ var anim = $(this).val(); testAnim(anim); }); }); ``` 可以看到,时机就是 `webkitAnimationEnd` 事件完成后,很明显这是一个动画结束事件。 元素动画结束事件,自然结束时触发,那么移除动画类导致的元素的动画效果停止,会不会触发呢。 > js能监听css3的动画结束事件,那能不能控制动画过程了呢?比如停止,暂停动画。 * * * * * ### 入场出场交错冲突问题 比如在入场动画进行时,用户点击取消了,那么此时在入场未完成的情况下要出场,这是怎么办。 如果直接移除入场类,那么元素将失去动画效果,回到本来的原点。 待实验…… * * * * * ### 动画实验 #### css动画版本 1. 连续添加相同的动画类没有用,动画只会运行一次。 2. 移除动画类,元素会回到没有动画类的初始状态。 3. 动画运行阶段,移除当前动画类,添加另一个动画类,元素突然回到无动画类的原点位置(一闪而过),再开始另一个动画。 4. 动画运行阶段,包括动画运行结束后,追加另一个动画类,没有作用,不会运行第二个动画。(jQuery中重复追加相同的类名只会有一个) 思考:当元素接受到新动画的指令时,如何由第一个动画平滑的转变运行第二个动画呢(即实现运行第二个动画时,起点就在当前位置,也就是要保留当前第一个动画的运行时场景、状态,就像进程调度一样,操作系统需要保存进程的状态,以便CPU再次切换回来时,能接着之前的状态继续工作),而不是第三种情况的那样立即失去动画效果,回到原点,一闪而过的那样非常不好。 ~~~ 不能中途离场,那么只能折中了,正确的效果就是等第一个动画运行完毕后才开始执行第二个动画。并且入场出场要衔接上,那么就要要求,第一个动画的结束就是第二个动画的开始状态,这个css里面可以设置。 animation-play-state: paused 可以暂停动画,但是能实现暂停后,转向另一个动画吗? fill-mode 控制动画结束后的位置 想到好的办法了,或许可以解决两个动画交替不能衔接的问题,方法就是,问题就在第二个动画开始时的状态,如果不设置 `to 0%` 直接设置 `to 100%` 不就没有这个问题了,不就可以直接由当前第一个动画顺畅过度执行第二个动画,第二个动画没有 `to 0%` ,不就没有闪动问题了吗? 待实验。 ~~~ #### js版本 待实验…… 项目地址:https://coding.net/u/xiasf/p/animation-test/git > 要理解动画,就要深入理解浏览器中js的工作原理,以及dom操作和渲染的细节,js是单进程的,js进程和渲染进程是互斥的。 * * * * * ### 扩展资料 [CSS VS JS动画,哪个更快](http://www.toutiao.com/i6303459255865311746/) [前端工程师CSS实例,加载动画](https://www.ixigua.com/i6457837281670595085/?utm_medium=feed_steam&utm_source=toutiao#mid=3529526410) [css动画:纯css实现灰太狼头像制作](http://www.toutiao.com/i6419085161446507010/) [css动画——动态渐变的效果](http://www.toutiao.com/i6405363758729789954/) [为什么老式电视比液晶电视伤眼睛,高速摄像机为你揭开其中奥秘](https://www.ixigua.com/i6514458568677130765/?utm_source=toutiao&utm_medium=feed_stream#mid=83935140651) [为什么手机拍摄快速移动的物体图像会变形?用超牛的画面来揭示](https://www.365yg.com/i6515267191212868099) [视觉暂留详解:请不要相信你的眼睛,片头试验很神奇,请配合哦](https://www.ixigua.com/i6515684983825236493/?utm_source=toutiao&utm_medium=feed_stream#mid=83935140651) [让你彻底搞懂前端路由前世今生!](https://www.toutiao.com/a6517043046805144067/?tt_from=weixin&utm_campaign=client_share&timestamp=1517478446&app=news_article&utm_source=weixin&iid=22069500288&utm_medium=toutiao_android&wxshare_count=1) [几种 JavaScript 动画库推荐](http://mp.weixin.qq.com/s/K7Q85nBkvSH-JXxqhsbyWg) [前端,react,动画](https://tech.youzan.com/react-animations/) [腾讯浏览服务-前端技术文档](http://x5.tencent.com/tbs/guide/tech.html#/) [盒子端 CSS 动画性能提升研究](https://mp.weixin.qq.com/s/buywVtqnFXxyy4v40F7yKw) [CSS动画:animation、transition、transform、translate傻傻分不清](https://mp.weixin.qq.com/s/-QTPwc8byT9kvn4m5JZSQA) ```css .slider-slogan .btn-g a:hover { transform: scale(1.1); animation-fill-mode: backwards; } /* animation-fill-mode和再次设置元素变换有关,不这样设置,再次变换没有效果 */ ``` [Web 动画帧率(FPS)计算](https://mp.weixin.qq.com/s/RbWeh0qfNHnXlotHLQOq8g) [SVG Path路径在网页开发的作用](https://mp.weixin.qq.com/s/r7ZnAwQsxjRkq9j0LA5MHQ) > 完美的骨骼过度动画 [CSS3 animation属性中的steps功能符深入介绍 « 张鑫旭-鑫空间-鑫生活](https://www.zhangxinxu.com/wordpress/2018/06/css3-animation-steps-step-start-end/) #### 动画不可不知的细节(那些不为人知的秘密) [【前端性能】Web 动画帧率(FPS)计算 - ChokCoco - 博客园](https://www.cnblogs.com/coco1s/archive/2017/12/13/8029582.html) [浏览器的 16ms 渲染帧 - CSDN博客](https://blog.csdn.net/crystal6918/article/details/77361495) [浏览器的 16ms 渲染帧--摘抄 - 刘浩2561179983 - 博客园](https://www.cnblogs.com/liuhao-web/p/8266872.html) [HTML5探秘:用requestAnimationFrame优化Web动画 – WEB骇客](http://www.webhek.com/post/requestanimationframe.html) [requestAnimationFrame 方法你真的用对了吗? - 前端经验分享 - SegmentFault 思否](https://segmentfault.com/a/1190000010229232) [requestAnimationFrame,Web中写动画的另一种选择 - 刘哇勇 - 博客园](https://www.cnblogs.com/Wayou/p/requestAnimationFrame.html) [贝塞尔曲线的一些事情_Animation, Web动画 教程_w3cplus](https://www.w3cplus.com/animation/mathematical-intuition-behind-bezier-curves.html) [【转载】运动曲线提升CSS动画效果](https://mp.weixin.qq.com/s/oTriaa3Y64F3SoXhfaQKFg) > 贝塞尔曲线的创造就是一个奇迹。 它们一开始是被用于计算机图形学来绘制形状,并且被用在Sketch和Adobe Illustrator这类工具中来绘制矢量图形。三次Bezier曲线使用如此广泛的原因是它们用起来非常方便:我们只需要改变4个不同点的位置,然后创造我们需要的曲线。 [前端动画效果实现的简单比较](https://mp.weixin.qq.com/s/tOhCWTLVzVdX07SaJYVEPg) [有趣的CSS弹跳动画](https://mp.weixin.qq.com/s/LRbUyKw_0Ko3MK33kruSUw) * * * * * last update:2018-7-19 19:37:59