Spark AR —— 使用脚本创建效果(五)【脚本】

425 阅读4分钟

Spark AR 是 Facebook 免费创作 AR 作品的平台,使用户能够为 Facebook 和 Instagram 创建交互式增强现实体验,超过 40 万名创作者,190个国家/地区,使用 Spark AR 来创作自己的AR作品

由于该软件无需任何编码知识即可使用,因此任何人现在都可以在 AR 世界中几乎没有经验地制作下一个疯狂式传播的 Instagram AR 特效,引领世界潮流。

专门的 AR 滤镜设计师单价甚至可达到 1000 美元到 3 万美元不等。

通过手势缩放录音机

访问放置器(Placer)

为了缩放和旋转扬声器,我们将使用 placer 对象。我们需要这样做的原因是我们已经在缩放动画中使用了基础对象,如果我们在这里再次使用它,它会覆盖那个动画。

访问平面跟踪器的代码下面添加代码来查找 placer:

Promise.all([
    sceneRoot.findFirst('base_jnt'), // Existing code
    sceneRoot.findFirst('speaker_left_jnt'), // Existing code
    sceneRoot.findFirst('speaker_right_jnt'), // Existing code
    sceneRoot.findFirst('planeTracker0'), // Existing code
    sceneRoot.findFirst('placer')
 ])
 .then(function(objects) {
    const base = objects[0]; // Existing code
    const speakerLeft = objects[1]; // Existing code
    const speakerRight = objects[2]; // Existing code
    const planeTracker = objects[3]; // Existing code
    const placer = objects[4];

现在我们可以访问 placer,我们可以存储一个引用到它的变换(就像我们对基础对象所做的那样),以更新缩放和旋转。

脚本代码

const placerTransform = placer.transform;

订阅 Pinch 手势

为了缩放录音机,我们将订阅 Pinch 手势,你用两个手指做的手势越来越近或越来越远。

下面的代码使用了一种略有不同的订阅方法,该方法还允许我们在检测手势时捕获信号值。

脚本代码

 TouchGestures.onPinch().subscribeWithSnapshot( {

 }, function (gesture, snapshot) {

 });

subscribeWithSnapshot() 方法允许我们捕获额外的 “快照” 值,我们需要将其传递给回调函数以更新 scale。

传递快照值

我们想要在缩放手势时传递给回调函数的值是 placerTransform 当前的 x, y 和 z 缩放值。我们需要这么做的原因是,我们想要根据当前的比例改变缩放(根据手势增加或减少)。

添加快照代码给订阅函数

TouchGestures.onPinch().subscribeWithSnapshot( { // Existing code
    'lastScaleX' : placerTransform.scaleX,
    'lastScaleY' : placerTransform.scaleY,
    'lastScaleZ' : placerTransform.scaleZ 
   }, function (gesture, snapshot) { // Existing code
 }); // Existing code

快照是一个信号值字典,可以在回调函数中按名称访问它。

缩放的 placer

从快照传递的当前缩放值,现在可以在回调函数中使用,结合从缩放手势得到的缩放值来对 placer 进行缩放。

在回调函数中添加缩放代码:

 TouchGestures.onPinch().subscribeWithSnapshot( { // Existing code
     'lastScaleX' : placerTransform.scaleX, // Existing code
     'lastScaleY' : placerTransform.scaleY, // Existing code
     'lastScaleZ' : placerTransform.scaleZ // Existing code
 }, function (gesture, snapshot) { // Existing code
     placerTransform.scaleX = gesture.scale.mul(snapshot.lastScaleX);
     placerTransform.scaleY = gesture.scale.mul(snapshot.lastScaleY);
     placerTransform.scaleZ = gesture.scale.mul(snapshot.lastScaleZ);
 }); // Existing code

将快照值与 PinchGesture 的 scale 属性相乘,就可以得到想要的缩放效果。

脚本代码如下

const Animation = require('Animation');
 const Scene = require('Scene');
 const TouchGestures = require('TouchGestures');
 
 const sceneRoot = Scene.root;
 
 Promise.all([
     sceneRoot.findFirst('base_jnt'),
     sceneRoot.findFirst('speaker_left_jnt'),
     sceneRoot.findFirst('speaker_right_jnt'),
     sceneRoot.findFirst('planeTracker0'),
     sceneRoot.findFirst('placer')
 ])
 .then(function(objects) {
     const base = objects[0];
     const speakerLeft = objects[1];
     const speakerRight = objects[2];
     const planeTracker = objects[3];
     const placer = objects[4];
     
     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);
 
     const baseTransform = base.transform;
 
     baseTransform.scaleX = baseAnimation;
     baseTransform.scaleY = baseAnimation;
     baseTransform.scaleZ = baseAnimation;
     
     const speakerDriverParameters = {
         durationMilliseconds: 200,
         loopCount: Infinity,
         mirror: true
     };
 
     const speakerDriver = Animation.timeDriver(speakerDriverParameters);
     speakerDriver.start();
 
     const speakerSampler = Animation.samplers.easeOutElastic(0.7,0.85);
 
     const speakerAnimation = Animation.animate(speakerDriver,speakerSampler);
     
     const speakerLeftTransform = speakerLeft.transform;
 
     speakerLeftTransform.scaleX = speakerAnimation;
     speakerLeftTransform.scaleY = speakerAnimation;
     speakerLeftTransform.scaleZ = speakerAnimation;
 
     const speakerRightTransform = speakerRight.transform;
 
     speakerRightTransform.scaleX = speakerAnimation;
     speakerRightTransform.scaleY = speakerAnimation;
     speakerRightTransform.scaleZ = speakerAnimation;
     
     TouchGestures.onPan().subscribe(function(gesture) {
         planeTracker.trackPoint(gesture.location, gesture.state);
     });
     
     const placerTransform = placer.transform;
     
     TouchGestures.onPinch().subscribeWithSnapshot( {
         'lastScaleX' : placerTransform.scaleX,
         'lastScaleY' : placerTransform.scaleY,
         'lastScaleZ' : placerTransform.scaleZ 
     }, function (gesture, snapshot) {
         placerTransform.scaleX = gesture.scale.mul(snapshot.lastScaleX);
         placerTransform.scaleY = gesture.scale.mul(snapshot.lastScaleY);
         placerTransform.scaleZ = gesture.scale.mul(snapshot.lastScaleZ);
     });
 });

保存你的脚本并返回 Spark AR Studio

将项目发送到你选择的应用程序,你现在就可以通过使用两个手指和 Pinch 手势在你的设备上缩放录音机。

通过手势旋转录音机

订阅旋转手势

为了旋转录音机,我们将订阅旋转手势,这是一种用两个手指相互旋转的手势。

添加代码到脚本

TouchGestures.onRotate().subscribeWithSnapshot( {
     'lastRotationY' : placerTransform.rotationY,
  }, function (gesture, snapshot) {
     const correctRotation = gesture.rotation.mul(-1);
     placerTransform.rotationY = correctRotation.add(snapshot.lastRotationY);
 });

我们使用 subscribeWithSnapshot()placerTransformy 旋转值(我们将要围绕旋转的轴)传递给回调函数。

在回调函数中,我们将 RotateGesture 的 rotation 乘以 -1,然后将其加到 placerTransform 以旋转录音机。我们将手势旋转乘以 -1,以确保旋转发生在正确的方向上。

const Animation = require('Animation');
 const Scene = require('Scene');
 const TouchGestures = require('TouchGestures');
 
 const sceneRoot = Scene.root;
 
 Promise.all([
     sceneRoot.findFirst('base_jnt'),
     sceneRoot.findFirst('speaker_left_jnt'),
     sceneRoot.findFirst('speaker_right_jnt'),
     sceneRoot.findFirst('planeTracker0'),
     sceneRoot.findFirst('placer')
 ])
 .then(function(objects) {
     const base = objects[0];
     const speakerLeft = objects[1];
     const speakerRight = objects[2];
     const planeTracker = objects[3];
     const placer = objects[4];
     
     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);
 
     const baseTransform = base.transform;
 
     baseTransform.scaleX = baseAnimation;
     baseTransform.scaleY = baseAnimation;
     baseTransform.scaleZ = baseAnimation;
     
     const speakerDriverParameters = {
         durationMilliseconds: 200,
         loopCount: Infinity,
         mirror: true
     };
 
     const speakerDriver = Animation.timeDriver(speakerDriverParameters);
     speakerDriver.start();
 
     const speakerSampler = Animation.samplers.easeOutElastic(0.7,0.85);
 
     const speakerAnimation = Animation.animate(speakerDriver,speakerSampler);
     
     const speakerLeftTransform = speakerLeft.transform;
 
     speakerLeftTransform.scaleX = speakerAnimation;
     speakerLeftTransform.scaleY = speakerAnimation;
     speakerLeftTransform.scaleZ = speakerAnimation;
 
     const speakerRightTransform = speakerRight.transform;
 
     speakerRightTransform.scaleX = speakerAnimation;
     speakerRightTransform.scaleY = speakerAnimation;
     speakerRightTransform.scaleZ = speakerAnimation;
     
     TouchGestures.onPan().subscribe(function(gesture) {
         planeTracker.trackPoint(gesture.location, gesture.state);
     });
     
     const placerTransform = placer.transform;
     
     TouchGestures.onPinch().subscribeWithSnapshot( {
         'lastScaleX' : placerTransform.scaleX,
         'lastScaleY' : placerTransform.scaleY,
         'lastScaleZ' : placerTransform.scaleZ 
     }, function (gesture, snapshot) {
         placerTransform.scaleX = gesture.scale.mul(snapshot.lastScaleX);
         placerTransform.scaleY = gesture.scale.mul(snapshot.lastScaleY);
         placerTransform.scaleZ = gesture.scale.mul(snapshot.lastScaleZ);
     });
     
     TouchGestures.onRotate().subscribeWithSnapshot( {
         'lastRotationY' : placerTransform.rotationY,
     }, function (gesture, snapshot) {
         const correctRotation = gesture.rotation.mul(-1);
         placerTransform.rotationY = correctRotation.add(snapshot.lastRotationY);
     });
 });

保存你的脚本并返回 Spark AR Studio

将项目发送到你选择的应用程序,你现在就可以通过使用两个手指和旋转手势来旋转录音机。