引言—

在 web 应用中,前端同学在实现动画效果时往往常用的几种方案:

  1. css3 transition / animation - 实现过渡动画
  2. setInterval / setTimeout - 通过设置一个间隔时间来不断的改变图像的位置
  3. requestAnimationFrame - 通过一个回调函数来改变图像位置,由系统来决定这个回调函数的执行时机,比定时修改的性能更好,不存在失帧现象

在大多数需求中,css3 的 transition / animation 都能满足我们的需求,并且相对于 js 实现,可以大大提升我们的开发效率,降低开发成本。

本篇文章将着重对 animation 的使用做个总结,如果你的工作中动画需求较多,相信本篇文章能够让你有所收获:

  • Animation 常用动画属性
  • Animation 实现不间断播报
  • Animation 实现回弹效果
  • Animation 实现直播点赞效果 ❤️
  • Animation 与 Svg 又会擦出怎样的火花呢??
  1. Loading 组件
  2. 进度条组件

Animation steps() 运用 ⏰

  1. 实现打字效果
  2. 绘制帧动画

Animation 常用动画属性—


介绍完 animation 常用属性,为了将这些属性更好地理解与运用,下面将手把手实现一些 DEMO 具体讲述

Animation 实现不间断播报—


实现不间断播报 DEMO [1]

通过修改内容在父元素中的 y 轴的位置来实现广播效果

@keyframes scroll {  0%{transform: translate(0, 0);  }  100%{transform: translate(0, -$height);  }}

.ul {animation-name: scroll;animation-duration: 5s;animation-timing-function: linear;animation-iteration-count: infinite;/* animation: scroll 5s linear infinite; 动画属性简写 */}

此处为了保存广播滚动效果的连贯性,防止滚动到最后一帧时没有内容,需要多添加一条重复数据进行填充

<div class="ul"><div class="li">小刘同学加入了凹凸实验室div><div class="li">小邓同学加入了凹凸实验室div><div class="li">小李同学加入了凹凸实验室div><div class="li">小王同学加入了凹凸实验室div>

<div class="li">小刘同学加入了凹凸实验室div>div>

Animation 实现回弹效果—

通过将过渡动画拆分为多个阶段,每个阶段的 top 属性停留在不同的位置来实现


实现回弹效果 DEMO[2]

/* 规定动画,改变top,opacity */@keyframes animate {  0% {top: -100%;opacity: 0;  }  25% {top: 60;opacity: 1;  }  50% {top: 48%;opacity: 1;  }  75% {top: 52%;opacity: 1;  }  100%{top: 50%;opacity: 1;  }}

为了让过渡效果更自然,这里通过 cubic-bezier() 函数定义一个贝塞尔曲线来控制动画播放速度

过渡动画执行完后,为了将让元素应用动画最后一帧的属性值,我们需要使用 animation-fill-mode: forwards

.popup {animation-name: animate;animation-duration: 0.5s;animation-timing-function: cubic-bezier(0.21, 0.85, 1, 1);animation-iteration-count: 1;animation-fill-mode: forwards;/* animation: animate 0.5s cubic-bezier(0.21, 0.85, 1, 1) 1 forwards; 动画属性简写 */}

Animation 实现点赞效果—

实现点赞效果 DEMO [3]

相信大多数同学都知道点赞效果,本文章会实现一个简易版的点赞效果,主要讲述一下实现思路:

  1. 为了让气泡可以向上偏移,我们需要先实现一个 y 轴方向上移动的 @keyframes 动画
/* 规定动画,改变y轴偏移距离*/@keyframes animation-y {  0%{transform:  translate(-50%, 100px) scale(0);  }  50%{transform:  translate(-50%, -100px) scale(1.5);  }  100%{transform:  translate(-50%, -300px) scale(1.5);  }}
  1. 为了让气泡向上偏移时显得不太单调,我们可以再实现一个 x 轴方向上移动的 @keyframes 动画
/* 规定动画,改变x轴偏移距离 */@keyframes animation-x {  0%{margin-left: 0px;  }  25%{margin-left: 25px;  }  75%{margin-left: -25px;  }  100%{margin-left: 0px;  }}

这里我理解:

  • 虽然是修改 margin 来改变 x 轴偏移距离,但实际上与修改 transform没有太大的性能差异
  • 因为通过 @keyframes animation-y 中的 transform 已经新建了一个渲染层 ( PaintLayers )
  • animation 属性 可以让该渲染层提升至 合成层(Compositing Layers) 拥有单独的图形层 ( GraphicsLayer ),即开启了硬件加速 ,不会影响其他渲染层的 paint、layout
  • 对于合成层(Compositing Layers)相关知识不是很了解的同学,可以阅读一下凹凸实验室(http://aotu.io)的文章《从浏览器渲染层面解析 css3 动效优化原理》
  • 如下图所示:

如笔者这里理解有误,还请读者大佬指出,感激不尽~

  1. 给气泡应用上我们所实现的两个 @keyframes 动画
.bubble {animation: animation-x 3s -2s linear infinite,animation-y 4s 0s linear 1;/*  给 bubble 开启了硬件加速 */}
  1. 在点赞事件中,通过 js 操作动态添加/移除气泡元素
function like() {const likeDom = document.createElement('div');  likeDom.className = 'bubble'; // 添加样式document.body.appendChild(likeDom);  // 添加元素  setTimeout( () => {document.body.removeChild(likeDom);  // 移除元素  }, 4000)}

Animation 与 Svg 绘制 loading/进度条 组件 ?—

Animation 与 Svg 绘制 loading/进度条 组件 ? DEMO [4]

  1. 首先,我们使用 svg 绘制一个圆周长为2 * 25 * PI = 157 的圆
<svg with='200' height='200' viewBox="0 0 100 100"  ><circle cx="50" cy="50" r="25"  fill="transparent" stroke-width="4" stroke="#0079f5" >circie>svg>

  1. 将实线圆绘制成虚线圆,这里需要用 stoke-dasharray:50, 50 (可简写为50) 属性来绘制虚线, stoke-dasharray 参考资料[5]
  • 它的值是一个数列,数与数之间用逗号或者空白隔开,指定短划线(50px)缺口(50px)的长度。
  • 由于50(短划线) + 50(缺口) + 50(段划线) = 150, 150 < 157,无法绘制出完整的圆,所以会导致右边存在缺口(7px)
<svg with='200' height='200' viewBox="0 0 100 100"  ><circle cx="50" cy="50" r="25"  fill="transparent" stroke-width="4" stroke-dasharray="50" stroke="#0079f5" >circie>svg>

  1. stroke-dashoffset 属性可以使圆的短划线和缺口产生偏移,添加 @keyframes 动画后能够实现从无到有的效果,stoke-dashoffset 参考资料[6]
  • 设置 stroke-dasharray="157 157",指定 短划线(157px)缺口(157px) 的长度。
  • 添加 @keyframes 动画 修改stroke-dashoffset值, 值为正数逆时针偏移?,, 值为负数时,顺时针偏移?
@keyframes loading {  0%{stroke-dashoffset: 0;  }  100%{stroke-dashoffset: -157; /* 线条顺时针偏移 */  }}circle{animation: loading 1s 0s ease-out infinite;}

  1. 修改短划线和缺口值
  • 为了让 loading 组件线条可见,我们需要一个50px的短划线,设置 stroke-dasharray="50"
  • 为了让短划线发生偏移后可以完全消失,缺口需要大于或等于圆周长157,设置 stroke-dasharray="50 157"
  • 添加 @keyframes 动画,为了让动画结束时仍处理动画开始位置,需要修改 stroke-dashoffset:-207(短划线+缺口长度)
  • 进度条也是类似原理,帮助理解 stroke-dashoffset 属性,具体实现请查看示例[7]
@keyframes loading {  0%{stroke-dashoffset: 0;  }  100%{stroke-dashoffset: -207; /* 保证动画结束时仍处理动画开始位置 */  }}circle{animation: loading 1s 0s ease-out infinite;}

Animation steps()运用—

steps()animation-timing-function 的属性值

animation-timing-function : steps(number[, end | start])
  • steps 函数指定了一个阶跃函数,它接受两个参数
  • 第一个参数接受一个整数值,表示两个关键帧之间分几步完成
  • 第二个参数有两个值 start or end。默认值为 end
  • step-start 等同于 step(1, start)。step-end 等同于 step(1, end)

steps 适用于关键帧动画,第一个参数将两个关键帧细分为N帧,第二个参数决定从一帧到另一帧的中间间隔是用开始帧还是结束帧来进行填充。

看下图可以发现:

  • steps(N, start)将动画分为N段,动画在每一段的起点发生阶跃(即图中的空心圆 → 实心圆),动画结束时停留在了第 N 帧
  • steps(N, end)将动画分为N段,动画在每一段的终点发生阶跃(即图中的空心圆 → 实心圆),动画结束时第 N 帧已经被跳过(即图中的空心圆 → 实心圆),停留在了 N+1 帧。

实践出真知!—

Animation 实现打字效果

Animation 实现打字效果 DEMO[8]

  • 此处用英文字母(I'm an O2man.)举例,一共有13个字符。[经测试,多数中文字体每个字符宽高都相等]
  • steps(13)可以将 @keyframes 动画分为13阶段运行,且每一阶段运行距离相等

效果如下:


/* 改变容器宽度 */@keyframes animate-x {  0%{width: 0;  }}

p {width: 125px;overflow: hidden;border-right: 1px solid transparent;animation: animate-x 3s 0s steps(13) 1 forwards;}
  • 可以发现仅仅这样还不够,动画运行过程中出现了字符被截断的情况,为了保证每个阶段运行后能准确无误地显示当前所处阶段的字符,我们还需要保证每个字符的width与动画每一阶段运行的距离相等
  • 设置Monaco字体属性,用以保证每个字符的 width 相同,具体像素受fontSize属性影响,示例中的字体宽度约为 9.6px,9.6px * 13(段数) = 124.8px (125px),所以当我们设置容器宽度为 125px,即可的达成目的:每个字符的 width 与动画每一阶段运行的距离相等(约为 9.6px )
p {/* 设置 Monaco 字体属性,字体大小为16px,用以保证每个字符的 width 相同,width 约为9.6p */font-family: Monaco;/* 9.6px * 13 = 124.8px (125px) */width: 125px ;font-size: 16px;overflow: hidden;border-right: 1px solid transparent;/* 同时应用动画 animate-x、cursor-x */animation: animate-x 3s 0s steps(13) 1 forwards,cursor-x 0.4s 0s linear infinite;}

Animation 实现帧动画 ⏰

Animation 实现帧动画 ⏰ DEMO [9]

  • 这里我们拿到了一张47帧的雪碧图(css spirit)[10],设置背景图
.main {width: 260px;height: 200px;background: url(url) no-repeat;background-size: 100%;background-position: 0 0;}
  • 添加 @keyframes 修改 background-position,让背景图移动
@keyframes animate {    0% {background-position: 0 0;    }

    100% {background-position: 0 100%;    }}.main{width: 260px;height: 200px;background: url(url) no-repeat;background-size: 100%;background-position: 0 0;animation: animate 2s 1s steps(47) infinite alternate;}
  • 同时, css 还提供了animation-play-state用于控制动画是否暂停
input:checked+.main{animation-play-state: paused;}

文章篇幅较长,感谢大家的阅读,希望各位看客能够有所收获~ ~ ~


相关参考资料

《Animation 常用动画属性》[11]

《CSS 参考手册》[12]

《steps 参考资料》[13]

《SVG 学习之 stroke-dasharray 和 stroke-dashoffset 详解》[14]

《理解 CSS3 Animation 中的 steps》[15]

《【译】css 动画里的 steps 用法详解》[16]

《CSS Will Change》[17]

参考资料

[1]

实现不间断播报 DEMO : https://codepen.io/awesomedevin/pen/wvMGEaY

[2]

实现回弹效果 DEMO: https://codepen.io/awesomedevin/pen/wvMGEaY

[3]

实现点赞效果 DEMO : https://codepen.io/awesomedevin/pen/dyGXEar

[4]

Animation 与 Svg 绘制 loading/进度条 组件 ? DEMO : https://codepen.io/awesomedevin/pen/zYromBB

[5]

stoke-dasharray 参考资料: https://www.cnblogs.com/daisygogogo/p/11044353.html

[6]

stoke-dashoffset 参考资料: https://www.cnblogs.com/daisygogogo/p/11044353.html

[7]

示例: https://codepen.io/awesomedevin/pen/zYromBB

[8]

Animation 实现打字效果 DEMO: https://codepen.io/awesomedevin/pen/xxZEjjO

[9]

Animation 实现帧动画 ⏰ DEMO : https://codepen.io/awesomedevin/pen/JjGRMgN

[10]

雪碧图(css spirit): https://img11.360buyimg.com/ling/jfs/t1/142743/11/2314/166268/5f046114Efb97efac/b327092864ed1f04.png

[11]

Animation 常用动画属性: https://www.w3school.com.cn/cssref/index.asp

[12]

CSS 参考手册: https://www.w3school.com.cn/cssref/index.asp

[13]

steps 参考资料: https://segmentfault.com/a/1190000007042048

[14]

SVG 学习之 stroke-dasharray 和 stroke-dashoffset 详解: https://www.cnblogs.com/daisygogogo/p/11044353.html

[15]

理解 CSS3 Animation 中的 steps: https://laixiazheteng.com/article/page/id/0gU2Wefas7hn

[16]

【译】css 动画里的 steps 用法详解: https://segmentfault.com/a/1190000007042048

[17]

CSS Will Change: https://developer.mozilla.org/zh-CN/docs/Web/CSS/will-change

聚焦全栈,专注分享 TypeScript、Web API、前端架构等技术干货。

animation停留_这些Animation动画技巧与细节你知道么相关推荐

  1. Silverlight Blend动画设计系列六:动画技巧(Animation Techniques)之对象与路径转化、波感特效...

    原文:Silverlight & Blend动画设计系列六:动画技巧(Animation Techniques)之对象与路径转化.波感特效 当我们在进行Silverlight & Bl ...

  2. python matplotlib animation制作世界人口变动动画

    python matplotlib animation制作世界人口变动动画 主要利用animation 做了个世界人口动画,数据从网上下载的.做成json格式的.读入pandas.没有放数据, 只是弄 ...

  3. Unity用Animation组件制作简单的动画

    游戏中经常会出现动态提示,例如提示当前金钱不足,一般会从屏幕中央弹出,然后缓慢的向上飘去. 今天游戏项目中遇到了这么个要求,以前做过几次,但总是会忘记,而且随着unity版本更新,新版本总有些莫名其妙 ...

  4. 用Animation制作简单的物体动画

    ** 用Animation制作简单的物体动画 ** 大家好,今天来记录一下制作简单物体动画的教程. 1.首先打开窗口(Window)-动画(Animation)-动画(Animation) 2.选中需 ...

  5. 利用CSS3的animation step属性实现wifi动画(结尾有彩蛋)

    之前攒的满满的SVG+CSS3做动画的技能一直未能放个大招,理由很简单,因为本身从事行业的性质,软件里不能出现劳什子动画这等花里胡哨的东西,哦,不不,叫隐喻行为引导的趣味化.用canvas实现了一个科 ...

  6. CSS3 animation实现点点点loading动画

    一.再续前缘 去年夏天,写了篇名为"CSS3 animation渐进实现点点点等待提示效果"的文章,主要内容是实现类似下面打点等待提示效果,比干巴巴的字符...要更人性化: 之前实 ...

  7. css手指点击样式,CSS3-通过 Animation实现手指点击动画效果代码

    CSS3-通过 Animation实现手指点击动画效果代码 html代码: css代码.wrapper { /* position: absolute; top: 50%; left: 50%; */ ...

  8. 利用Animation控件制作帧动画过程详解

    利用Animation控件制作帧动画过程详解 前言 通过Animation控件来达到序列图的播放(素材和示例视频在文章末尾) 一.序列图 (此素材为已经分割好的序列图) 如若序列图在一张图片上,请参考 ...

  9. android 图片闪光动画_剖析Android动画(图片闪烁、左右摇摆、上下晃动等效果) | 学步园...

    图片闪烁,类似这样. 2011-11-22 16:18 上传 左右摇摆: 2011-11-22 17:07 上传 一.续播  (不知道取什么名字好,就是先播放动画A, 接着播放动画B) 有两种方式. ...

最新文章

  1. vb.net中类型转换
  2. OCM备考 三. Managing Database Availability 之RMAN日常操作
  3. zsh 隐藏用户名和主机
  4. graphpad7.04多组比较p值_同是折线图为何你却这么优秀,这才是多组数据作图应该有的样子...
  5. 数据结构与算法系列——排序(10)_归并排序
  6. python模块介绍二。
  7. c语言 long double输出,printf和long double
  8. 如何删除github中的提交历史记录
  9. 准备Scrum之旅 之 Hello,温哥华——《轻松Scrum之旅》(16)
  10. 使用redis incr处理并发问题
  11. oslo.messaging库
  12. Beego2 使用Session时SetCookie无效
  13. 数据分析系统的设计与实现
  14. Mirai僵尸网络+DDoS 攻击+常用端口号大全
  15. 旧路由器改装无线打印服务器,旧路由器改wifi放大器详细教程【图】
  16. 计数器——Verilog HDL语言
  17. 数据分析案例(口罩亏损)--数据处理
  18. 怎么把ubuntu系统从英文修改为中文界面
  19. python知乎爬虫收藏夹_Python爬取知乎问题收藏夹 爬虫入门
  20. 【数学】Sixth Grade Math

热门文章

  1. Equipment upload - ERP inbound的debug
  2. 使用cl_htmlb_manager获得用户输入
  3. 从popup window出发做navigation
  4. winrar命令行的一些参数例子
  5. SAP CRM中间件下载equipment时遇到的一个错误
  6. Win10用Windows照片查看程序打开图片+更改注册表后导致Win10任务栏Adobe PDF阅读器图标显示异常
  7. excel删除重复数据保留一条_VBA利用字典删除重复行,保留唯一值
  8. python基础应用_【复习】mysql+python基础应用(20190815)
  9. IntelliJ IDEA scala的源码设置
  10. Hadoop生态系统的详细介绍