前端播放在线spine方案

3,198 阅读5分钟

spine介绍

从前端程序员的角度来说,spine就是一种动画,严格来说是一种 2D 骨骼动画,具有体积小、流畅性、方便控制等优点,功能十分强大,更多详见Spine是什么?

一个spine动画一般由三个文件组成

  1. 精灵图集,一个图片文件,动画用到的所有图片拼合到一张图上,以.png结尾
  2. 图集数据,一个文本文件,包含各部分骨骼图片在精灵图中位置、宽高的数据,以.atlas结尾
  3. 动画数据,一个json文本文件,包含动画播放过程中的所有信息:动画的整体宽高,每个骨骼图片的宽高,以及每个动画播放时骨骼的位置、缩放、旋转等信息,以.json结尾

以上两个文本文件都有固定的格式,但咱们作为前端程序员不需要研究太多,只需要懂得如何播放就可以了

一般设计伙伴提供的spine文件都是一个文件夹,以spine的名字命名,其下是三个同名文件,文件不允许重命名,否则动画无法正常播放

image.png

播放环境

spine动画的使用场景很多,本文只介绍在Cocos Creator和h5中如何加载、播放spine。

其中Cocos版本是3.7,原生支持spine动画的播放。h5中借助pixi(v7.2.4)与pixi-spine(v4.0.4)

设计伙伴提供的spine版本为3.8.99,体现在json文件中,spine文件版本过低可能导致加载后不能正常解析

准备数据

播放spine的前提是在服务器上准备好动画数据,也就是之前提到的三个文件。为了能够正常加载与播放,我们需要这三个文件处在服务器的同一目录下,并且文件名称与动画名称一致。

具体的校验规则:

  1. 三个文件分别以.png .atlas .json结尾,且文件名相同
  2. Atlas文件的第一行为空行,第二行为图片文件的名称动效名称.png(如下图)

image.png

播放spine

接下来分别介绍Cocos和h5中播放spine的具体步骤

Cocos Creator

由于Cocos Creator原生支持spine的播放,实现相对简单一点,可以参考官方文档

我们现在有三个同路径的spine动画文件,并在cocos页面中创建一个节点并添加sp.Skeleton组件,接下来编写js代码

  1. 加载文本数据,在Cocos中使用assetManager加载远程资源,其中先加载两个文本资源,这里设置后缀名Cocos自动帮我们解析了json对象
  2. 加载图片资源,同样使用assetManager加载,其中获取的图片格式为ImageAsset。不在第一步一同加载是因为loadAny下载的图片在Web端会变成<img>节点
  3. 创建纹理对象,官方文档中下载的图片资源自动解析成Texture2D格式,但估计很久没更新了,实际运行时下载的图片格式为ImageAsset,需要手动创建Texture2D对象并绑定图片资源
  4. 创建骨骼并设置数据,将我们前几步准备的资源按照官方教程绑定上去,其中图片名字从路径中获取
  5. 从json对象中获取动画名称,播放动画~

具体代码如下:

// 三个文件的远程资源路径
let imageUrl = 'https://xxx/xxx/xxx.png';
let jsonUrl = 'https://xxx/xxx/xxx.json';
let atlasUrl = 'https://xxx/xxx/xxx.atlas';
// 加载图集数据和动画数据
assetManager.loadAny(
    [
        {url: atlasUrl, ext: '.txt'}, // 解析为文本
        {url: jsonUrl, ext: '.json'}, // 解析为json对象
    ],
    (error, assets) => {
        if (error) {
            console.log('json/atlas加载出错');
            return;
        }
        // 读取图集文本和json对象
        const atlas = assets[0];
        const json = assets[1];
        // 加载图片 返回的结果是ImageAsset类型
        assetManager.loadRemote(imageUrl, (error, imageAsset) => {
            if (error) {
                console.log('图片加载出错');
                return;
            }
            // 我们要用的是Texture2D对象,需要手动创建并绑定
            const texture = new Texture2D();
            texture.image = imageAsset;
            // 创建骨骼对象并设置数据
            let asset = new sp.SkeletonData();
            asset.skeletonJson = json; // 设置动画数据 这里传递json文本和json对象都可以
            asset.atlasText = atlas; // 设置图集数据
            asset.textures = [texture]; // 设置文本库
            // 从路径中获取图片文件名称(包含.png)
            let spineName = imageUrl.slice(image.lastIndexOf('/') + 1)
            asset.textureNames = [spineName];// 设置图片名称
            // 获取Skeleton组件 spineNode是提前在页面中准备的节点
            const comp = this.spineNode.getComponent(sp.Skeleton);
            // 设置spine数据
            comp.skeletonData = asset;
            // 循环播放动效 从json文件中读取第一个动画的名称
            comp.setAnimation(0, Object.keys(json.animations)[0], true);
        });
    }
);

其实cocos播放在线spine不要求三个远程文件目录一致,但需要图片的文件名称与动效名相同

h5

在h5中我们采用PIXI来播放spine,createjs、min2d也是不错的动画库,但使用它们还需要根据spine数据编写许多的代码才能支持运行,不如PIXI开箱即用,具体流程如下

  1. 在html文件中加载pixi.jspixi-spine.js,这里会在window身上绑定PIXI对象,在我们加载spine时访问调用就行了
  2. 加载数据,PIXI也提供了资源加载的方法Assets.load,只需要提供json文件的路径,他会自动加载同目录下的atlas和png文件
  3. 创建应用,这里可以传入页面中的canvas节点,若不传则自动创建,后续需要手动添加到页面上
  4. 创建spine动画对象并添加到画布中,然后设置动画的位置,获取动画名称,播放动画~

html

<script src="../static/js/pixi.min.js"></script>
<script src="../static/js/pixi-spine.min.js"></script>

js

// json文件的远程资源路径
let jsonUrl = 'https://xxx/xxx/xxx.json';
// 加载图集数据和动画数据
window.PIXI.Assets.load(jsonUrl).then(resources => {
    // 从骨骼数据中读取宽高
    const {width, height, animations} = resources.spineData;
    // 绑定canvas画布,设置宽高
    const app = new window.PIXI.Application({
        view: document.querySelector('#canvas'), // 设置canvas节点
        backgroundAlpha: 0, // 背景透明
        width,
        height,
    });
    // 创建spine动画对象并添加到画布中
    let animation = new window.PIXI.spine.Spine(resources.spineData);
    app.stage.addChild(animation);
    // 设置动画位置为画布中心
    animation.x = width / 2;
    animation.y = height / 2;
    // 循环播放动画
    animation.state.setAnimation(0, animations[0].name, true);
});

其实h5播放在线spine不需要文件名称与动效名相同,但要求三个远程文件的目录与名称一致

官方还介绍了通过npm导入的方式使用,但实际使用时发现下载的资源并没有被PIXI解析,无法直接使用,不如通过脚本引入

结语

以上就是Cocos和h5播放在线spine的方案,当时在寻找方案时发现网上的教程都较为落后,所以在实现功能后总结沉淀,希望能帮助到大家~