Spark AR is Facebook’s free AR creation platform that enables users to create interactive AR experiences for Facebook and Instagram. More than 400,000 creators in 190 countries have used Spark AR to create their own AR creations
Since the software requires no coding knowledge to use, anyone can now lead the world by creating the next crazy viral Instagram AR effects with little experience in the AR world.
Specialized AR filter designers can cost anywhere from $1,000 to $30,000.
Zoom recorder with gestures
Access Placer
To scale and rotate the speaker, we will use the Placer object. The reason we need to do this is because we already used the base object in the zoom animation, and if we use it again here, it will overwrite that animation.
Add the following code to find the 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];
Copy the code
Now that we have access to the placer, we can store a transformation that refers to it (just as we did with the underlying object) to update the scale and rotation.
Script code
const placerTransform = placer.transform;
Copy the code
Subscribe to Pinch Gesture
To scale the recorder, we’re going to subscribe to the Pinch gesture, where you gesture closer and further away with two fingers.
The following code uses a slightly different subscription method that also allows us to capture signal values while detecting gestures.
Script code
TouchGestures.onPinch().subscribeWithSnapshot( {
}, function (gesture, snapshot) {});Copy the code
The subscribeWithSnapshot() method allows us to capture additional “snapshot” values that we need to pass to the callback callback update scale.
Passing snapshot values
The values we want to pass to the callback function when scaling the gesture are the current x, Y, and Z scaling values of the placerTransform. The reason we need to do this is that we want to change the scaling (increase or decrease depending on the gesture) based on the current scale.
Add snapshot code to the subscription function
TouchGestures.onPinch().subscribeWithSnapshot( { // Existing code
'lastScaleX' : placerTransform.scaleX,
'lastScaleY' : placerTransform.scaleY,
'lastScaleZ' : placerTransform.scaleZ
}, function (gesture, snapshot) { // Existing code
}); // Existing code
Copy the code
A snapshot is a dictionary of signal values that can be accessed by name in the callback function.
Scaling of placer
The current scale value passed from the snapshot can now be used in the callback function to scale the placer in conjunction with the scale value obtained from the scale gesture.
Add scaling code to the callback function:
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
Copy the code
Multiply the snapshot value by PinchGesture’s scale property to get the desired scaling effect.
The script code is as follows
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);
});
});
Copy the code
Save your script and return to Spark AR Studio
Send the project to the app of your choice and you can now scale the recorder on your device by using two fingers and the Pinch gesture.
Rotate recorder by gesture
Subscribe rotation gesture
To spin the recorder, we will subscribe to the spin gesture, which is a gesture that uses two fingers to rotate each other.
Add code to the script
TouchGestures.onRotate().subscribeWithSnapshot( {
'lastRotationY' : placerTransform.rotationY,
}, function (gesture, snapshot) {
const correctRotation = gesture.rotation.mul(-1);
placerTransform.rotationY = correctRotation.add(snapshot.lastRotationY);
});
Copy the code
We pass the y rotation value of the placerTransform (the axis we’ll rotate around) to the callback function using subscribeWithSnapshot().
In the callback function, we multiply RotateGesture’s rotation by -1, and then add it to the placerTransform to rotate the recorder. We multiplied the gesture rotation by -1 to ensure that the rotation occurred in the right direction.
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);
});
});
Copy the code
Save your script and return to Spark AR Studio
Send the item to the app of your choice and you can now rotate the recorder by using two fingers and the spin gesture.