作者:阿文
原文:https://aotu.io/notes/2020/10...
本篇将着重对animation的应用做个总结。
引言
在 web 利用中,前端同学在实现动画成果时往往罕用的几种计划:
- css3 transition / animation - 实现过渡动画
- setInterval / setTimeout - 通过设置一个间隔时间来一直的扭转图像的地位
- requestAnimationFrame - 通过一个回调函数来扭转图像地位,由零碎来决定这个回调函数的执行机会,比定时批改的性能更好,不存在失帧景象
在大多数需要中,css3 的 transition / animation
都能满足咱们的需要,并且绝对于 js 实现,能够大大晋升咱们的开发效率,升高开发成本。
本篇文章将着重对 animation
的应用做个总结,如果你的工作中动画需要较多,置信本篇文章可能让你有所播种:
- Animation 罕用动画属性
- Animation 实现不间断播报
- Animation 实现回弹成果
- Animation 实现直播点赞成果 ❤️
Animation 与 Svg 又会擦出怎么的火花呢?????
- Loading 组件
- 进度条组件
Animation steps() 使用 ⏰
- 实现打字成果
- 绘制帧动画
Animation 罕用动画属性
介绍完 animation 罕用属性,为了将这些属性更好地了解与使用,上面将手把手实现一些 DEMO 具体讲述
Animation 实现不间断播报
实现不间断播报 DEMO
通过批改内容在父元素中的 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
/\* 规定动画,扭转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 实现点赞成果 Online Code
实现点赞成果 DEMO
置信大多数同学都晓得点赞成果,本文章会实现一个简易版的点赞成果,次要讲述一下实现思路:
- 为了让气泡能够向上偏移,咱们须要先实现一个 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); } }
- 为了让气泡向上偏移时显得不太枯燥,咱们能够再实现一个 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)
相干常识不是很理解的同学,能够浏览一下这篇文章从浏览器渲染层面解析 css3 动效优化原理 - 如下图所示:
如笔者这里了解有误,还请读者大佬指出,感激不尽~
- 给气泡利用上咱们所实现的两个 @keyframes 动画
.bubble { animation: animation-x 3s -2s linear infinite,animation-y 4s 0s linear 1; /\* 给 bubble 开启了硬件加速 */ }
- 在点赞事件中,通过 js 操作动静增加/移除气泡元素
function like() { const likeDom = document.createElement('div'); likeDom.className = 'bubble'; // 增加款式 document.body.appendChild(likeDom); // 增加元素 setTimeout( () => { document.body.removeChild(likeDom); // 移除元素 }, 4000) }
Animation 与 Svg 绘制 loading/进度条 组件 ???? Online Code
Animation 与 Svg 绘制 loading/进度条 组件 ???? DEMO
- 首先,咱们应用 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>
- 将实线圆绘制成虚线圆,这里须要用
stoke-dasharray:50, 50 (可简写为50)
属性来绘制虚线, stoke-dasharray 参考资料
- 它的值是一个数列,数与数之间用逗号或者空白隔开,指定
短划线(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>
stroke-dashoffset
属性能够使圆的短划线和缺口产生偏移,增加 @keyframes 动画后可能实现从无到有的成果,stoke-dashoffset 参考资料
- 设置
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; }
- 批改短划线和缺口值
- 为了让 loading 组件线条可见,咱们须要一个
50px
的短划线,设置stroke-dasharray="50"
- 为了让短划线产生偏移后能够齐全隐没,
缺口须要大于或等于圆周长157
,设置stroke-dasharray="50 157"
- 增加 @keyframes 动画,为了让
动画完结时仍解决动画开始地位
,须要批改 stroke-dashoffset:-207(短划线+缺口长度)
- 进度条也是相似原理,帮忙了解
stroke-dashoffset
属性,具体实现请查看示例
@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
- 此处用英文字母(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
- 这里咱们拿到了一张
47帧
的雪碧图(css spirit),设置背景图
.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 罕用动画属性
CSS 参考手册
steps() 参考资料
SVG 学习之 stroke-dasharray 和 stroke-dashoffset 详解
了解 CSS3 Animation 中的 steps()
【译】css 动画里的 steps()用法详解
CSS Will Change
相干文章
- 104道 CSS 面试题,助你查漏补缺
- 20个让你效率更高的CSS代码技巧
最初,欢送关注我的公众号:前端开发博客,回复 加群,一起学习提高。