大前端动画

栏目: CSS · 发布时间: 6年前

内容简介:大前端开发中经常会遇到动画的开发,那么什么是动画?在物理学中运动就是研究物体在时间维度和空间维度上改变的现象,所以动画也一样,动画主要研究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 发生变化,这种动画的特点是需要一个驱动力去触发。因此就存在一些缺点:

  1. 需要事件触发,没法在网页加载时自动发生
  2. 是一次性的,不能重复发生,除非再次触发
  3. 只可以定义开始状态和结束状态,不能定义中间状态,因此没有丰富的动画空间
  4. 一条 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 端也一样,开启绘图上下文、拿到上下对象、绘制路径、上色、关闭上下文。

所以其他具体的例子也就不举了,本质上大前端的所有动画干的事情都一样,所以我们需要处理好时间和位置的关系。


以上所述就是小编给大家介绍的《大前端动画》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Mechanics of Web Handling

The Mechanics of Web Handling

David R. Roisum

This unique book covers many aspects of web handling for manufacturing, converting, and printing. The book is applicable to any web including paper, film, foil, nonwovens, and textiles. The Mech......一起来看看 《The Mechanics of Web Handling》 这本书的介绍吧!

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具