龙空技术网

使用FLIP技术让编写动画事半功倍

闪念基因 157

前言:

而今看官们对“jsflip”可能比较着重,大家都需要剖析一些“jsflip”的相关资讯。那么小编也在网摘上汇集了一些关于“jsflip””的相关文章,希望看官们能喜欢,小伙伴们快快来学习一下吧!

Animation brings user interface to life.-Nick Babich

动画在用户交互中扮演着重要的地位。甚至可以说,动画是用户体验的核心部分之一。

合理的使用动画,不仅仅能够增强用户体验,有趣、活泼的动画,甚至可以提升业务转化率,促进业务的增长

很多开发者会认为开发动画过于复杂,且仅仅是锦上添花,所耗费的时间与带来的收益不成正比。导致当今互联网中,大多数的产品都存在着突兀的跳转和页面的抖动

事实上,简单的滑入、滑出动画在现今CSS3、web animation api技术的加持下,其实现已经变得非常的简单。只需要几行代码就可以完成

复杂的动画也可以使用逐帧动画、APNG、lottie来简化开发成本。

当然,复杂场景下的动画确实会给开发带来一定的难度和成本,下面这篇文章介绍了基于CSS的骨骼动画。作者在实现这种动画的时候,动了很多心思,也花了很多时间来调整动画的效果。

纯CSS实现简单骨骼动画

本文将简要介绍FLIP动画,是一种高性能的动画方案。

它适用于动画的初始态或最终态不明确的情况,使用FLIP技术,能够大大减少动画的开发成本。

FLIP动画

FLIP动画并不是卡片翻转动画的英文名称,而是四个字的组合:First, Last, Invert, Play

First

动画的元素的初始状态(比如位置、透明度等等)。

Last

动画的元素的最终状态。

Invert

DOM 元素属性的改变(比如 left、right、 transform 等等),会被集中起来延迟到浏览器的下一帧统一渲染,所以我们可以得到一个这样的中间时间点:DOM 状态(位置信息)改变了,而浏览器还没渲染。此时,通过简单的计算,可以将图片的位置使用transfrom放回到初始的状态。

Play:

执行动画,将transform置为0或none,移动到动画后的位置和尺寸。

在熟悉FLIP动画的原理之后,就很容易写出来下面类似于洗牌、增删卡片的动画了。

实战

说完了思路,来看看实际中怎么使用FLIP编写洗牌(shffule)动画吧。

下面的实现不依赖于任何框架,使用Vanilla JS编写。

First

获取所有元素shffule前的位置。可以使用getBoundingClientRect来获取元素的位置。

  const prevImgs = imgList;  function getRects(doms) {    return doms.map(dom => {      const rect = dom.getBoundingClientRect();      const { left, top } = rect;      return { left, top };    })  }  const prevPostions = getRects(imgList);
Last

获取洗牌之后元素的位置。这里需要将原有的DOM随机互换位置。并取得互换位置之后的定位。

   function swapNodes(n1, n2) {    const p1 = n1.parentNode;    const p2 = n2.parentNode;    let i1, i2;    if (!p1 || !p2 || p1.isEqualNode(n2) || p2.isEqualNode(n1)) return;    for (let i = 0; i < p1.children.length; i++) {      if (p1.children[i].isEqualNode(n1)) {        i1 = i;      }    }    for (let i = 0; i < p2.children.length; i++) {      if (p2.children[i].isEqualNode(n2)) {        i2 = i;      }    }    if (p1.isEqualNode(p2) && i1 < i2) {      i2++;    }    p1.insertBefore(n2, p1.children[i1]);    p2.insertBefore(n1, p2.children[i2]);  }    const randomMax = max => { return Math.floor(max * Math.random()) }  function randomArr(arr) {    const newArr = [...arr];    const arrLen = arr.length;    for (let i = 0; i < imgList.length; i++) {      const first = randomMax(arrLen);      const second = randomMax(arrLen);      swapNodes(arr[first], arr[second])    }    return newArr;  }  const newImgs = randomArr(imgList);  const postions = getRects(newImgs);
Invert And Play

上述代码中,prevPostions和postions分别存储着洗牌前和洗牌后元素的位置。并且此时,元素的实际位置已经是洗牌后,但还未渲染出来。我们可以使用translate3D将元素从洗牌后的位置移至洗牌前的位置。

然后,再使用Web Animation API播放图片移动至洗牌后translate3D(0,0,0)的位置。

prevImgs.forEach((imgRef, index) => {      const currentPostion = postions[index];      const prePostion = prevPostions[index];      const invet = {        left: prePostion.left - currentPostion.left,        top: prePostion.top - currentPostion.top      }      const keyF = [{        transform: `translate3D(${invet.left}px, ${invet.top}px, 0)`,      }, {        transform: 'translate3D(0,0,0)'      }];      const opts = {        duration: 1000,        easing: 'cubic-bezier(0,0,0.32,1)'      }      const animition = imgRef.animate(keyF, opts);    })

至此,一个shffule动画就完成了。在这个基础之上稍加润色。我们甚至可以写出来一个简单的连连看游戏。

作者: Andy

来源:微信公众号:IVWEB社区

出处:

标签: #jsflip