微信小程序使用动画--lottie、svga

1,477 阅读3分钟

svga动画

一、引入js

  1. git项目地址:github.com/svga/SVGAPl…
  2. 直接下载本仓库下的 build/svga.min.js 并放置到小程序工程适当目录下,在需要使用的地方,使用以下方式引入

二、使用

只支持 svga 2.0 格式动画,如果无法播放动画,请联系设计师要求导出 2.0 格式,或者进入 svga.io 预览页自助转换。

添加 Canvas 组件

在需要播放动画的页面 wxml 中,添加以下 canvas,其中 type 必须为 2d,width 和 height 必须指定具体值,id 为任意值。

<canvas type="2d" style="width: 300px; height:300px; background-color: black" id="myCanvas"></canvas>

三、加载动画并播放

在适当的地址使用以下方式加载并播放动画,注意安全域名问题。

const SVGA = require("../svga.min.js")

const app = getApp()

Page({
  data: {

  },
  onReady: function () {
    let parser = new SVGA.Parser()
    let player = new SVGA.Player("#myCanvas")
    // 在组件中
    // let player = new SVGA.Player(wx.createSelectorQuery().in(this).select("#myCanvas"))
    parser.load("https://github.com/svga/SVGA-Samples/raw/master/angel.svga", function (videoItem) {
      player.setVideoItem(videoItem);
      player.startAnimation();
    })
  },
})

四、嵌入音频

由于小程序播放带有音效svga动画,无法播放音效,所以需要另外播放音频

const SVGA = require("../svga.min.js")

const app = getApp()

Page({
  data: {

  },
  onReady: function () {
    this.audio = wx.createInnerAudioContext();
    this.audio.autoplay = false;
    this.audio.src =
      "https:xxx.mp3";
    let parser = new SVGA.Parser()
    let player = new SVGA.Player("#myCanvas")
    // 在组件中
    // let player = new SVGA.Player(wx.createSelectorQuery().in(this).select("#myCanvas"))
    parser.load("https://github.com/svga/SVGA-Samples/raw/master/angel.svga", function (videoItem) {
      player.loops=1
      player.setVideoItem(videoItem);
      player.startAnimation();
      this.play();
    })
  },
})

该svga更多使用方法请看项目:github.com/svga/SVGAPl…

lottie-miniprogram

一、通过 npm 安装

npm install --save lottie-miniprogram

二、使用

只支持 svga 2.0 格式动画,如果无法播放动画,请联系设计师要求导出 2.0 格式,或者进入 svga.io 预览页自助转换。

添加 Canvas 组件

在需要播放动画的页面 wxml 中,添加以下 canvas,其中 type 必须为 2d,width 和 height 必须指定具体值,id 为任意值。

<canvas id="canvas" type="2d" style="width:{{width}}px;height:{{height}}px;"></canvas>

三、加载动画并播放

使用方式一:animationData--JSON数据,与第二种使用方式path互斥

直接使用json数据
  animationData: {......},//json数据省略
嵌入本地js文件

animationData: require("xxx.js"),

xxx.js:Lottie动画json数据,需要将该json改为js,即开头需要加上module.exports=

module.exports =json数据
modele.exports={
    key:value,
    key:value
}

全部代码如下

import lottie from "lottie-miniprogram";
data:{
    width: wx.getSystemInfoSync().windowWidth,
    height: (1624 * wx.getSystemInfoSync().windowWidth) / 750,
}
onReady(options) {
    wx.createSelectorQuery()
        .select("#canvas")
        .node((res) => {
          const canvas = res.node;
          const context = canvas.getContext("2d");
          canvas.width = this.data.width;
          canvas.height = this.data.height;
          lottie.setup(canvas);
          lottie.loadAnimation({
            loop: false,
            autoplay: true,
           animationData:{......}
            rendererSettings: {
              context,
            },
          });
        })
        .exec();
}

使用方式二:path--JSON文件路径

path:'xxxx.com/animation.j…

import lottie from "lottie-miniprogram";
data:{
    width: wx.getSystemInfoSync().windowWidth,
    height: (1624 * wx.getSystemInfoSync().windowWidth) / 750,
}
onReady(options) {
    wx.createSelectorQuery()
        .select("#canvas")
        .node((res) => {
          const canvas = res.node;
          const context = canvas.getContext("2d");
          canvas.width = this.data.width;
          canvas.height = this.data.height;
          lottie.setup(canvas);
          lottie.loadAnimation({
            loop: false,
            autoplay: true,
           path:"绝对路径",//http:xxxx.json
            rendererSettings: {
              context,
            },
          });
        })
        .exec();
}
某些动画所需的图片可能较大,图片是单独的一个文件夹,并没有打包进json文件,这时候就需要使用另一个字段 : assetsPath 。 它可以配置图片的路径。(这部分内容转载:juejin.cn/post/698055… )
构建项目建议将图片拿出来放到项目的public目录下

截屏2021-07-03 下午12.31.12.png

然后配置加上
    /* 省略*/
    assetsPath: `/effectfile/ribbon/images/`,
    /*省略*/
复制代码
为什么要这么配置呢?首先来看一下json文件的 assets字段,
"assets":[{"id":"image_0","w":131,"h":64,"u":"images/","p":"img_0.png","e":0}]
复制代码
还有获取资源的源码
AnimationItem.prototype.getAssetsPath = function (assetData) {
    var path = '';
    if(assetData.e) {
        path = assetData.p;
    } else if(this.assetsPath){
        var imagePath = assetData.p;
        if(imagePath.indexOf('images/') !== -1){ // 这里就把 images/忽略掉,只拿了图片名字,所以assetsPath直接找图片放的位置的路径就行
            imagePath = imagePath.split('/')[1];
        }
        path = this.assetsPath + imagePath;
    } else {
        path = this.path;
        path += assetData.u ? assetData.u : '';
        path += assetData.p;
    }
    return path;
};
复制代码
重点 :我的文件 e 为 0,所以走了else if;这个分支里面其实会忽略 u ,所以你要在自己的assetsPath路径里加上你的真实文件所在的目录,可以叫任意名字
本地开发时public文件夹下的文件相当于在 / 下,所以就可以引用到了。
如果部署到生产环境的话,那就要加上生产环境的主机地址
如果使用CDN则和部署生产环境类似,改为cdn的域名地址
import lottie from "lottie-miniprogram";
data:{
    width: wx.getSystemInfoSync().windowWidth,
    height: (1624 * wx.getSystemInfoSync().windowWidth) / 750,
}
onReady(options) {
    wx.createSelectorQuery()
        .select("#canvas")
        .node((res) => {
          const canvas = res.node;
          const context = canvas.getContext("2d");
          canvas.width = this.data.width;
          canvas.height = this.data.height;
          lottie.setup(canvas);
          lottie.loadAnimation({
            loop: false,
            autoplay: true,
            assetsPath:"域名地址"//http:xxxxxx/
           path:"绝对路径",//http:xxxx.json
            rendererSettings: {
              context,
            },
          });
        })
        .exec();
}

四、嵌入音频

import lottie from "lottie-miniprogram";
data:{
    width: wx.getSystemInfoSync().windowWidth,
    height: (1624 * wx.getSystemInfoSync().windowWidth) / 750,
}
onReady() {
    this.isPlay = false;
    this.audio = wx.createInnerAudioContext();
    this.audio.autoplay = false;
    this.audio.src =
      "https://xxx.mp3";
    wx.createSelectorQuery()
      .selectAll("#canvas")
      .node((res) => {
        const canvas = res[0].node;
        const context = canvas.getContext("2d");
        canvas.width = this.data.width;
        canvas.height = this.data.height;
        lottie.setup(canvas);
        this.ani = lottie.loadAnimation({
          loop: false,
          autoplay: false,
          path: "https://xxx.json",
          assetsPath: "https://xxx/images/",
          rendererSettings: {
            context,
          },
        });
         this.ani.play();
          this.ani.onEnterFrame = () => {
            if (!this.isPlay) {
              this.isPlay = true;
              this.play();
            }
          };
      })
      .exec();
  },
  play() {
    this.audio.play();
  },