Spark AR 是 Facebook 免费创作 AR 作品的平台,使用户能够为 Facebook 和 Instagram 创建交互式增强现实体验,超过 40 万名创作者,190个国家/地区,使用 Spark AR 来创作自己的AR作品
由于该软件无需任何编码知识即可使用,因此任何人现在都可以在 AR 世界中几乎没有经验地制作下一个疯狂式传播的 Instagram AR 特效,引领世界潮流。
专门的 AR 滤镜设计师单价甚至可达到 1000 美元到 3 万美元不等。
录音机的基对象动画
我们要应用的第一个动画是录音机的基对象(缩放)动画。我们想要通过播放的音频给录音机带来脉冲的效果。
加载场景模块
我们需要加载场景模块,这样我们就可以访问场景中的录音机的基对象。
下面的代码将加载场景模块并将其存储在一个变量中,以便以后可以使用它来访问场景中的对象。
脚本代码
const Scene = require('Scene');
require() 方法告诉脚本我们正在寻找一个模块,我们传入模块的名称作为参数来指定我们想要加载的模块。
Scene 变量现在包含了对 Scene 模块的引用,可以用它来访问模块的属性、方法、类和枚举。
访问基对象
在我们可以访问脚本中的基础对象之前,我们需要知道它在场景面板中被称为什么。
通过点击箭头展开 boombox_animated 对象,在场景面板中显示完整的对象树。
boombox 的基部由 base_jnt 对象表示。这个基础对象,以及它下面的扬声器,只是在 3D 模型中进行变换。
场景对象的名称已知后,我们现在可以在脚本中使用它来访问它。
下面的代码在场景中找到 base_jnt 对象,并将其存储在一个变量中,我们将在后面使用它来制作动画。
脚本代码
Scene.root.findFirst('base_jnt')
.then(function(base) {});
scene 模块的根(root)属性允许我们访问 Scene Panel 树的根,SceneObjectBase (由根属性返回)的 findFirst() 方法允许我们搜索树中的对象。
找到的对象 base 将在 Promise 回调中返回。
脚本代码
const Scene = require('Scene');
Scene.root.findFirst('base_jnt')
.then(function(base) {});
加载动画模块
我们需要加载动画模块,这样我们就可以在场景中为基对象和扬声器添加动画。
该模块的加载方式与场景模块相同,将单词'scene'替换为 'Animation'。
脚本代码
在场景模块上面的一行中添加加载动画模块的代码:
const Animation = require('Animation');
const Scene = require('Scene'); // Existing code
完整代码如下
const Animation = require('Animation');
const Scene = require('Scene');
Scene.root.findFirst('base_jnt')
.then(function(base) {});
创建基动画
在 Spark AR Studio 中创建动画包含3个步骤:
- 创建一个驱动器(driver)。
- 创建一个取样器(sampler)。
- 结合驱动器和采样器来创建动画。
创建一个驱动器
在 Spark AR Studio 中有两种类型的驱动器:
- 时间驱动器(Time driver) ——— 允许你为动画指定一个以毫秒为单位的持续时间,以及用于循环和镜像的可选参数。
- 值驱动程序器(Value driver) —— 允许你指定一个ScalarSignal,它的值将控制动画,阶段到给定的最小值和最大值。
对于这个项目中的动画,我们将使用时间驱动器。
下面的代码使用预先创建的一组参数创建一个时间驱动器:
脚本代码
const baseDriverParameters = {
durationMilliseconds: 400,
loopCount: Infinity,
mirror: true
};
const baseDriver = Animation.timeDriver(baseDriverParameters);
baseDriverParameters 对象指定:
- durationMilliseconds - 动画将持续0.4秒。
- loopCount —— 动画将无限循环。
- mirror —— 当动画完成一个循环时,动画将返回到它的初始值。
然后使用 Animation Module 的 timeDriver() 方法使用这些参数创建一个时间驱动器。
时间驱动器也需要指示才能启动。
如下创建时间驱动器
脚本代码
const baseDriver = Animation.timeDriver(baseDriverParameters); // Existing code
baseDriver.start();
在脚本中此时启动驱动器不会产生效果,直到我们稍后创建动画,目前我们只是将驱动器代码保存在一起。
脚本代码
const Animation = require('Animation');
const Scene = require('Scene');
Scene.root.findFirst('base_jnt')
.then(function(base) {
const baseDriverParameters = {
durationMilliseconds: 400,
loopCount: Infinity,
mirror: true
};
const baseDriver = Animation.timeDriver(baseDriverParameters);
baseDriver.start();
});
创建采样器
采样器允许您指定动画的开始值和结束值,以及应用于它的 easing (缓动)函数,从而改变变化率。
下面的代码创建了一个采样器。
脚本代码
const baseSampler = Animation.samplers.easeInQuint(0.9,1);
动画模块的 sampler 属性使我们可以访问 SamplerFactory 类,我们用它来通过 easeInQuint() 方法设置 easing 函数。我们将 0.9 和 1 传递给该方法,以指定动画的开始和结束值。
脚本代码
const Animation = require('Animation');
const Scene = require('Scene');
Scene.root.findFirst('base_jnt')
.then(function(base) {
const baseDriverParameters = {
durationMilliseconds: 400,
loopCount: Infinity,
mirror: true
};
const baseDriver = Animation.timeDriver(baseDriverParameters);
baseDriver.start();
const baseSampler = Animation.samplers.easeInQuint(0.9,1);
});
创建动画
动画是由驱动器和采样器组合而成的。
脚本代码
const baseAnimation = Animation.animate(baseDriver,baseSampler);
animation 模块的 animate() 方法返回一个 ScalarSignal ,根据所使用的 easing 函数,该信号每 0.4 秒在 0.9 到 1 之间变化。
脚本代码
const Animation = require('Animation');
const Scene = require('Scene');
Scene.root.findFirst('base_jnt')
.then(function(base) {
const baseDriverParameters = {
durationMilliseconds: 400,
loopCount: Infinity,
mirror: true
};
const baseDriver = Animation.timeDriver(baseDriverParameters);
baseDriver.start();
const baseSampler = Animation.samplers.easeInQuint(0.9,1);
const baseAnimation = Animation.animate(baseDriver,baseSampler);
});
随着动画创建,我们现在可以将它应用到 boombox 的基础对象,我们将使用它来改变比例。
录音机的基础对象只是代表了整个 3D 模型。将动画应用到基础对象将意味着我们正在动画整个对象。
获得基础变换
要访问基础的缩放,我们需要首先访问变换(Transform)。变换表示对象在其局部坐标系中的变换(位置、缩放和旋转)。
脚本代码
const baseTransform = base.transform;
SceneObjectBase 类(基础对象是该类的实例)的 transform 属性返回一个 TransformSignal。
绑定动画
通过访问基础的变换,我们现在可以将动画绑定到它的缩放属性,对模型进行动画。
脚本代码
baseTransform.scaleX = baseAnimation;
baseTransform.scaleY = baseAnimation;
baseTransform.scaleZ = baseAnimation;
TransformSignal 的 scaleX/Y/Z() 方法允许我们将动画输出的 baseAnimation ScalarSignal 绑定到 base 对象的缩放上。
脚本代码
const Animation = require('Animation');
const Scene = require('Scene');
Scene.root.findFirst('base_jnt')
.then(function(base) {
const baseDriverParameters = {
durationMilliseconds: 400,
loopCount: Infinity,
mirror: true
};
const baseDriver = Animation.timeDriver(baseDriverParameters);
baseDriver.start();
const baseSampler = Animation.samplers.easeInQuint(0.9,1);
const baseAnimation = Animation.animate(baseDriver, baseSampler);
baseTransform.scaleX = baseAnimation;
baseTransform.scaleY = baseAnimation;
baseTransform.scaleZ = baseAnimation;
});
保存脚本并返回 Spark AR Studio
录音机模型现在将在场景中动画化。