美文网首页
async/await在CSS动画控制中的简单应用

async/await在CSS动画控制中的简单应用

作者: DaveJump | 来源:发表于2017-07-25 11:49 被阅读0次

最近在做一个H5动画的小项目,由于项目周期充裕,前期主要是搭架构,也没用其他多余的动画库。由于经验不足,在搭架构的过程中也遇到挺多坑,比如webpack的配置问题、场景动画类的封装等等。这次就记录下如何异步控制动画的出现和消失。

回顾ES6的Promise和ES7的async/await

在ES6出来之前和不用其他动画库的情况下,很多人做简单动画基本都是用css3 animation + setTimeout + jQuery animate,但这样却面临一个问题:没错,回调地狱和嵌套层次太深,代码可读性大打折扣。
但现在有了ES6、ES7和babel,我们可以大胆地用promise和async/await来做动画的异步执行。
async函数是generator的一个语法糖,目前能被babel编译。它的优点在于外部不需要手动调用next方法,也不需要链式调用then方法,可以说是优于promise和generator。用法非常简单,来看一个简单例子:

const getUserData = url => (
    new Promise((resolve, reject) => {
       axios.get(url)
         .then(({ data }) => resolve(data))
         .catch(error => reject(error));
    })
);
const getUserDataByAsync = async () => {
    let _username;
    try{
      const { username } = await getUserData('https://github.com/username');
      _username = username;
      if(_username) {
        /* do something */
      }
    }catch(err){
      console.log(err);
    }
};
getUserDataByAsync();
  • 首先我们定义了一个getUserData函数,返回一个promise对象实例,用于抓取github上的用户信息。axios的get方法返回的也是一个promise对象,请求成功后会执行第一层promise的resolve方法,并把请求到的数据传出去。
  • 接下来定义一个名为getUserDataByAsync的async函数(也可以这么声明: async function getUserDataByAsync(){}),用于处理请求成功后的操作。await关键字后调用getUserData,而在此之后的代码(在try之内,await之后)则会被阻塞,待请求成功后才会继续执行。await getUserData()的返回值则是getUserData函数里resolve后传入的data。这里我们用try-catch来捕获请求失败后的异常信息,catch打印出来的则是getUserData里请求失败后reject传入的error。
  • 最后再调用getUserDataByAsync函数就行了。
我们用同样的方法封装一个动画延时器
  • 首先我们先封装动画方法,这里为了操作节点方便一点用了jQuery
const animate = several => {
     for (let effectName in several) {
       let effect = `${effectName}`,
           element_list = (several[effectName] instanceof Array) ? several[effectName] : [];

       element_list.forEach(element => {
         //为了防止display和animation冲突我们需要判断元素是否被隐藏了
         if ($(element).is(':hidden')) {
           $(element).show();
           setTimeout(() => {
             $(element).addClass(`animated ${effect}`);
           }, 10);
         } else {
           $(element).addClass(`animated ${effect}`);
         }
       });
     }
};

需配合自己写的css3 animation或引入animate.css库。

  • 再封装一个延时器
const delay = (timeout = 0) => (
    new Promise(resolve => {
      setTimeout(resolve, timeout);
    })
);
  • 之后就可以随意控制动画的出现和消失了
const pageAnimationStart = async () => {
    const _sceneWrap= $('#scene-wrap'),
          _title = _scene_wrap.find('.title'),
          _tree =  _scene_wrap.find('.tree'),
          _apples = _scene_wrap.find('.apple');

    animate({
      'scaleIn': [_sceneWrap]
    });

    await delay(1000);

    animate({
      'slideBounceInDown': [_tree]
    });

    await delay(1500);

    animate({
      'bounceIn': [_title, _apples]
    });
};
window.addEventListener('load', function(){
    pageAnimationStart();
}, false);

页面加载完成后,场景开始,先是整个场景背景_sceneWrap放大进入,1秒后大树_tree由上到下掉入,再过1.5秒后标题_title和苹果_apples跳入。
大概就是这样一个步奏,以异步执行、同步写法的方式,看起来特别舒服,清晰地展示了每一步该做什么,避免了的嵌套、回调和满屏的then方法。

这就是async/await在动画处理中的简单方法。其他应用场景等我研究过后再记录吧!

相关文章

网友评论

      本文标题:async/await在CSS动画控制中的简单应用

      本文链接:https://www.haomeiwen.com/subject/nfxwkxtx.html