乐趣区

关于react.js:React中用lottieweb自定义antdm的PullToRefresh下拉刷新动画

需要:

1、有两个 AE(Adobe After Effects)生成的动画 json 文件;
2、antdm 实现的下拉刷新组件 PullToRefresh;
3、须要自定义本人特色的下拉刷新动画特色;

剖析

1、动画 1 json 为刷新时的;
2、动画 2 json 为完结时的;
3、1)当动画 1 展现时动画 2 暗藏;
2)松开手指动画 1 开始播放;
3)动画 1 播放完结,动画 2 展现并播放;
4)动画 2 播放完结,动画 1 展现但不播放;

间接上代码:

import React, {useEffect} from 'react';
import lottie from 'lottie-web';
import {PullToRefresh} from 'antd-mobile-v5';
import refreshingJson from './animationJson/refreshing.json';
import endJson from './animationJson/end.json';
import './index.scss';

let refreshingAnimation;
let endAnimation;
export default (props) => {
  // 下拉刷新动画相干
  useEffect(() => {
    // 创立绑定动画
    refreshingAnimation = lottie.loadAnimation({container: document.getElementById('refreshingDom'),
      renderer: 'svg',
      loop: false,
      autoplay: false,
      animationData: refreshingJson,
    });
    endAnimation = lottie.loadAnimation({container: document.getElementById('completeDom'),
      renderer: 'svg',
      loop: false,
      autoplay: false,
      animationData: endJson,
    });

    // 第一局部动画实现
    refreshingAnimation.addEventListener('complete', () => {
      // dom1 暗藏,dom2 展现
      document.getElementById('refreshingDom').style.display = 'none';
      document.getElementById('completeDom').style.display = 'unset';
      // 动画 2 开始从第一帧播放
      endAnimation?.goToAndPlay(0);
    });
    // 第二局部动画实现
    endAnimation.addEventListener('complete', () => {
      // dom2 暗藏,dom1 展现
      // 原本想用一个 flag 在元素上判断 display,然而有效,所以只能这样
      document.getElementById('refreshingDom').style.display = 'unset';
      document.getElementById('completeDom').style.display = 'none';
    });
    // 销毁
    return () => {refreshingAnimation.destroy();
      endAnimation.destroy();}
  }, [])

  const controlAnimation = (status) => {if (status === 'refreshing') {
      // 动画 1 播放
      refreshingAnimation?.goToAndPlay(0);
    }
  }

  return <PullToRefresh
    onRefresh={onRefresh}
    completeDelay={2300} // 实现动画后提早的工夫
    headHeight={60} // 头部高度
    threshold={40} // 下拉多少高度触发
    renderText={(status) =>
      <div className="bbt_refresh_animation">
        <div id="refreshingDom"></div>
        <div id="completeDom"></div>
        {controlAnimation(status)}
      </div>
    }
  >
    <div> 动画哈哈哈哈哈 </div>
  </PullToRefresh>;
};

参考链接

https://zhuanlan.zhihu.com/p/…
https://mobile.ant.design/zh/…
https://www.jianshu.com/p/1cf…

最初的吐槽

如果两端动画的 json 为一个 json 文件,动画是连贯的,其实并不会这么吃力。。。

退出移动版