上手指南

阅读时间:6分钟更新于 2025-04-01 11:54

本文档是对各模块功能的概述,详细介绍见官网中对应部分内容

1. Galacean Effects 是什么

1.1. 基本介绍

Galacean Effects 是一款蚂蚁自研的专注于移动端的动效方案,主要由 Studio (编辑器)和 Player(播放器)组成。

Studio 是一款面向设计师的动效编辑器,在动效制作完成之后,需要在编辑器中进行 Galacean Effects 的资源发布,用于生成 Galacean Effects JSON 产物。发布过程会对 Galacean Effects 动效资源进行审核和压缩优化,保证上线的稳定性。

Player 用于播放 Galacean Effects JSON 产物。 Player 的底层渲染引擎是 WebGL/OpenGL,能够高性能地支持粒子、Spine、3D、特效等特性,实时展现惊艳的视觉表现效果。

1.2. 工作流

基于 Galacean Effects 的互动开发的主要流程如下,前端在开发前与设计沟通好诉求,由设计在 Studio 上根据设计稿和业务诉求制作动效并发布成 JSON 文件交付前端,前端再使用 Player 根据业务逻辑对 JSON 文件包含的动画进行播放控制。此外,在实际业务中,还会涉及到资源优化、降级、性能优化等操作。

1.3. 开发复杂度

1.3.1. 初级

直接使用 JSON 播放即可,可能使用动态文本/换图,交互点击:

1.3.2. 中级

根据业务逻辑组合或控制多个 JSON 的播放,也可能需要多个 Player 组合使用。

1.3.3. 高级

需要了解 Galacean Effects 中提供的元素控制 API 或 进行 Galacean Effects Plugin 插件开发。

物理系统

本质上也是实时控制位置,但是需要接入陀螺仪和物理碰撞等更复杂的系统,需要深度接入 Galacean Effects Plugin 的能力。

2. Galacean Effects 基本概念

下面结合 Studio 的界面介绍应用开发中应当知道的几个概念和操作:

  1. 合成:Player 播放动画是以合成对象为最小维度进行的,一个合成发布后对应一个 JSON 文件,一个项目中可能会用到多个合成。
  2. 元素:不同类型的元素具有不同特性,每个元素可以在动画中占据不同的时长。
    1. 图层(Sprite):2D 图片的动画,支持缩放、旋转、位移、透明度的变化。
    2. 粒子(Particle):由粒子发射器发射元素的动画。
    3. 交互(Interact):用于点击、消息、拖拽等事件的响应。
    4. 特效(Effect):制作一些高级效果。
    5. Spine(Spine):带骨骼驱动的2D变形动画。
    6. 3D(3D):3D 的模型动画。目前支持 FBX/GLB 格式的导入。
    7. 相机(Camera):Galacean Effects 中所有物体的是放置在三维空间中的,相机用于摆放在需要拍摄的位置
    8. 文本(Text) :支持中英文文字渲染的元素
  1. 项目操作:【发布】可以将当前选中的合成发布成 JSON 资源,【导出项目】可以导出 zip 资源包或其他格式文件
  2. 画布尺寸:如果是全屏动画,可以修改尺寸预览不同机型下的效果;
  3. 预览和分享:预览当前项目在手机上的效果或分享当前项目给他人。

3. H5 应用开发

在 Galacean Effects 的框架下,动画播放主要有三个阶段:资源加载,播放,销毁。

3.1. 基本使用

Galacean Effects 需要通过 <canvas /> 画布元素来执行 WebGL 指令,需要先根据业务需求设置好指定尺寸的容器并传递到 Galacean Effects。

3.1.1. 安装依赖

$ npm i @galacean/effects

3.1.2. 创建容器

<div id="container" style="width: 100vw; height: 100vh;"></div>

3.1.3. 实例化播放器

import { Player } from '@galacean/effects';

const player = new Player({
  /**
   * 播放器的容器,会在容器中创建 canvas,container 和 canvas 必传一个
   */
  container?: document.getElementById('container'),
  /**
   * 指定 canvas 进行播放
   */
  canvas?: HTMLCanvasElement,
  /**
   * 初始化 Player 或 loadScene 时遇到的异常
   * @since 2.3.0
   */
  onError: (err, ...args) => {
    console.error(err.message);
  },
});

3.1.4. 加载并播放动画

// 发布后的 Galacean Effects JSON
const myAnimation = 'https://mdn.alipayobjects.com/mars/afts/file/A*dnU-SprU5pAAAAAAAAAAAAAADlB4AQ';

// 1. 加载动画资源,加载完成后会自动播放
await player.loadScene(myAnimation);

// 2. 加载动画资源, 手动播放
const comp = await player.loadScene(myAnimation, {
  autoplay: false
});
// ...
player.play();

// 页面退出时销毁
window.addEventListener('unload', () => player.dispose());

3.1.5. 处理错误

3.1.5.1. 错误监听

可捕获异常的时机:

  • 初始化 Player 遇到异常(包含 webglcontextlost 事件)
  • loadScene 运行时异常(包含资源加载失败以及 rendererror 异常等)
  • 非以上两种情况,请自行 try/catch 捕获
const player = new Player({
  // ...
  onError: (err, ...args) => {
    switch (err.cause) {
      case 'webgliniterror':
        // WebGL 初始化失败或者 Player 已经被销毁
        break;
      case 'rendererror':
        // 运行时渲染错误
        break;
      case 'webglcontextlost': {
        // WebGL 上下文丢失
        console.info(args); // WebGLContextEvent 对象

        break;
      }
      default: {
        // 1. 网络异常导致的加载错误
        // 2. 其他未知异常(如:创建播放器传入的容器不是 `HTMLElement` 时抛出错误)
        console.error(err.message);

        break;
      }
    }
  },
});

注意:

  • 如果使用 onError 回调捕获异常,则以上两种时机无需再用 try/catch 捕获
  • 如果不使用 onError 回调,则以上两种时机务必需要自行用 try/catch 捕获异常

3.1.5.2. 错误处理

为了保证动画在低端设备上或出现渲染错误时可以稳定运行。一般需要准备错误处理方案:

  1. 简单动画可以用降级图片占位,降级图片在编辑器导出产物时会一起生成。

  1. 复杂动画需要前端实现 DOM 兜底方案。
const player = new Player({
  // ...
  onError: (err, ...args) => {
    // 使用降级图片
    const containerStyle =  container.style;
    containerStyle.backgroundImage = `url(${downgradeUrl})`;
    containerStyle.backgroundRepeat = 'no-repeat';
    containerStyle.backgroundSize = 'cover';
    containerStyle.backgroundPosition = 'center';
    // 或前端实现
  },
});

await player.loadScene(url);

3.1.6. 完整基本播放示例

https://www.galacean.com/effects/playground/vanilla-%E9%99%8D%E7%BA%A7%E5%A4%84%E7%90%86

3.2. 屏幕适配

请在动画制作前确认好使用的容器是否固定尺寸、全屏动画的适配模式。

3.2.1. 固定尺寸

在播放器创建之前使用 CSS 设置 container 的大小即可。

3.2.2. 全屏适配

Galacean Effects 使用不同的剪裁方式进行多尺寸屏幕的适配,剪裁方式的设置和不同机器下的渲染效果在编辑器中进行调节和预览,目前支持两种剪裁规则:

  1. 垂直剪裁,水平填满,一般适合手机屏幕,使用 iPhoneX 比例进行设计即可适配所有手机
  2. 水平剪裁,竖直填满,一般适合 PC 宽屏

无论使用哪种剪裁方式,都需要保持核心内容在最小尺寸机器下可以完整显示。

3.3. 功能

3.3.1. 交互

在编辑器中设置交互后,Player 可以完成元素的点击事件、创建/销毁生命周期等响应,Player 销毁后交互行为的监听都不会生效。

import { spec, Player } from '@galacean/effects';

type MessageItem = {
  name: string; // 编辑器中设置的名字
  phrase: number; // 元素状态,开始: MESSAGE_ITEM_PHRASE_BEGIN ,结束: MESSAGE_ITEM_PHRASE_END
}

type ClickedItem = {
  name: string; // 编辑器中设置的名字
}

const player = new Player({
  container,
  // 设置了此参数才响应交互
  interactive: true,
});

// 在指定元素的创建 / 销毁时触发
player.on('message', e => {
  console.info(`[player message] - item [${e.name}] trigger message, type [${e.phrase}].`);

  if (e.phrase === spec.MESSAGE_ITEM_PHRASE_BEGIN) {
    // 元素创建
  } else if (e.phrase === spec.MESSAGE_ITEM_PHRASE_END) {
    // 元素销毁
  }
});

// 在指定元素被点击时触发
player.on('click', e => {
  console.info(`[player click] - item [${e.name}] clicked.`);
});
// 也可以直接绑定元素上
const item = composition.getItemByName('lotteryBtn');

item?.on('click', e => {
  console.info(`[item click] - item [${e.name}] clicked.`);
});

3.3.2. 文本元素

在实际业务中,经常有一些动画含有动态数据,比如营销活动中的红包金额等需要在运行时才传入,可以使用文本元素功能。添加文本元素后,设计在编辑器设置好对应的属性,开发使用元素名进行元素获取和文案设置。

开发可以在动画播放前和播放过程中对文案内容进行设置:

// 播放前修改文案内容
const comp = await player.loadScene(myAnimation, {
  variables: {
    textName: '${YourText}',
  },
});

// 播放过程中修改文案内容
const textItem = comp.getItemByName('textName');
// 变更文案
textItem.content.setText('${YourText}');

3.3.3. 动态换图

除了文字,Galacean Effects 还支持图片的动态传入。设计需要在资源窗口对指定贴图开启改功能,开发根据设置的【背景字段名】即可在播放前完成对应图片的替换。

需要注意的是,动态传入的图片需要保持和编辑器中预设图片的宽高比例相同,否则会出现拉伸或压缩的情况。

player.loadScene(url, {
	variables: {
    // 动态图片,支持传入图片地址或地址数组
    background: 'url', // 如果图片加载失败,将会触发加载失败
    image_avatar: ['url','fallback_url'], // 如果第一个加载失败,将尝试使用第二个地址,都失败将会触发加载失败
	},
});

使用限制:

  • 降级后无法再使用动态换图

3.3.4. Spine

在 Galacean Effects 中支持 Spine 的渲染,需要单独引入 Spine 插件包。此外,Galacean Effects Player 也提供来 API 在运行时动态切换 Spine 的皮肤、动作和播放速度。

// NPM
import { Player } from '@galacean/efffects';
// 确保在 Player 引入之后再引入插件, 插件版本保持和 Player 一致
import '@galacean/effects-plugin-spine';

3.3.5. 3D model

在 Galacean Effects 中使用 3D 元素的渲染,需要单独引入 3D 插件包。3D模型可能会引入复杂的渲染,上线前需要评估性能。

// NPM
import { Player } from '@galacean/effects';
// 确保在 Player 引入之后再引入插件, 插件版本保持和 Player 一致
import '@galacean/effects-plugin-model';

3.4. 进阶使用

3.4.1. 多合成控制

  1. 默认情况下,Player 支持多合成播放,后播放的合成会叠加在已经播放的合成之上。处于内存考虑,当某个合成不需要时,我们可以调用 composition.dispose(),通过 player.destroyCurrentCompositions可以销毁当前正在播放的所有合成。调用 composition.dispose() 后,composition 会被自动从数组中移除,请不要直接修改player.compositions 数组。合成被销毁后,如果需要再次播放,请重新加载 JSON。
  2. 合成的位移、缩放、旋转等控制可以通过 Composition 的接口指定
  3. 合成的播放顺序、播放速度、播放循环等均可以通过接口设置,详见官网的 playground 中的示例

3.4.2. 元素操作

在复杂场景中,可能遇到合成中的元素需要随用户操作的情况。Player 中支持对元素的位置、显示 / 隐藏、速度等进行设置,详见官网的 playground 中的示例。

Preview