内容简介:大前端开发中经常会遇到动画的开发,那么什么是动画?在物理学中运动就是研究物体在时间维度和空间维度上改变的现象,所以动画也一样,动画主要研究2个因素,发生运动物体的在 Web 前端开发中实现动画有2种方式。要么依靠 CSS 实现动画,要么依靠 JS 控制实现动画。首先要说 CSS 中的4个概念:animation、transition、transform、translate
大前端开发中经常会遇到动画的开发,那么什么是动画?在物理学中运动就是研究物体在时间维度和空间维度上改变的现象,所以动画也一样,动画主要研究2个因素,发生运动物体的 时间 和 空间 。
Web前端开发中的动画
在 Web 前端开发中实现动画有2种方式。要么依靠 CSS 实现动画,要么依靠 JS 控制实现动画。
CSS 实现动画
首先要说 CSS 中的4个概念:animation、transition、transform、translate
属性 | 含义 |
---|---|
transition(过度动画) | 用于设置元素的样式过渡效果,和 animation 有类似的效果,但存在使用场合有着较大差别 |
transform(变形) | 用于设置元素的旋转、位移、缩放。和设置元素的动画并没直接关系,就跟写 css 属性一样 |
translate(移动) | 用于设置元素的位置,就是 transform 的一个属性 |
animation(动画) | 用于设置怨毒的动画属性,它是一个简写,有6个属性值 |
transition字面意思,过渡是指元素从属性a的某个值过渡到属性a的另一个值,这就是一个状态的改变,但是需要一个条件来触发从而发生这种转变,比如 &:hover,&:checked,&:focus、媒体查询或者 JS
#box { height: 100px; width: 100px; background: green; transition: transform 1s ease-in 1s; } #box:hover{ transform: rotate(180deg) scale(0.5,0.5); transform: translateX(100px); transform: translateY(100px) translateX(100px) scale(0.5, 0.5); } <div id="box"></div> 复制代码
分析:给 div 添加了一个过渡动画,动画指定了 transform 动画,触发时机为当鼠标移上去的时候。因此当鼠标移入的时候元素的 transform 属性发生变化,那么这个时候触发了 transition 动画,当鼠标移除的时候也产生了 transform 的变化,因此还是会触发 transition,产生动画。 上面设置了3个 transform 只有最后一个生效 因此 transition 产生动画的条件是设置的 property 发生变化,这种动画的特点是需要一个驱动力去触发。因此就存在一些缺点:
- 需要事件触发,没法在网页加载时自动发生
- 是一次性的,不能重复发生,除非再次触发
- 只可以定义开始状态和结束状态,不能定义中间状态,因此没有丰富的动画空间
- 一条 transition 规则,只能定义一个属性的变化,不能涉及多个属性
语法:transition:property duration timing-function delay
属性 | 含义 |
---|---|
transition-property | 规定设置过渡效果的 css 属性名称 |
transition-duration | 规定完成过渡效果需要时间 |
transition-timing-function | 规定速度效果的速度曲线 |
transition-delay | 规定动画效果何时开始 |
animation
animation 总体来说是对 transition 的增强,不再受限于触发时机和动画的属性值。
.box { height: 100px; width: 100px; border: 15px solid black; animation: changebox 4s ease-in-out 1s 1 alternate running forwards; } .box:hover { animation-play-state: paused; } @keyframes changebox { 10% { background: red; } 50% { width: 80px; } 70% { border: 15px solid yellow; } 100% { width: 180px; height: 180px; } } <div class="box"></div> 复制代码
animation: animation-name, animation-duration, animation-timing-function, animation-delay, animation-iteration-count, animation-direction, animation-fill-mode
属性 | 含义 |
---|---|
animation-name | 用来调用@keyframes定义好的动画,与@keyframes定义的动画名称一致 |
animation-duration | 指定元素播放动画所持续的时间 |
animation-timing-function | 指定速度效果的速度曲线,是针对每一个小动画所在时间范围内的变化频率 |
animation-delay | 定义在执行动画之前的等待时间 |
animation-iteration-count | 定义动画的播放次数,可选具体次数或者无限次(infinite) |
animation-direction | 设置动画播放方向:normal(按时间轴顺序)、alternate(轮流,即来回往复进行) |
animation-play-state | 控制元素的播放状态:running(继续)、paused(暂停) |
animation-fill-mode | 控制动画结束后元素的样式,有4个值: none(回到动画之前的状态)、forwards(元素停留在动画结束后的状态)、backwords(动画回到第一帧的状态)、both(根据 animation-direction 轮流应用 forwards 和 backwords 规则)。注意与 iteration-count 不要冲突 |
总结:单个动画效果、简单的由 transtion 实现,复杂的用 animation 实现。animation 出现后市面上出现了很多这种 css 动画库,其中我在使用 animate.css 推荐小伙伴们使用下
JS 实现动画
大家用 JS 写动画立马想到的是 setTimeout 和 setInterval,但是较好的动画体验是保持在 60fps 最好,上面的2个 api 由于会受到 runloop 的影响,并不会特别准时,JS 有个 requestAnimationFrame api 可以保持动画在 60fps, JS 实现动画的本质就是控制元素在时间和空间上的变化的研究。
假如要实现一个匀速直线动画,让一个 div 在 3秒内在水平方向上从向由右移动500px。那么如何实现,先从物理问题上解决吧。
总时间: 3s 总位移: 500px 那么每秒移动多少 500px/3s 我们设计一个 JS 函数。4个参数, 属性开始值,属性结束值,动画执行时间,回调函数
大体思路是:外界传入上面4个参数,我们可以记录函数调用刚开始的时刻也就是开始时间(start),然后通过 performance.now() 拿到当前时间(now),然后 period = (now-start) 就是经过的时间。然后通过 period/time 就是时间的进度百分比,拿这个百分比再去乘以总的属性值差就是当前的属性值,然后将计算结果实时调用回调函数(这个回调函数就是指定这个属性值如何应用到动画元素上)
/** * 执行补间动画方法 * * @param {Number} start 开始数值 * @param {Number} end 结束数值 * @param {Number} time 补间时间 * @param {Function} callback 每帧回调 * @param {Function} timing 速度曲线,默认匀速 */ function animate(start, end, time, callback, timing = t => t) { let startTime = performance.now() // 设置开始的时间戳 let period = end - start // 拿到数值差值 // 创建每帧之前要执行的函数 function loop() { liveAnimationFunction = requestAnimationFrame(loop) // 下一调用每帧之前要执行的函数 const passTime = performance.now() - startTime // 获取当前时间和开始时间差 let per = passTime / time // 计算当前已过百分比 if (per >= 1) { // 判读如果已经执行 per = 1 // 设置为最后的状态 cancelAnimationFrame(raf) // 停掉动画 } const pass = period * timing(per) // 通过已过时间百分比*开始结束数值差得出当前的数值 callback(pass) } let liveAnimationFunction = requestAnimationFrame(loop) // 下一阵调用每帧之前要执行的函数 } function doMove(easing) { animate(0, 100, 1000, move.bind(null, document.querySelector(`#${easing}Box`)), EasingFunctions[easing]) } function move(box, value) { box.style.transform = `translateX(${value}px)` } 复制代码
Native 端动画(iOS为例)
其实动画的本质就是元素时间和空间上发生变化的研究。在 web 前端如此,在 native 端也是如此,不过就是换了一些 api 如此。
举个例子,就拿上面所说的水平位移为例,下面给 iOS 的原生代码
//CALayer 层动画 CABasicAnimation *positionAnimation = [CABasicAnimation animation]; //指定动画路径是水平方向x轴 positionAnimation.keyPath = @"position.x"; //指定位移距离 positionAnimation.toValue = @1000; //下面2行代码让动画停留在动画结束的位置 positionAnimation.fillMode = kCAFillModeForwards;//(效果完全等同于 css 中的 animation-fill-mode属性) positionAnimation.removedOnCompletion = NO; [self.animationView.layer addAnimation:positionAnimation forKey:nil]; 复制代码
css 中的 animation-fill-mode(控制动画结束后元素的样式,有4个值: none(回到动画之前的状态)、forwards(元素停留在动画结束后的状态)、backwords(动画回到第一帧的状态)、both(根据 animation-direction 轮流应用 forwards 和 backwords 规则))和 native(iOS)端的 fillMode 属性一致。
下面提出 iOS 端的 fillMode 取值选项
/* `fillMode' options. */ CA_EXTERN CAMediaTimingFillMode const kCAFillModeForwards API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); CA_EXTERN CAMediaTimingFillMode const kCAFillModeBackwards API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); CA_EXTERN CAMediaTimingFillMode const kCAFillModeBoth API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); CA_EXTERN CAMediaTimingFillMode const kCAFillModeRemoved API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0)); 复制代码
看得出来 fillMode web 端和 native 端是一模一样的。
再举个例子,平时我们有可能画一根横线,在 web 端 和 native 端都存在 view 这样的概念,在 web 端可能会是一个 div(高度设置为1)或者是 canvas 实现(canvas 拿到当前上下文、绘制路径、关闭路径、填充颜色)。在 native 端也一样,开启绘图上下文、拿到上下对象、绘制路径、上色、关闭上下文。
所以其他具体的例子也就不举了,本质上大前端的所有动画干的事情都一样,所以我们需要处理好时间和位置的关系。
以上所述就是小编给大家介绍的《大前端动画》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 前端动画调研-V1
- 由奥迪车灯想到的前端动画
- 三角函数在前端动画中的应用
- 前端canvas动画如何转成mp4视频
- 【前端优化】动画几种实现方式总结和性能分析
- # 前端每日实战 168# 视频演示如何利用 Web Animation API 制作一个切换英语单词的交互动画
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。