This is the 21st day of my participation in the August More Text Challenge
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.
In addition to JavaScript, SparkAR Studio also supports TypeScript.
The TypeScript language is a superset of JavaScript that follows an object-oriented programming structure and provides additional language features such as optional static typing and access modifiers for class members.
When adding a new script to Spark AR Studio, you can choose whether to create a new JavaScript file or TypeScript file.
You can use both JavaScript and TypeScript files in your effects without making any changes to existing.js files.
All script files should have a unique name, regardless of the extension — TypeScrip t files and JavaScript files cannot share the same name.
While many ides support the TypeScript language, some provide additional features to enhance the development experience. For example, Visual Studio Code provides syntax highlighting, automatic Code completion, and suggested Code snippets, among other useful development features.
Listed below are some of the key language features TypeScript provides.
Module import syntax
The syntax for importing modules from the SparkAR API is slightly different in TypeScript, but the functionality is the same.
// How to load in modules in a TypeScript file
import Scene from 'Scene';
import Diagnostics from 'Diagnostics';
Copy the code
Once imported, you can use the API just as you would in a JavaScript file.
// How to load in modules in a TypeScript file
import Diagnostics from 'Diagnostics';
// Enable async/await in TypeScript [Part 1]
(async function () {
// Log a message to the console
Diagnostics.log("Hello world");
// Enable async/await in TypeScript [Part 2]}) ();Copy the code
You can also import script packages from the AR library just like you would with JavaScript.
import Cannon from 'cannon';
// Enable async/await in TypeScript [Part 1]
(async function () {
const world = new Cannon.World();
// Enable async/await in TypeScript [Part 2]}) ();Copy the code
Type annotation
In TypeScript, you can choose data types that explicitly specify variables, function parameters, function return types, or object attributes. This differs from weakly typed languages such as JavaScript, which infer data types based on usage.
The syntax for type annotations is :type, where type is a valid TypeScript type.
// Declaring variables with type annotation in TypeScript
var message: string = "Hello";
var someNumber: number = 10;
var someBoolean: boolean = true;
// Type annotations are optional, so the following declaration is also valid
// The type of 'value' is inferred as a number because of the value assigned
var value = 5;
// Type annotation for a function's parameters and return type
function addTwoNumbers(x: number, y: number) :number {
return x + y;
}
Copy the code
Type annotations are used to enforce type checking, which helps catch common data type errors at compile time.
// Declaring two variables of different data types
var message: string = "Hello";
var someNumber: number = 10;
// Throws a compiler error because we are trying to assign a numerical value to an object of type 'string'
message = 10;
// Throws a compiler error because the function 'toUpperCase' does not exist for objects of type 'number'
someNumber.toUpperCase();
Copy the code
Strict typing also helps code readability and maintainability.
Types of assertions
You can use type assertion to set the type of an object or value to a specific Spark type through the AS keyword. Such as:
// Locate the plane in the scene, which we know will be of type Plane
const plane = await Scene.root.findFirst('plane0') as Plane;
// Create a reference to the position property, which we know will be a PointSignal
const position = plane.transform.position as PointSignal;
Copy the code
Doing so allows the compiler to provide correct type information and auto-completion for objects and values.
Type assertions are only valid at compile time and do not affect the runtime behavior of your code.
Access modifier
When creating a class, you can use TypeScript’s three access modifiers to set the accessibility level of a property or method:
-
Publi C – Public properties or methods can be accessed from anywhere. If no access modifier is specified, a public modifier is assigned by default.
-
Private – A Private property or method can only be accessed from the class that declared it. Attempting to access it from outside the class results in a compilation error.
-
Protected – A Protected property or method can be accessed from the same class that declared it and from any subclasses (classes that inherit from their parent). Trying to access it from anywhere else results in a compilation error.
class Person {
// These variables are only accessible from within the 'Person' class
private firstName: string;
private lastName: string;
// This variable is accessible from within the 'Person' class, and any of its subclasses
protected idNumber: number;
constructor(firstName: string, lastName: string, idNumber: number){
this.firstName = firstName;
this.lastName = lastName;
this.idNumber = idNumber;
}
// This function can be called from anywhere, including from outside of the class
public getInfo(): string {
return `Full name: The ${this.firstName} The ${this.lastName}, ID: The ${this.idNumber}`; }}// Creating a new instance of 'Person'
const person = new Person("John"."Smith".101);
// We can call this function here outside of the class because its accessibility is set to 'public'
var personInfo = person.getInfo(); // Result: Full name: John Smith, ID: 101
Copy the code
The generic
Generics in TypeScript allow you to create reusable components that use multiple data types instead of just one, reducing the amount of code you need to write and maintain.
Consider the following functions that perform the same logic but take different types of arguments:
// Returns the number value that was passed as an argument
function getNumber(someNumber: number) :number {
return someNumber;
}
// Returns the string value that was passed as an argument
function getString(someString: string) :string {
return someString;
}
var firstResult = getNumber(10); // Result: 10
var secondResult = getString("Hello"); // Result: Hello
Copy the code
Although the code above could be converted to a generic function using the any keyword, it would lose type safety because it would accept any data.
// Returns the value that was passed as an argument
function getValue(someValue: any) :any {
return someValue;
}
var firstResult = getValue(10); // Result: 10
// This wouldn't cause a compilation error since the function accepts any data, but could cause a runtime error if we attempt to perform an incompatible operation
var secondResult = getValue(someOtherObject);
Copy the code
By using generics, we can create a function that can take arguments of different data types while keeping it type-safe.
These generic type parameters are represented by the use of or T.
// Returns the value that was passed as an argument
// Works with multiple data types
function getValue<T> (someValue: T) :T{
return someValue;
}
// When calling the function we substitute <T> with the data type of the value we are passing in
var firstResult = getValue<number>(10); // Result: 10
var secondResult = getValue<string>("Hello"); // Result: Hello
// The compiler can also infer the data type of the argument and set the type of 'T' to match, so the following is also valid
var thirdResult = getValue("A string"); // Result: A string
Copy the code
A function can have more than one generic parameter:
// This function has multiple generic parameters and returns the value of the first argument passed
function someFunction<T.U.V> (firstValue: T, secondValue: U, thirdValue: V) :T{
return firstValue;
}
Copy the code
Classes can also be generic
// Create a class which
class GenericValue<T> {
private value: T;
constructor(value: T){
this.value = value;
}
public GetValue(): T{
return this.value; }}// Create a new 'GenericValue' instance with a number type
var numberObject = new GenericValue<number>(10);
var firstResult = numberValue.GetValue(); // Result: 10
// Create a new 'GenericValue' instance with a string type
var stringObject = new GenericValue<string>("Hello");
var secondResult = stringValue.GetValue(); // Result: Hello
Copy the code
TypeScript provides many other language features, which you can check out here