API Module
Pro features are only available with a Professional licence. To upgrade, visit cavalry.scenegroup.co.
Introduction
The following APIs are all in the api
namespace. They are ONLY available in the JavaScript Editor and not available when writing expressions in the JavaScript Layers.
All commands in this namespace must be prefixed with api.
e.g api.create("null", "My Null");
The API can communicate with the Web (see Web APIs) and execute shell commands. See runProcess below.
When working with Layers and Attributes it is important to know their layerId
and attrId
.
To find the layerId:
- Right click on a layer in the Viewport, Scene Window or its header bar in the Attribute Editor.
- Select
Copy Layer Id
.
This will copy the Layer's Id to the clipboard.
To find the attrId:
- Right click on an attribute in the Attribute Editor.
- Choose
Copy Scripting Path
from the contextual menu. - Select and click an option from the list.
This will copy the attribute's Id to the clipboard.
These Ids can then be used within a script. In the example below, basicShape#1 is the layerId
and position.x is the attrId
.
api.get("basicShape#1", "position.x");
Member Functions
Working with the Composition
setFrame(frame:int)
Move the playhead to a specific frame.
// Move the playhead to frame 100
api.setFrame(100);
getFrame() → int
Return the frame number the playhead is on.
// Move the playhead to frame 50 and then print that frame number to the Console.
api.setFrame(50);
console.log(api.getFrame());
play()
Start playback.
stop()
Stop playback (must be called from a UI Script).
getCompLayers(isTopLevel:bool) → [string]
var primId = api.primitive("polygon", "My Polygon");
var nullId = api.create("null", "My Null");
api.parent(primId, nullId);
// The boolean indicates top level layers only (ie. ignore all children)
var topLevelIds = api.getCompLayers(true);
// Prints: 1
console.log(topLevelIds.length)
// Get all the layers in the composition
var allIds = api.getCompLayers(false);
// Prints: 2
console.log(allIds.length)
getCompLayersOfType(isTopLevel:bool, type:string) → [string]
Return all the Layers in the active Composition of a certain type.
api.create("null", "My Null");
api.create("null", "My Other Null");
api.create("group", "My Folder");
api.create("spreadsheet", "My Spreadsheet");
let nulls = api.getCompLayersOfType(false, "null");
for (var layer of nulls) {
console.log(api.getNiceName(layer));
}
createTimeMarker(time:int) → string
Adds a new Time Marker. The second example sets up a Time Marker as a controller for a Scheduling Group.
let markerId = api.createTimeMarker(10);
api.set(markerId, {"label": "Hello, World", "drawColorId": 0, "useRelPlacement": true});
/// After running this script, move the Time Marker around
let rectId = api.primitive("rectangle", "My Rectangle");
let ellipseId = api.primitive("ellipse", "My Ellipse");
let scheduleGroup = api.create("schedulingGroup", "Marker Controlled Group");
api.parent(rectId, scheduleGroup);
api.parent(ellipseId, scheduleGroup);
let markerId = api.createTimeMarker(10);
api.set(markerId, {"label": "Hello, World", "drawColorId": 0, "useRelPlacement": true});
api.connect(markerId, "id", scheduleGroup, "childOffset");
getTimeMarkers() → [string]
Returns a list of all the Time Marker Ids in this Composition
api.createTimeMarker(10);
api.createTimeMarker(40);
var markers = api.getTimeMarkers();
for (let markerId of markers) {
console.log(markerId)
}
removeTimeMarker(markerId:string)
A convenience function for removing Time Markers. This forwards to api.Layer(layerId)
.
getNthBeat(beat:int) → int
Return the frame of the 'n'th beat from the Beat Marker settings. For example, an argument of 3 will return the frame number that the 3rd beat falls on.
const frame = api.getNthBeat(3);
console.log(frame);
addGuide(compId:string, isVertical:bool, position:int) → int
Add a Ruler Guide to the given Composition. This function returns an id which can be used to delete the Guide later. Note that 0,0 is the centre of the Composition.
let id = api.addGuide(api.getActiveComp(), false, 100);
console.log(id);
deleteGuide(compId:string, id:int)
Delete a Ruler Guide with the corresponding id from the given Composition.
let id = api.addGuide(api.getActiveComp(), false, 100);
console.log(id);
api.deleteGuide(api.getActiveComp(), 1);
// If you run this in a new scene, there should be no guides.
clearGuides(compId:string)
Clear all Ruler Guide from the given Composition.
api.addGuide(api.getActiveComp(), true, -100);
api.addGuide(api.getActiveComp(), false, 100);
api.clearGuides(api.getActiveComp());
// If you run this in a new scene, there should be no guides.
getGuideInfo(compId:string) → array[{id:int, direction:int, position:int}]
Get the Ids of all the Ruler Guides in the given Composition.
Direction returns:
- 0 for Horizontal Guides.
- 1 for Vertical Guides.
api.addGuide(api.getActiveComp(), true, -100);
api.addGuide(api.getActiveComp(), false, 100);
console.log(JSON.stringify(api.getGuideInfo(api.getActiveComp())));
getControlCentreAttributes(compId:string) → [string]
Get a list of all the Attributes that have been added to the Control Centre.
console.log(api.getControlCentreAttributes(api.getActiveComp()));
timecodeToFrames(timecode:string, fps:number) → int
Converts a given frame number into an equivalent timecode based on a given frame rate. Note that a timecode starts at frame 0 regardless of the Frame Range set in the Composition Settings.
console.log(api.timecodeToFrames("00:00:06:05",30));
framesToTimecode(frame:int, fps:number) → string
Converts a given timecode into an equivalent frame number based on a given frame rate. Note that a timecode starts at frame 0 regardless of the Frame Range set in the Composition Settings.
console.log(api.framesToTimecode(100,25));
Working with Layers
primitive(type:string, name:string) → string
Creates a Primitive Shape.
/// returns the layerId for the new shape
var primId = api.primitive("rectangle", "My Rectangle");
createEditable(path:Path, name:string) → string
Creates an Editable Shape from a Path.
var path = new cavalry.Path();
path.moveTo(0.,0.);
path.lineTo(0.,-100.);
path.lineTo(300.,-100.);
path.cubicTo(210., 110., 240., 140., 280., 260);
path.close();
api.createEditable(path, "My Path");
create(layerType:string, name:string, allowDefaultPreset=false) → string
Create a Layer of any type. The optional name
argument can be used to specify the name of the Layer in the Scene Window. The optional allowDefaultPreset
argument can be used to apply a Preset which is 'Set as Default Settings' in the Presets Manager.
api.create("null", "My Null", true);
deleteLayer(layerId:string)
Delete a Layer.
/// Delete all render queue items
var items = api.getRenderQueueItems();
for (var layer of items) {
api.deleteLayer(layer);
}
layerExists(layerId:string) → bool
Returns true
if a Layer with the given layerId
exists.
var layerId = api.create("basicShape","Layer")
console.log("Layer exists:" + api.layerExists(layerId) + ". Active Comp exists: " + api.layerExists(api.getActiveComp()));
getLayerType(layerId:string) → string
Get the layer's type (which can be used to create new instances of this layer).
var layerId = api.create("null", "My Null");
console.log(api.getLayerType(layerId));
resetLayerAttributes(layerId:string)
Reset all Attributes on a Layer back to the default state.
getSelection(sortByHierarchyOrder=false) → [string]
Gets the currently selected Layers from the Composition or Assets Window. When the optional sortByHierarchyOrder
argument is true
, the selection list is returned in hierarchy order, otherwise it's returned in selection order.
// Print the selected Layer's nice names to the console.
// Create some Layers and select them:
var sel = api.getSelection();
for (var layer of sel) {
console.log(api.getNiceName(layer));
}
select(layers:[string])
Sets the selected Layers.
var primId = api.primitive("rectangle", "My Rectangle");
api.select([primId]);
invertSelection()
Deselect any selected Layers and select any deselected Layers.
var rect1 = api.primitive("rectangle", "Selected");
var rect2 = api.primitive("rectangle", "Not Selected");
api.select([rect2]);
api.invertSelection();
duplicate(layerId:string, withInputConnections:bool);
Duplicate a Layer with an option to also duplicate any input connections.
getChildren(layerId:string) → [string]
Gets the children of the specified Layer.
var primId = api.primitive("polygon", "My Polygon");
var nullId = api.create("null", "My Null");
api.parent(primId, nullId);
var childIds = api.getChildren(nullId);
console.log(childIds.length)
parent(layerId:string, newParentId:string)
Make one Layer the child of another.
var primId = api.primitive("polygon", "My Polygon");
var nullId = api.create("null", "My Null");
api.parent(primId, nullId);
unParent(layerId:string)
Move a Layer up one level of hierarchy to its parent's parent. This is the equivalent of the Un-Parent context menu item available in the Scene Tree.
// Given basicShape#1 is the child of another Layer...
api.unParent("basicShape#1");
getParent(layerId:string) → string
Return the layerId of a Layer's parent.
var primId = api.primitive("polygon", "My Polygon");
var nullId = api.create("null", "My Null");
api.parent(primId, nullId);
console.log(api.getParent(primId));
getNiceName(layerId:string) → string
Return the 'nice name' of a Layer.
var nullId = api.create("null", "My Null");
console.log(api.getNiceName(nullId));
rename(layerId:string, name:string)
Rename a Layer.
/// rename all selected items
var sel = api.getSelection();
sel.forEach(function (item, index) {
api.rename(item, "My Name "+index);
});
offsetLayerTime(layerId:string, delta:int)
Offset a Layer's Visibility Clip and any related animation in time.
const layerId = api.primitive("rectangle", "Rectangle");
api.setOutFrame(layerId, 50);
api.offsetLayerTime(layerId, 100);
setStroke(layerId:string, isOn:bool)
Enable/disable the Stroke for a Shape.
var primId = api.primitive("rectangle", "Rectangle");
api.setFill(primId, false);
api.setStroke(primId, true);
api.set(primId, {"stroke.strokeColor": "#049dd9", "stroke.width": 20});
hasStroke(layerId:string) → bool
Returns true
if a Shape has a Stroke.
var primId = api.primitive("rectangle", "Rectangle");
api.setStroke(primId, true);
console.log(api.hasStroke(primId));
setFill(layerId:string, isOn:bool)
Enable/disable the Fill for a Shape.
var primId = api.primitive("rectangle", "Rectangle");
api.setFill(primId, false);
api.setStroke(primId, true);
hasFill(layerId:string) → bool
Returns true
if a Shape has a Fill.
var primId = api.primitive("rectangle", "Rectangle");
console.log(api.hasFill(primId));
getBoundingBox(layerId:string, worldSpace:bool) → {x:number, y:number, width:number, height:number, centre:{x:number, y:number}, left:number, right:number, top:number, bottom:number}
Return the bounding box of the specified Layer.
var primId = api.primitive("polygon", "My Polygon");
var bbox = api.getBoundingBox(primId, true);
console.log(JSON.stringify(bbox));
getSelectionBoundingBox() → {x:number, y:number, width:number, height:number, centre:{x:number, y:number}, left:number, right:number, top:number, bottom:number}
Return the world space bounding box of the selected Layers.
const shape1 = api.create("basicShape");
api.set(shape1, {"position": [450, -120]});
const shape2 = api.create("basicShape");
api.set(shape2, {"position": [-100, 210]});
api.select([shape1, shape2]);
let bbox = api.getSelectionBoundingBox();
console.log(JSON.stringify(bbox));
isVisible(layerId:string, includeHierarchy:bool) → bool
Determines if a Layer is visible in the Viewport. This considers the Layer's 'Hidden' attribute and the state of the Layer's Visibility Clip at the current frame. When the includeHierarchy argument is true
, if the Layer is the child of another Layer, the visibility of that Layer (and its parent's and so on) is also considered.
const layerId = api.create("basicShape");
console.log(api.isVisible(layerId, false));
isTransform(layerId:string) → bool
Returns true if a specified Layer has transform Attributes (e.g. Position and Scale).
has3dTransforms(layerId:string) → bool
Returns true if a specified Layer has its 3d transform Attributes activated.
getInFrame(layerId:string) → int
Return the first frame of a visibility clip.
var sel = api.getSelection();
for (let layerId of sel) {
console.log(api.getInFrame(layerId));
}
setInFrame(layerId:string, frame:int)
Set the first frame of a visibility clip.
const layerId = api.primitive("rectangle", "Rectangle");
api.setInFrame(layerId, 50);
getOutFrame(layerId:string) → int
Return the last frame of a visibility clip.
var sel = api.getSelection();
for (let layerId of sel) {
console.log(api.getOutFrame(layerId));
}
setOutFrame(layerId:string, frame:int)
Set the last frame of a visibility clip.
const layerId = api.primitive("rectangle", "Rectangle");
api.setOutFrame(layerId, 50);
getInOutKeyframeIds(layerId:string) → [object]
Returns an array of objects containing the keyframe ids of all the in and out points for a Layer.
const layer1 = api.create("basicShape");
const keyIds = api.getInOutKeyframeIds(layer1);
console.log(JSON.stringify(keyIds));
getActiveCamera() → string
Return the active Camera's Layer Id. A Camera is considered 'active' when its visibility is on at the current frame. Where more than one Camera is visible on the same frame, the Camera highest in the hierarchy is considered the active one.
api.create("planarCamera");
console.log(api.getActiveCamera());
hasActiveCamera() → bool
Return whether there is an active Camera in the active Composition. A Camera is considered 'active' when its visibility is on at the current frame.
console.log(api.hasActiveCamera());
bringForward()
Move the selected Layers up the layer stack by one place.
const shape1 = api.create("basicShape", "Shape1");
const shape2 = api.create("basicShape", "Shape2");
api.select([shape1]);
api.bringForward();
bringToFront()
Move the selected Layers to the top of the layer stack.
const shape1 = api.create("basicShape", "Shape1");
const shape2 = api.create("basicShape", "Shape2");
const shape3 = api.create("basicShape", "Shape3");
api.select([shape1]);
api.bringToFront();
moveBackward()
Move the selected Layers down the layer stack by one place.
const shape1 = api.create("basicShape", "Shape1");
const shape2 = api.create("basicShape", "Shape2");
api.select([shape2]);
api.moveBackward();
moveToBack()
Move the selected Layers to the bottom of the layer stack.
const shape1 = api.create("basicShape", "Shape1");
const shape2 = api.create("basicShape", "Shape2");
const shape3 = api.create("basicShape", "Shape3");
api.select([shape3]);
api.moveToBack();
isShape(layerId:string) → bool
Checks if a specified Layer is a Shape.
const shape1 = api.primitive("ellipse", "Ellipse");
console.log(api.isShape(shape1));
editComponent(layerId:string, editingMode:bool)
Sets the editing mode for a Component.
// Collapse a Component containing an Ellipse.
const ellipseId = api.primitive("ellipse", "Ellipse");
const componentId = api.create("component");
api.connect(ellipseId, "position", componentId, "promotedAttributes");
api.parent(ellipseId, componentId);
api.editComponent(componentId, false);
sortLayerIdsByHierarchy(layerIds:[String]) → [String]
Returns the Ids of the given Layers in the order they appear in the hierarchy.
const cId = api.primitive("circle", "Circle (Bottom)");
const rId = api.primitive("rectangle", "Rectangle (Middle)");
const pId = api.primitive("polygon", "Polygon (Top)");
const layerIds = [rId, pId, cId];
const ordered = api.sortLayerIdsByHierarchy(layerIds);
for (const layerId of ordered) {
console.log(api.getNiceName(layerId));
}
reorder(layerIdToReorder:string, underLayerId:string)
Reorder Layers in the hierarchy, re-parenting if required.
const cId = api.primitive("circle", "Circle");
const rId = api.primitive("rectangle", "Rectangle");
const pId = api.primitive("polygon", "Polygon");
const sId = api.primitive("star", "Star");
// Make the Circle and Star children of the Rectangle.
api.parent(sId, rId);
api.parent(cId, rId);
// Reorder the Polygon to be below the Circle and so automatically a child of the Rectangle.
api.reorder(pId, cId);
api.rename(pId, "Polygon - Reordered");
Working with Attributes
getSelectedAttributes() → [object]
This will return an array containing the paths of the selected attributes.
var selAttr = api.getSelectedAttributes();
for (const [layerId, attr] of selAttr) {
console.log(layerId+"."+attr);
}
set(layerId:string, arguments:object)
Set values for a Layer's attributes.
// Create a Rectangle and set its Size, Position, Rotation and Fill Color
var primId = api.primitive("rectangle", "My Rectangle");
api.set(primId, {"generator.dimensions":[100,370], "position": [100, 200], "rotation": 50, "material.materialColor": "#8dc429"});
// Create a Text Shape and set its Font Family and Style
var textId = api.create("textShape", "My Text");
api.set(textId, {"font":{"font":"Arial", "style":"Bold"}});
// Collapse the hierarchy of a layer
api.set("basicShape#1", {"hierarchy": false});
get(layerId:string, attrId:string) → object/value
Get the values for a Layer's attributes.
var primId = api.primitive("rectangle", "My Rectangle");
api.set(primId, {"material.materialColor": "#8dc429", "generator.dimensions":[100,370], "rotation": 50, "position": [100, 200]});
var obj = api.get(primId, "position");
console.log(JSON.stringify(obj))
getAttributeDefinition(layerId:string, attrId:string) → object
Returns an object containing detailed information about an Attribute.
var shapeId = api.create("basicShape");
const definition = api.getAttributeDefinition(shapeId, "motionBlur");
console.log(definition.type);
The returned object contains keys for:
attrId
// the attribute's Idtype
// e.g double, string, int2prefix
// the prefix used in the UIplaceholder
// a string attribute's placeholder (e.g. A Stroke's Dash Pattern containsDash, Gap (e.g. “4, 2“)
)isAttrReadOnly
// true if the attribute is read onlyallowsAspectRatioLocking
// the attribute's proportions can be constrainednumericInfo
// an object where any of the child keys can be nullhardMin
// the minimum value allowedhardMax
// the maximum value allowedsoftMin
// the minimum value that can be set by scrubbing in the UIsoftMax
// the maximum value that can be set by scrubbing in the UIstep
// the increment values increase/decrease when scrubbingisBound
// this checks if hardMin and hardMax exist. i.e. the attributeis a slider
multiline
// true if the attribute is a multi-line stringenumValues
// the valid indices for dropdown attributeschildren
// child attribute definitions (for example position attributes have three children, x, y and z).isArray
// true if the attribute is an arrayisCompound
// true if the attribute is a compound (for example a point within a Graph attribute)isDynamic
// true if this attribute is a dynamic attributes (for example the array that contains uniforms in a JavaScript Layer)
setGenerator(layerId:string, attrId:string, type:string)
Some Layers in Cavalry contain Generators, these are discrete feature blocks that are used to extend the functionality of Layers. For example the Basic Shape Layer has a Generator to determine the shape it creates (e.g Ellipse, Rectangle...). Generators can be set with this function.
// Create an Ellipse and set it up
var ellipseId = api.primitive("ellipse", "Ellipse");
api.set(ellipseId, {"generator.radius.x": 10, "generator.radius.y": 10, "hidden": true});
// Create a Duplicator
var duplicatorId = api.create("duplicator", "Duplicator");
// Connect the Ellipse to the Duplicator
api.connect(ellipseId, "id", duplicatorId, "shapes");
// Change the Distribution on the Duplicator to a Custom Distribution
api.setGenerator(duplicatorId, "generator", "circleDistribution");
// Set the Distribution count
api.set(duplicatorId, {"generator.count": 10});
getCurrentGenerator(layerId:string, attrId:string) → string
Returns the generatorId for an attribute on a Layer or empty if there isn't one.
var duplicatorId = api.create("duplicator", "Duplicator");
console.log(api.getCurrentGenerator(duplicatorId, "generator"));
getGenerators(layerId:string) → [string]
Some Layers in Cavalry contain Generators, these are discrete feature blocks that are used to extend the functionality of Layers. For example the Basic Shape Layer has a Generator to determine the shape it creates (e.g Ellipse, Rectangle). Generators on a Layer can be listed with this command.
var layerId = api.create("connectShape", "Connect Shape");
var generatorId = api.getGenerators(layerId);
for (gId of generatorId) {
console.log(gId);
}
getCurrentGeneratorType(layerId:string, attrId:string) → string
Returns the current Generator type (which can be used with setGenerator
).
var ellipseId = api.primitive("ellipse", "My Ellipse")
console.log(api.getCurrentGeneratorType(ellipseId, "generator"))
setAttributeExpression(layerId:string, attrId:string, expression:string)
Set an attribute expression, this will take whatever the input value is in the expression, and manipulate it in some way (multiply, add to it etc.).
var rectId = api.primitive("rectangle", "My Rectangle");
api.set(rectId, {"position.x": 300});
var starId = api.primitive("star", "Star");
api.set(starId, {"position.x": -300});
// Connect the result of the Star to the Rectangle
api.connect(starId, "position.y", rectId, "position.y");
// Add an attribute expression
api.setAttributeExpression(rectId, "position.y", "*2");
//api.setAttributeExpression(rectId, "position.y", "%50");
//api.setAttributeExpression(rectId, "position.y", "clamp(-45, value, 45)");
//api.setAttributeExpression(rectId, "position.y", "sqrt(value)");
// Power the stars movement with an Oscillator
var oscillatorId = api.create("oscillator", "Oscillator");
api.set(oscillatorId, {"strength": 1500});
api.connect(oscillatorId, "id", starId, "position.y");
api.play();
hasAttributeExpression(layerId:string, attrId:string) → bool
Returns true if the given attribute has an Attribute Expression.
var rectId = api.primitive("rectangle", "Rectangle");
api.connect(rectId, "position.x", rectId, "position.y");
api.setAttributeExpression(rectId, "position.y", "*2");
console.log(api.hasAttributeExpression(rectId, "position.y"));
getAttributeExpression(layerId:string, attrId:string) → string
Returns an Attribute's Attribute Expression.
var rectId = api.primitive("rectangle", "Rectangle");
api.connect(rectId, "position.x", rectId, "position.y");
api.setAttributeExpression(rectId, "position.y", "*2");
console.log(api.getAttributeExpression(rectId, "position.y"));
connect(fromLayerId:string, fromAttrId:string, toLayerId:string, toAttrId:string, force:bool)
Connect one attribute to another. The result or output of a Layer is referred to as the id
connection. Optionally forcing a connection will overwrite any existing connections.
var starId = api.primitive("star", "Star");
var ellipseId = api.primitive("ellipse", "Ellipse");
var pathfinderId = api.create("pathfinder", "Pathfinder");
api.set(starId, {"generator.radius": 300});
api.set(ellipseId, {"generator.radius": [50,50], "material.materialColor": "#4ffd7a"});
// Connect the result of the Star to the Pathfinder
api.connect(starId, "id", pathfinderId, "inputShape");
// Connect the result of the Pathfinder to the Text.Position
api.connect(pathfinderId, "id", ellipseId, "position");
let fillId = api.create("colorMaterial");
api.set(fillId, {"materialColor": "#6437ff"});
// Connect the Fill to the Star and overwrite the default Fill.
api.connect(fillId, "id", starId, "material", true);
disconnect(fromLayerId:string, fromAttrId:string, toLayerId:string, toAttrId:string)
Remove connections between attributes.
var primId = api.primitive("rectangle", "Rectangle");
var oscillatorId = api.create("oscillator", "Oscillator");
api.connect(oscillatorId, "id", primId, "rotation");
console.log(api.getInConnection(primId, "rotation"));
api.disconnect(oscillatorId, "id", primId, "rotation");
console.log(api.getInConnection(primId, "rotation"));
disconnectInput(layerId:string, attrId:string)
Disconnect an Attribute's input connection.
api.disconnectInput("basicShape#1", "position.x");
disconnectOutputs(layerId:string, attrId:string)
Disconnect all the output connections from an Attribute.
api.disconnectOutputs("basicShape#1", "position.x");
getInConnection(layerId:string, attrId:string) → string
Returns the input connection to an Attribute. An empty string is returned if there's no input on the Attribute in question.
var primId = api.primitive("rectangle", "Rectangle");
var oscillatorId = api.create("oscillator", "Oscillator");
api.connect(oscillatorId, "id", primId, "rotation");
console.log(api.getInConnection(primId, "rotation"));
getOutConnections(layerId:string, attrId:string) → [string]
Returns all the output connections from an Attribute.
var primId = api.primitive("rectangle", "Rectangle");
var oscillatorId = api.create("oscillator", "Oscillator");
api.connect(oscillatorId, "id", primId, "rotation");
console.log(api.getOutConnections(oscillatorId, "id"));
getSelectedKeyframes() → object
This returns the selected keyframes as an enumerable string-keyed object. Each string is an attribute path, and each key is an array of frame numbers on which a keyframe resides.
let selKeys = api.getSelectedKeyframes();
for (const [key, value] of Object.entries(selKeys)) {
console.log(key+": "+value);
}
keyframe(layerId:string, frame:int, {object}) → string
Set keyframes for Layers and return the keyframeId.
const primId = api.primitive("rectangle", "My Rectangle");
const kfId1 = api.keyframe(primId, 0, {"scale.x": 5.});
console.log(kfId1);
const kfId2 = api.keyframe(primId, 100, {"scale.x": 1.});
console.log(kfId2);
// 1. Draw a Path with the Pencil tool.
// 2. Set a Path keyframe at frame 0.
// 3. Move to frame 50.
// 4. Move some points with the Edit Shape tool to set a second Path keyframe.
// 5. Run script:
const layerId = 'editableShape#1';
const keyData = api.get("keyframe#3", 'data');
console.log(JSON.stringify(keyData))
api.keyframe(layerId, 100, {"inputPath": keyData["pathValue"]});
deleteKeyframe(layerId:string, attrId:string, frame:int)
Remove a Layer's keyframes.
var primId = api.primitive("rectangle", "My Rectangle");
api.keyframe(primId, 0, {"scale.x": 5.});
api.keyframe(primId, 50, {"scale.x": 7.});
api.keyframe(primId, 100, {"scale.x": 1.});
api.deleteKeyframe(primId, "scale.x", 50);
modifyKeyframe(layerId:string, data:object)
Modify the keyframe time (frame number) or value.
The supplied object must include a frame
key, in addition to this it can also include:
newFrame
// Specify a new frame for the keyframe (optional).newValue
// Specify a new value for the keyframe (optional).type
// The keyframe type as an integer0
Bezier,1
Linear,2
Step (optional).
Example of modifying keyframe values and frames:
var primId = api.primitive("rectangle", "My Rectangle");
api.keyframe(primId, 0, {"scale.x": 5.});
api.keyframe(primId, 100, {"scale.x": 1.});
api.modifyKeyframe(primId, {"scale.x": {"frame": 0, "newValue": 3.5, "newFrame": 10}});
Example of setting all keyframes to step interpolation.
let ellipseId = api.primitive("ellipse", "Ellipse");
// Create some values to set as keyframes
let keyValues = [-200,200,-300, 300]
let keyTime = 0;
// Set some keyframes for us to modify
for (let value of keyValues) {
api.keyframe(ellipseId, keyTime, {"position.x":value});
keyTime+=40;
}
// Get the keyframe times
let times = api.getKeyframeTimes("basicShape#1","position.x")
for (let frame of times) {
// Set the keyframes to step interpolation
api.modifyKeyframe(ellipseId, {"position.x":{"frame": frame, "type":2}});
}
modifyKeyframeTangent(layerId:string, data:object)
Modify the keyframe tangents.
The supplied object must include a frame
key.
Both the in and out handle will be affected unless a handle is specified and the handle is not weight and angle locked.
inHandle
// An optional boolean value used to specify the inHandle to be affected.outHandle
// An optional boolean value used to specify the outHandle to be affected.angleLocked
// Boolean stating if the key tangents are angle locked or not (optional).weightLocked
// Boolean stating if the key tangents are weight locked or not (optional).angle
// Set a new angle for the keyframe tangent, 0 is flat (optional).weight
// Set a new weight for the keyframe tangent (optional).
Example setting flat keyframes:
// Make a new ellipse
let ellipseId = api.primitive("ellipse", "Ellipse");
// Create some values to set as keyframes
let keyValues = [-200,200,-300, 300]
let keyTime = 0;
// Set some keyframes for us to modify
for (let value of keyValues) {
api.keyframe(ellipseId, keyTime, {"position.x":value});
keyTime+=40;
}
// Get the keyframe times
let times = api.getKeyframeTimes(ellipseId,"position.x")
for (let frame of times) {
// Modify the tangents, giving them all a weight of 20 and an angle of 0 (flat)
api.modifyKeyframeTangent(ellipseId, {"position.x":{"angle":0, "frame": frame, "weight":20}});
}
Example breaking tangents and weighting the outHandles.
// Create a Shape
let ellipseId = api.primitive("ellipse", "Ellipse");
// Store some values to set as keyframes
let keyValues = [-200,200,-300, 300]
let keyTime = 0;
// Set some keyframes to modify
for (let value of keyValues) {
api.keyframe(ellipseId, keyTime, {"position.x":value});
keyTime+=40;
}
// Get the keyframe times
let times = api.getKeyframeTimes(ellipseId, "position.x")
for (let frame of times) {
// Set the handle weights to 0
api.modifyKeyframeTangent(ellipseId, {"position.x":{"frame": frame, "weight":0}});
// Set the weight for only the out handles
api.modifyKeyframeTangent(ellipseId, {"position.x":{"frame": frame, "weight":20, "outHandle": true, "weightLocked": false}});
}
getKeyframeIdsForAttribute(layerId:string, attrId:string)
Get all keyframeIds for a particular layerId's attribute. This can be used in combination with setUserData.
var primId = api.primitive("rectangle", "My Rectangle");
api.keyframe(primId, 0, {"position.x": 10});
console.log(api.getKeyframeIdsForAttribute(primId, "position.x"));
getSelectedKeyframeIds() → [string]
Get the ids for selected keyframes. This can be used in combination with setUserData.
// Create a Shape, add some keyframes and then select them before running:
console.log(api.getSelectedKeyframeIds());
setSelectedKeyframeIds(keyframeIds:[string])
Set the keyframe selection. To clear the keyframe selection send an empty array through.
// Create a Shape and add some keyframes to scale.x
var primId = api.primitive("rectangle", "My Rectangle");
api.keyframe(primId, 0, {"scale.x": 4.});
api.keyframe(primId, 50, {"scale.x": 3.});
api.keyframe(primId, 100, {"scale.x": 1.});
//console.log(api.getKeyframeIdsForAttribute(primId, "scale.x"));
// Select the first and third keyframes (uncomment above to return keyframeIds)
api.setSelectedKeyframeIds(["keyframe#3", "keyframe#5"]);
getAttributeFromKeyframeId(keyframeId:string) → string
Get the attribute path for a given keyframe.
const keyIds = api.getSelectedKeyframeIds();
for (const keyId of keyIds) {
console.log(api.getAttributeFromKeyframeId(keyId))
}
magicEasing(layerId:string, attrId:string, frame:int, easingName:string)
Apply Magic Easing to a new or existing keyframe.
api.magicEasing("basicShape#1", "position.x", 25, "SlowIn");
Valid Magic Easing names are:
- "SlowIn"
- "SlowOut"
- "SlowInSlowOut"
- "VerySlowIn"
- "VerySlowOut"
- "VerySlowInVerySlowOut"
- "SpringIn"
- "SpringOut"
- "SpringInSpringOut"
- "SmallSpringIn"
- "SmallSpringOut"
- "SmallSpringInSmallSpringOut"
- "AnticipateIn"
- "OvershootOut"
- "AnticipateInOvershootOut"
- "BounceIn"
- "BounceOut"
- "BounceInBounceOut"
getKeyframeTimes(layerId:string, attrId:string)
deleteAnimation(layerId:string, attrId:string)
Delete all keyframes on an attribute.
getAttrType(layerId:string, attrId:string) → string
Get the data type of the Attribute
var layerId = api.create("javaScript", "JS Layer");
api.addDynamic(layerId, "array", "string");
console.log(api.getAttrType(layerId, "array.1"));
resetAttribute(layerId:string, attrId:string)
Reset an Attribute back to its default value.
addArrayIndex(layerId:string, attrId:string) → int
Add a new child to an array Attribute.
var arrayId = api.create("valueArray", "My Value Array");
api.addArrayIndex(arrayId, "array")
api.addArrayIndex(arrayId, "array")
api.set(arrayId, {"array.0": 10, "array.1": 20, "array.2": 30});
removeArrayIndex(layerId:string, attrId:string)
Remove an Attribute from an array
getArrayCount(layerId:string, attrId:string) → int
Return the number of Attributes in the array
var arrayId = api.create("valueArray", "My Value Array");
api.addArrayIndex(arrayId, "array")
api.addArrayIndex(arrayId, "array")
console.log(api.getArrayCount(arrayId, "array"));
addDynamic(layerId:string, attrId:string, type:string)
Add a dynamic attribute to a Layer. Dynamic attributes are a special kind of Array Attribute in that they can be of different types. Only certain special Layers can have dynamic attributes added to them, for example the JavaScript Utility. Once added, these attributes can be renamed by using renameAttribute or removed by using removeArrayIndex. The name of the attribute is used in the JavaScript execution, and in the UI, but getting and setting these attributes is done by index (e.g. array.0) and not by the Attribute name.
var layerId = api.create("javaScript", "JS Layer");
api.addDynamic(layerId, "array", "double");
api.addDynamic(layerId, "array", "bool");
api.addDynamic(layerId, "array", "string");
api.addDynamic(layerId, "array", "int2");
api.addDynamic(layerId, "array", "double2");
api.addDynamic(layerId, "array", "color");
/// an example of setting and getting a Dynamic Attribute
var layerId = api.create("javaScript", "JS Layer");
api.addDynamic(layerId, "array", "double");
api.set(layerId, {"array.1": 10});
var value = api.get(layerId, "array.1");
console.log(value);
getCustomAttributeName(layerId:string, attrId:string) → string
Return the nice name for Dynamic or Array Attributes.
var arrayId = api.create("valueArray", "My Value Array");
api.renameAttribute(arrayId, "array.0", "Example Name");
console.log(api.getCustomAttributeName(arrayId, "array.0"));
hasCustomAttributeName(layerId:string, attrId:string) → bool
Returns true if the specified attribute has a custom name.
var shapeId = api.create("basicShape");
api.renameAttribute(shapeId, "position", "Example Name");
console.log(api.hasCustomAttributeName(shapeId, "position"));
getAttrParent(layerId:string, attrId:string) → string
Return the Id of the parent attribute. If there is no parent attribute, an empty string is returned.
let shapeId = api.create("basicShape");
let parentAttrId = api.getAttrParent(shapeId, "position.x");
console.log(parentAttrId);