官网:Lottie is a mobile library for Web, and iOS that parses Adobe After Effects animations exported as json with Bodymovin and renders them natively on mobile! Lottie Docs

作用:

Lottie是一个库,可以解析使用AE制作的动画(需要用bodymovin导出为json格式),支持web、ios、android和react native。在web侧,lottie-web库可以解析导出的动画json文件,并将其以svg或者canvas的方式将动画绘制到我们页面中。

优点:

Lottie方法方案是由设计师出动画,导出为json,给前端播放。所以,使用Lottie方案的好处在于:

  • 动画由设计使用专业的动画制作工具Adobe After Effects来实现,使动画实现更加方便,动画效果也更好;
  • 前端可以方便的调用动画,并对动画进行控制,减少前端动画工作量;
  • 设计制作动画,前端展现动画,专业人做专业事,分工合理;
  • 卖家秀即买家秀,还原程度百分之百;
  • 使用lottie方案,json文件大小会比gif文件小很多,性能也会更好。

原理:

在Adobe After Effects中,动画是由一个一个的图层组成的,在相应的图层上面添加一些变换(例如:缩放、移动等),这变成为了动画。 lottie-web提供了很多操控动画的 方法 和 事件,基本可以满足对动画进行控制的需求。

play: 播放动画
stop: 停止播放动画
pause: 暂停动画
goToAndStop: 跳到某一帧动画,并停止
setDirection: 设置播放方向
setSpeed: 设置播放速度


onComplete: 动画播放完成触发
onLoopComplete: 当前循环播放完成触发
onEnterFrame: 播放一帧动画的时候触发
onSegmentStart: 开始播放一个动画片段的时候触发

使用示例:实现一个扑克翻牌抽奖

1. 点击按钮出现翻牌动画

动画由Lottie配置loadAnimation信息,包括作用的容器container用refs获取、

路径path为ui提供的json文件(内容为动画本身,包括素材图片的移动缩放等)通过cdn上传到云端、

渲染方式设为svg优化页面性能、

开启自动播放autoPlay、无需循环播放loop

2. 控制动画播放的时机,在合适的时候关闭动画,展现抽奖结果(弹框显示)。动画弹框均作用于一个盒子,通常会将该触发挂载到顶层有子组件调用。

<div ref="pokersLottie" />

    import lottie from 'lottie-web';

    let animation;

export default {
  data() {
    return {
      visible: false, // 弹窗展示状态
      awardImg:
        "https://4gimg.map.qq.com/test/f44ae635a21c7dd7f34fa6e668c41dfd.png",
      popType: "login",
      labelText: "送你",
      goldCount: 100,
      popShow: true, // 弹窗内容展示
      lottieShow: false, // 动画展示状态
    };
  },

  methods: {
    /**
     * 弹窗展示
     * @param params.awardImg 奖品图片
     * @param params.popType 弹窗类型
     * @param params.labelText 文本
     * @param params.goldCount 金币数量
     */
    init(params = {}) {
      this.awardImg = params.awardImg;
      this.popType = params.popType;
      this.labelText = params.labelText;
      this.goldCount = params.goldCount;
      this.visible = true;
      if (params.popType === "award") {
        this.popShow = false;  // 点击之后弹框先不展示
        this.lottieShow = true; // 先展示动画
        this.lottieLoad({
        // 重点配置
          animationOptions: {
            container: this.$refs.pokersLottie,
            path: "https://qqmap-1251316161.file.myqcloud.com/fe-static/mapActivity/hlddz/poker/data.json",
            renderer: "svg",
            autoPlay: true,
            loop: false,
          },
        });
        setTimeout(() => {
          this.lottieShow = false;  // 1.5秒后关闭动画
          this.popShow = true;      // 再展示弹框内容
          this.$refs.pokersLottie.innerHTML = "";
        }, 1500);
      }
    },



    /**
     * 动画预加载
     * @interface
     * @param {Object} animationOptions - 自定义动画选项
     * @param {Function} onDataReady - 资源加载结束钩子
     * @param {Function} onComplete - 动画完成加载钩子
     */
    lottieLoad({ animationOptions = {}, onDataReady, onComplete } = {}) {
      const options = Object.assign({}, animationOptions);
      animation = lottie.loadAnimation(options);
      animation.addEventListener("data_ready", () => {
        console.log("[lottieView][load] data_ready.");
        onDataReady && onDataReady();
      });
      animation.addEventListener("complete", () => {
        console.log("[lottieView][load] complete.");
        onComplete && onComplete();
      });
    },
  },
};
// 点击抽奖的盒子   
     <div
      v-image.normal="AthenaData.pokers"
      class="pokers"
      @click="reportLottery"
    />


    // 抽奖回调

  methods: {

      async reportLottery() {

      const container = getAthenaContainer();
      // 检查环境是否就绪
      if (!checkConditionReady(container.main)) return;

      if (this.goldCount < 100) return this.$mps.toast('金币不足,做任务获取更多金币');
      if (this.actInfoData?.data?.lottery?.lottery_infos?.length) {
        const lotteryInfoTemp = this.actInfoData.data.lottery.lottery_infos.filter(item => item.id === '19')[0];
        const loading = this.$mps.toast({
          text: '正在加载...',
          type: 'loading',
          autoDismiss: false,
          interactive: false,
        });
        // 向后端发抽奖请求
        const res = await fetchLottery({
          game_id: Number(lotteryInfoTemp.id),
          access_token: '',
        });
        if (res) {
          // 获取活动信息,刷新按钮
          const container = getAthenaContainer();
          fetchActInfo({}, container.main);
        }
        setTimeout(() => {
          loading.close();
        }, 800);
      }
    },


}