Introduction [](/content/docs/tech-info/scripting/api-module/#introduction "Direct link to Introduction"/index.html)
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.
tip
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 Pathfrom 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 [](/content/docs/tech-info/scripting/api-module/#member-functions "Direct link to Member Functions"/index.html)
Working with the Composition [](/content/docs/tech-info/scripting/api-module/#working-with-the-composition "Direct link to Working with the Composition"/index.html)
setFrame(frame:int) [](/content/docs/tech-info/scripting/api-module/#setframe "Direct link to setframe"/index.html)
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] [](/content/docs/tech-info/scripting/api-module/#getcomplayers "Direct link to getcomplayers"/index.html)
Returns all Layer Ids from the active Composition with an option to filter for 'top level' Layers.
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] [](/content/docs/tech-info/scripting/api-module/#getcomplayersoftype "Direct link to getcomplayersoftype"/index.html)
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");
var nulls = api.getCompLayersOfType(false, "null");
for (var layer of nulls) {
console.log(api.getNiceName(layer));
}
getParentComp(layerId:string) → string [](/content/docs/tech-info/scripting/api-module/#getparentcomp "Direct link to getparentcomp"/index.html)
Return the Id of a given Layer's parent Composition.
var shapeId = api.create("basicShape");
console.log(api.getParentComp(shapeId));
createTimeMarker(time:int) → string [](/content/docs/tech-info/scripting/api-module/#createtimemarker "Direct link to createtimemarker"/index.html)
Adds a new Time Marker. The second example sets up a Time Marker as a controller for a Scheduling Group.
var markerId = api.createTimeMarker(10);
api.set(markerId, {"label": "Hello, World", "drawColorId": 0, "useRelPlacement": true});
/// After running this script, move the Time Marker around
var rectId = api.primitive("rectangle", "My Rectangle");
var ellipseId = api.primitive("ellipse", "My Ellipse");
var scheduleGroup = api.create("schedulingGroup", "Marker Controlled Group");
api.parent(rectId, scheduleGroup);
api.parent(ellipseId, scheduleGroup);
var 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) [](/content/docs/tech-info/scripting/api-module/#removetimemarker "Direct link to removetimemarker"/index.html)
A convenience function for removing Time Markers. This forwards to api.Layer(layerId).
getNthBeat(beat:int) → int [](/content/docs/tech-info/scripting/api-module/#getnthbeat "Direct link to getnthbeat"/index.html)
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.
var frame = api.getNthBeat(3);
console.log(frame);
addGuide(compId:string, isVertical:bool, position:int) → int [](/content/docs/tech-info/scripting/api-module/#addguide "Direct link to addguide"/index.html)
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.
var id = api.addGuide(api.getActiveComp(), false, 100);
console.log(id);
deleteGuide(compId:string, id:int) [](/content/docs/tech-info/scripting/api-module/#deleteguide "Direct link to deleteguide"/index.html)
Delete a Ruler Guide with the corresponding id from the given Composition.
var 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) [](/content/docs/tech-info/scripting/api-module/#clearguides "Direct link to clearguides"/index.html)
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}] [](/content/docs/tech-info/scripting/api-module/#getguideinfo "Direct link to getguideinfo"/index.html)
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] [](/content/docs/tech-info/scripting/api-module/#getcontrolcentreattributes "Direct link to getcontrolcentreattributes"/index.html)
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 [](/content/docs/tech-info/scripting/api-module/#timecodetoframes "Direct link to timecodetoframes"/index.html)
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 [](/content/docs/tech-info/scripting/api-module/#framestotimecode "Direct link to framestotimecode"/index.html)
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 [](/content/docs/tech-info/scripting/api-module/#working-with-layers "Direct link to Working with Layers"/index.html)
primitive(type:string, name:string) → string [](/content/docs/tech-info/scripting/api-module/#primitive "Direct link to primitive"/index.html)
Creates a Primitive Shape.
/// returns the layerId for the new shape
var primId = api.primitive("rectangle", "My Rectangle");
createEditable(path:Path, name:string) → string [](/content/docs/tech-info/scripting/api-module/#createeditable "Direct link to createeditable"/index.html)
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 [](/content/docs/tech-info/scripting/api-module/#create "Direct link to create"/index.html)
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) [](/content/docs/tech-info/scripting/api-module/#deletelayer "Direct link to deletelayer"/index.html)
Delete a Layer.
/// Delete all render queue items
var items = api.getRenderQueueItems();
for (var layer of items) {
api.deleteLayer(layer);
}
layerExists(layerId:string) → bool [](/content/docs/tech-info/scripting/api-module/#layerexists "Direct link to layerexists"/index.html)
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 [](/content/docs/tech-info/scripting/api-module/#getlayertype "Direct link to getlayertype"/index.html)
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));
isThirdPartyLayer(layerId:string) → bool [](/content/docs/tech-info/scripting/api-module/#isthirdpartylayer "Direct link to isthirdpartylayer"/index.html)
Returns true if the given Layer is from an external developer.
resetLayerAttributes(layerId:string) [](/content/docs/tech-info/scripting/api-module/#resetlayerattributes "Direct link to resetlayerattributes"/index.html)
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])
Selects the specified 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); [](/content/docs/tech-info/scripting/api-module/#duplicate "Direct link to duplicate"/index.html)
Duplicate a Layer with an option to also duplicate any input connections.
getChildren(layerId:string) → [string] [](/content/docs/tech-info/scripting/api-module/#getchildren "Direct link to getchildren"/index.html)
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) [](/content/docs/tech-info/scripting/api-module/#parent "Direct link to parent"/index.html)
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) [](/content/docs/tech-info/scripting/api-module/#unparent "Direct link to unparent"/index.html)
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 [](/content/docs/tech-info/scripting/api-module/#getparent "Direct link to getparent"/index.html)
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 [](/content/docs/tech-info/scripting/api-module/#getnicename "Direct link to getnicename"/index.html)
Return the 'nice name' of a Layer.
var nullId = api.create("null", "My Null");
console.log(api.getNiceName(nullId));
rename(layerId:string, name:string) [](/content/docs/tech-info/scripting/api-module/#rename "Direct link to rename"/index.html)
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) [](/content/docs/tech-info/scripting/api-module/#offsetlayertime "Direct link to offsetlayertime"/index.html)
Offset a Layer's Clip and any related animation in time.
var layerId = api.primitive("rectangle", "Rectangle");
api.setOutFrame(layerId, 50);
api.offsetLayerTime(layerId, 100);
setStroke(layerId:string, isOn:bool) [](/content/docs/tech-info/scripting/api-module/#setstroke "Direct link to setstroke"/index.html)
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 [](/content/docs/tech-info/scripting/api-module/#hasstroke "Direct link to hasstroke"/index.html)
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) [](/content/docs/tech-info/scripting/api-module/#setfill "Direct link to setfill"/index.html)
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 [](/content/docs/tech-info/scripting/api-module/#hasfill "Direct link to hasfill"/index.html)
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} [](/content/docs/tech-info/scripting/api-module/#getboundingbox "Direct link to getboundingbox"/index.html)
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} [](/content/docs/tech-info/scripting/api-module/#getselectionboundingbox "Direct link to getselectionboundingbox"/index.html)
Return the world space bounding box of the selected Layers.
var shape1 = api.create("basicShape");
api.set(shape1, {"position": [450, -120]});
var shape2 = api.create("basicShape");
api.set(shape2, {"position": [-100, 210]});
api.select([shape1, shape2]);
var bbox = api.getSelectionBoundingBox();
console.log(JSON.stringify(bbox));
isVisible(layerId:string, includeHierarchy:bool) → bool [](/content/docs/tech-info/scripting/api-module/#isvisible "Direct link to isvisible"/index.html)
Determines if a Layer is visible in the Viewport. This considers the Layer's 'Hidden' attribute and the state of the Layer's 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.
var layerId = api.create("basicShape");
console.log(api.isVisible(layerId, false));
isTransform(layerId:string) → bool [](/content/docs/tech-info/scripting/api-module/#istransform "Direct link to istransform"/index.html)
Returns true if a specified Layer has transform Attributes (e.g. Position and Scale).
has3dTransforms(layerId:string) → bool [](/content/docs/tech-info/scripting/api-module/#has3dtransforms "Direct link to has3dtransforms"/index.html)
Returns true if a specified Layer has its 3d transform Attributes activated.
getInFrame(layerId:string) → int [](/content/docs/tech-info/scripting/api-module/#getinframe "Direct link to getinframe"/index.html)
Return the first frame of a Clip.
var sel = api.getSelection();
for (let layerId of sel) {
console.log(api.getInFrame(layerId));
}
setInFrame(layerId:string, frame:int) [](/content/docs/tech-info/scripting/api-module/#setinframe "Direct link to setinframe"/index.html)
Set the first frame of a Clip.
var layerId = api.primitive("rectangle", "Rectangle");
api.setInFrame(layerId, 50);
getOutFrame(layerId:string) → int [](/content/docs/tech-info/scripting/api-module/#getoutframe "Direct link to getoutframe"/index.html)
Return the last frame of a Clip.
var sel = api.getSelection();
for (let layerId of sel) {
console.log(api.getOutFrame(layerId));
}
setOutFrame(layerId:string, frame:int) [](/content/docs/tech-info/scripting/api-module/#setoutframe "Direct link to setoutframe"/index.html)
Set the last frame of a Clip.
var layerId = api.primitive("rectangle", "Rectangle");
api.setOutFrame(layerId, 50);
getInOutKeyframeIds(layerId:string) → [object] [](/content/docs/tech-info/scripting/api-module/#getinoutkeyframeids "Direct link to getinoutkeyframeids"/index.html)
Returns an array of objects containing the keyframe ids of all the in and out points for a Layer.
var layer1 = api.create("basicShape");
var 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.
var shape1 = api.create("basicShape", "Shape1");
var shape2 = api.create("basicShape", "Shape2");
api.select([shape1]);
api.bringForward();
bringToFront()
Move the selected Layers to the top of the layer stack.
var shape1 = api.create("basicShape", "Shape1");
var shape2 = api.create("basicShape", "Shape2");
var shape3 = api.create("basicShape", "Shape3");
api.select([shape1]);
api.bringToFront();
moveBackward()
Move the selected Layers down the layer stack by one place.
var shape1 = api.create("basicShape", "Shape1");
var shape2 = api.create("basicShape", "Shape2");
api.select([shape2]);
api.moveBackward();
moveToBack()
Move the selected Layers to the bottom of the layer stack.
var shape1 = api.create("basicShape", "Shape1");
var shape2 = api.create("basicShape", "Shape2");
var shape3 = api.create("basicShape", "Shape3");
api.select([shape3]);
api.moveToBack();
isShape(layerId:string) → bool [](/content/docs/tech-info/scripting/api-module/#isshape "Direct link to isshape"/index.html)
Checks if a specified Layer is a Shape.
var shape1 = api.primitive("ellipse", "Ellipse");
console.log(api.isShape(shape1));
editComponent(layerId:string, editingMode:bool) [](/content/docs/tech-info/scripting/api-module/#editcomponent "Direct link to editcomponent"/index.html)
Sets the editing mode for a Component.
// Collapse a Component containing an Ellipse.
var ellipseId = api.primitive("ellipse", "Ellipse");
var 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.
var cId = api.primitive("circle", "Circle (Bottom)");
var rId = api.primitive("rectangle", "Rectangle (Middle)");
var pId = api.primitive("polygon", "Polygon (Top)");
var layerIds = [rId, pId, cId];
var ordered = api.sortLayerIdsByHierarchy(layerIds);
for (let layerId of ordered) {
console.log(api.getNiceName(layerId));
}
reorder(layerIdToReorder:string, underLayerId:string) [](/content/docs/tech-info/scripting/api-module/#reorder "Direct link to reorder"/index.html)
Reorder Layers in the hierarchy, re-parenting if required.
var cId = api.primitive("circle", "Circle");
var rId = api.primitive("rectangle", "Rectangle");
var pId = api.primitive("polygon", "Polygon");
var 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");
getLayerVersion(layerId:string) → string [](/content/docs/tech-info/scripting/api-module/#getlayerversion "Direct link to getlayerversion"/index.html)
Returns the version of a specified Layer – useful for third-party developers.
compareVersions(firstVersion:string, secondVersion:string) → bool [](/content/docs/tech-info/scripting/api-module/#compareversions "Direct link to compareversions"/index.html)
Returns true if the first version is less than the second version.
let isLower = api.compareVersions("1.0", "2.0");
console.log(isLower) // true
isLower = api.compareVersions("3.0.1", "3.0");
console.log(isLower) // false
isProLayerType(layerType:string) → bool [](/content/docs/tech-info/scripting/api-module/#isprolayertype "Direct link to isprolayertype"/index.html)
Returns true if the specified layer requires a Pro licence to use.
console.debug(api.isProLayerType("extrude"));
showInAttributeEditor(layerId:string) [](/content/docs/tech-info/scripting/api-module/#showinattributeeditor "Direct link to showinattributeeditor"/index.html)
Load the given Layer's UI into the Attribute Editor.
var shapeId = api.create("basicShape");
api.showInAttributeEditor(shapeId);
clearAttributeEditor(layerId:string) [](/content/docs/tech-info/scripting/api-module/#clearattributeeditor "Direct link to clearattributeeditor"/index.html)
Clear the Attribute Editor.
api.clearAttributeEditor();
isReferenced(layerId:string) → bool [](/content/docs/tech-info/scripting/api-module/#isreferenced "Direct link to isreferenced"/index.html)
Returns true if the Composition layer has been imported as part of a Reference.
// Via Assets Window
var refId = "yourReferenceAssetId"; // Update the to the Asset Id of an imported Reference (parent) in the Assets Window.
var refChildComps = api.getChildren(refId);
console.log(api.isReferenced(refChildComps[0]));
// Via Scene Window
var layerId = "yourPreCompLayerId"; // Update to the Layer Id of a Pre-Comp in the Scene Window.
var compId = api.getCompFromReference(layerId);
console.log(api.isReferenced(compId));
Working with Attributes [](/content/docs/tech-info/scripting/api-module/#working-with-attributes "Direct link to Working with Attributes"/index.html)
getSelectedAttributes() → [object]
This will return an array containing the paths of the selected attributes.
var selAttr = api.getSelectedAttributes();
for (let [layerId, attr] of selAttr) {
console.log(layerId+"."+attr);
}
set(layerId:string, arguments:object) [](/content/docs/tech-info/scripting/api-module/#set "Direct link to set"/index.html)
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 [](/content/docs/tech-info/scripting/api-module/#get "Direct link to get"/index.html)
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 [](/content/docs/tech-info/scripting/api-module/#getattributedefinition "Direct link to getattributedefinition"/index.html)
Returns an object containing detailed information about an Attribute.
var shapeId = api.create("basicShape");
var 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)default// return the default value for the attribute. Note that lists/compound attributes do not have defaults.
setGenerator(layerId:string, attrId:string, type:string) [](/content/docs/tech-info/scripting/api-module/#setgenerator "Direct link to setgenerator"/index.html)
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 [](/content/docs/tech-info/scripting/api-module/#getcurrentgenerator "Direct link to getcurrentgenerator"/index.html)
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] [](/content/docs/tech-info/scripting/api-module/#getgenerators "Direct link to getgenerators"/index.html)
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 [](/content/docs/tech-info/scripting/api-module/#getcurrentgeneratortype "Direct link to getcurrentgeneratortype"/index.html)
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) [](/content/docs/tech-info/scripting/api-module/#setattributeexpression "Direct link to setattributeexpression"/index.html)
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 [](/content/docs/tech-info/scripting/api-module/#hasattributeexpression "Direct link to hasattributeexpression"/index.html)
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 [](/content/docs/tech-info/scripting/api-module/#getattributeexpression "Direct link to getattributeexpression"/index.html)
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) [](/content/docs/tech-info/scripting/api-module/#connect "Direct link to connect"/index.html)
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");
var 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) [](/content/docs/tech-info/scripting/api-module/#disconnect "Direct link to disconnect"/index.html)
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) [](/content/docs/tech-info/scripting/api-module/#disconnectinput "Direct link to disconnectinput"/index.html)
Disconnect an Attribute's input connection.
api.disconnectInput("basicShape#1", "position.x");
disconnectOutputs(layerId:string, attrId:string) [](/content/docs/tech-info/scripting/api-module/#disconnectoutputs "Direct link to disconnectoutputs"/index.html)
Disconnect all the output connections from an Attribute.
api.disconnectOutputs("basicShape#1", "position.x");
getInConnection(layerId:string, attrId:string) → string [](/content/docs/tech-info/scripting/api-module/#getinconnection "Direct link to getinconnection"/index.html)
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] [](/content/docs/tech-info/scripting/api-module/#getoutconnections "Direct link to getoutconnections"/index.html)
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.
var selKeys = api.getSelectedKeyframes();
for (let [key, value] of Object.entries(selKeys)) {
console.log(key+": "+value);
}
keyframe(layerId:string, frame:int, {object}) → string [](/content/docs/tech-info/scripting/api-module/#keyframe "Direct link to keyframe"/index.html)
Set keyframes for Layers and return the keyframeId.
var primId = api.primitive("rectangle", "My Rectangle");
var kfId1 = api.keyframe(primId, 0, {"scale.x": 5.});
console.log(kfId1);
var 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:
var layerId = 'editableShape#1';
var 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) [](/content/docs/tech-info/scripting/api-module/#deletekeyframe "Direct link to deletekeyframe"/index.html)
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) [](/content/docs/tech-info/scripting/api-module/#modifykeyframe "Direct link to modifykeyframe"/index.html)
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 integer0Bezier,1Linear,2Step (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.
var ellipseId = api.primitive("ellipse", "Ellipse");
// Create some values to set as keyframes
var keyValues = [-200,200,-300, 300]
var 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
var 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) [](/content/docs/tech-info/scripting/api-module/#modifykeyframetangent "Direct link to modifykeyframetangent"/index.html)
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).xValue// The absolute value for the bezier handle's X position (frame).yValue// The absolute value for the bezier handle's Y position (value).
Example setting flat keyframes:
// Make a new ellipse
var ellipseId = api.primitive("ellipse", "Ellipse");
// Create some values to set as keyframes
var keyValues = [-200,200,-300, 300]
var 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
var 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
var ellipseId = api.primitive("ellipse", "Ellipse");
// Store some values to set as keyframes
var keyValues = [-200,200,-300, 300]
var 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
var 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}});
}
setKeyframeVelocity(layerId:string, dictionary:object) [](/content/docs/tech-info/scripting/api-module/#setkeyframevelocity "Direct link to setkeyframevelocity"/index.html)
Set speed and influence values on a Layer's keyframes.
api.setKeyframeVelocity("basicShape#1", {
"position.x": {
frame: 30,
leftSpeed: 0.0, // incoming speed (0.0..2.0)
rightSpeed: 1.0, // outgoing speed
leftInfluence: 0.7, // incoming influence (0.01..1.0)
rightInfluence: 0.333 // outgoing influence
},
"position.y": {
frame: 30,
leftSpeed: 0.0,
rightSpeed: 1.0,
leftInfluence: 0.7,
rightInfluence: 0.333
}
});
clearKeyframeVelocity(layerId:string, dictionary:object) [](/content/docs/tech-info/scripting/api-module/#clearkeyframevelocity "Direct link to clearkeyframevelocity"/index.html)
Reset all four speed/influence fields on a keyframe.
api.clearKeyframeVelocity("basicShape#1", {"position.x": { frame: 30 }});
getKeyframeIdsForAttribute(layerId:string, attrId:string) [](/content/docs/tech-info/scripting/api-module/#getkeyframeidsforattribute "Direct link to getkeyframeidsforattribute"/index.html)
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 [](/content/docs/tech-info/scripting/api-module/#getattributefromkeyframeid "Direct link to getattributefromkeyframeid"/index.html)
Get the attribute path for a given keyframe.
var keyIds = api.getSelectedKeyframeIds();
for (let keyId of keyIds) {
console.log(api.getAttributeFromKeyframeId(keyId))
}
resyncPathKeyframes(layerId:string, attrId:string) [](/content/docs/tech-info/scripting/api-module/#resyncpathkeyframes "Direct link to resyncpathkeyframes"/index.html)
Resynchronise path keyframe data after using set() on Path Animation keyframes.
magicEasing(layerId:string, attrId:string, frame:int, easingName:string, expression:string) [](/content/docs/tech-info/scripting/api-module/#magiceasing "Direct link to magiceasing"/index.html)
Apply Magic Easing to an Attribute's keyframe and optionally add an expression.
// Add SlowOut Magic Easing
var shapeId = api.create("basicShape");
api.keyframe(shapeId, 0, {"position.x": 0})
api.keyframe(shapeId, 24, {"position.x": 200})
api.magicEasing(shapeId, "position.x", 0, "SlowOut");
// Add Custom Magic Easing
var shapeId = api.create("basicShape");
api.keyframe(shapeId, 0, {"position.x": 0})
api.keyframe(shapeId, 24, {"position.x": 200})
api.magicEasing(shapeId, "position.x", 0, "Custom", "1 - pow(1 - x, 5)");
Valid Magic Easing names are:
- "SlowIn"
- "SlowOut"
- "SlowInSlowOut"
- "VerySlowIn"
- "VerySlowOut"
- "VerySlowInVerySlowOut"
- "SpringIn"
- "SpringOut"
- "SpringInSpringOut"
- "SmallSpringIn"
- "SmallSpringOut"
- "SmallSpringInSmallSpringOut"
- "AnticipateIn"
- "OvershootOut"
- "AnticipateInOvershootOut"
- "BounceIn"
- "BounceOut"
- "BounceInBounceOut"
- "Custom" // This must be used if adding an expression
- "None"
getKeyframeTimes(layerId:string, attrId:string) [](/content/docs/tech-info/scripting/api-module/#getkeyframetimes "Direct link to getkeyframetimes"/index.html)
Get the keyframe times for an attribute.
deleteAnimation(layerId:string, attrId:string) [](/content/docs/tech-info/scripting/api-module/#deleteanimation "Direct link to deleteanimation"/index.html)
Delete all keyframes on an attribute.
getAttrType(layerId:string, attrId:string) → string [](/content/docs/tech-info/scripting/api-module/#getattrtype "Direct link to getattrtype"/index.html)
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) [](/content/docs/tech-info/scripting/api-module/#resetattribute "Direct link to resetattribute"/index.html)
Reset an Attribute back to its default value.
addArrayIndex(layerId:string, attrId:string) → int [](/content/docs/tech-info/scripting/api-module/#addarrayindex "Direct link to addarrayindex"/index.html)
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) [](/content/docs/tech-info/scripting/api-module/#removearrayindex "Direct link to removearrayindex"/index.html)
Remove an Attribute from an array.
var arrayId = api.create("colorArray");
api.addArrayIndex(arrayId, "array");
api.addArrayIndex(arrayId, "array");
api.renameAttribute(arrayId, "array.0", "Color1");
api.renameAttribute(arrayId, "array.1", "Color2");
api.renameAttribute(arrayId, "array.2", "Color3");
api.removeArrayIndex(arrayId, "array.1"); // Remove Color2
reorderArrayAttr(layerId:string, attrId:string, oldIndex:int, newIndex:int) [](/content/docs/tech-info/scripting/api-module/#reorderarrayattr "Direct link to reorderarrayattr"/index.html)
Reorder an Array attribute from one index to another.
var colorId = api.create("colorArray");
api.addArrayIndex(colorId, "array");
api.addArrayIndex(colorId, "array");
api.set(colorId, {"array.1": "#ffff00", "array.2": "#6437ff"})
// Green, Yellow, Purple
api.reorderArrayAttr(colorId, "array", 2, 0);
// Purple, Green, Yellow
getArrayCount(layerId:string, attrId:string) → int [](/content/docs/tech-info/scripting/api-module/#getarraycount "Direct link to getarraycount"/index.html)
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) [](/content/docs/tech-info/scripting/api-module/#adddynamic "Direct link to adddynamic"/index.html)
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 [](/content/docs/tech-info/scripting/api-module/#getcustomattributename "Direct link to getcustomattributename"/index.html)
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 [](/content/docs/tech-info/scripting/api-module/#hascustomattributename "Direct link to hascustomattributename"/index.html)
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 [](/content/docs/tech-info/scripting/api-module/#getattrparent "Direct link to getattrparent"/index.html)
Return the Id of the parent attribute. If there is no parent attribute, an empty string is returned.
var shapeId = api.create("basicShape");
var parentAttrId = api.getAttrParent(shapeId, "position.x");
console.log(parentAttrId);
getAttrChildren(layerId:string, attrId:string) → [string] [](/content/docs/tech-info/scripting/api-module/#getattrchildren "Direct link to getattrchildren"/index.html)
Return the Ids of any child attributes. If there are no child attributes, an empty array is returned.
var arrayId = api.create("valueArray", "My Value Array");
api.addArrayIndex(arrayId, "array")
api.addArrayIndex(arrayId, "array")
var children = api.getAttrChildren(arrayId, "array");
console.log(children);
renameAttribute(layerId:string, attrId:string, newName:string) [](/content/docs/tech-info/scripting/api-module/#renameattribute "Direct link to renameattribute"/index.html)
Rename a specified Attribute for a Layer.
var arrayId = api.create("valueArray", "My Value Array");
api.renameAttribute(arrayId, "array.0", "Example Name");
getAttributeNiceName(layerId:string, attrId:string) → string [](/content/docs/tech-info/scripting/api-module/#getattributenicename "Direct link to getattributenicename"/index.html)
Return the 'nice name' of an Attribute based on its Scripting Path.
var shapeId = api.create("basicShape");
api.renameAttribute(shapeId, "position", "Custom Name");
console.log(api.getAttributeNiceName(shapeId, "position"));
getDropdownNiceName(layerId:string, attrId:string, index:int) → string [](/content/docs/tech-info/scripting/api-module/#getdropdownnicename "Direct link to getdropdownnicename"/index.html)
Returns the 'nice name' of the given index for an enum (dropdown) Attribute.
var shapeId = api.create("basicShape");
console.log(api.getDropdownNiceName(shapeId, "motionBlur", 1));
getOutConnectedAttributes(layerId:string) → [string] [](/content/docs/tech-info/scripting/api-module/#getoutconnectedattributes "Direct link to getoutconnectedattributes"/index.html)
List the output connections from a Layer.
var layer = api.primitive("ellipse", "Ellipse");
api.connect(layer, "scale.x", layer, "scale.y");
api.connect(layer, "position.x", layer, "position.y");
var outConn = api.getOutConnectedAttributes(layer);
console.log(outConn);
getInConnectedAttributes(layerId:string) → [string] [](/content/docs/tech-info/scripting/api-module/#getinconnectedattributes "Direct link to getinconnectedattributes"/index.html)
List the input connections to a Layer.
var ayer = api.primitive("ellipse", "Ellipse");
api.connect(layer, "scale.x", layer, "scale.y");
api.connect(layer, "position.x", layer, "position.y");
var inConn = api.getInConnectedAttributes(layer);
console.log(inConn);
getAttributes(layerId:string) → [string] [](/content/docs/tech-info/scripting/api-module/#getattributes "Direct link to getattributes"/index.html)
Return a list of all the attributes that exist on a Layer.
var layerId = api.create("null", "My Null");
var attrIds = api.getAttributes(layerId);
for (aId of attrIds) {
console.log(aId);
}
selectAttribute(attributePaths:[string], add:bool) [](/content/docs/tech-info/scripting/api-module/#selectattribute "Direct link to selectattribute"/index.html)
Select attributes by their full paths (e.g., "layerId.attrId.subAttr") with an option to add to the current selection. Pass an empty array to clear the selection.
deselectAttribute(attributePaths:[string])
Deselect attributes by their full paths (e.g., "layerId.attrId.subAttr").
hasAttribute(layerId:string, attrId:string) → bool [](/content/docs/tech-info/scripting/api-module/#hasattribute "Direct link to hasattribute"/index.html)
Check to find out if a particular attribute exists on a Layer.
var layer = api.primitive("ellipse", "Ellipse")
var attr = api.hasAttribute(layer, "position.x");
console.log(attr);
getAnimatedAttributes(layerId:string) → [string] [](/content/docs/tech-info/scripting/api-module/#getanimatedattributes "Direct link to getanimatedattributes"/index.html)
Return a list of all the animated attributes that exist on a Layer.
var layerId = api.create("null", "My Null");
api.keyframe(layerId, 0, {"scale.x": 5.});
api.keyframe(layerId, 100, {"scale.x": 1.});
var attrIds = api.getAnimatedAttributes(layerId);
for (aId of attrIds) {
console.log(aId);
}
isAnimatedAttribute(layerId:string, attrId:string) → bool [](/content/docs/tech-info/scripting/api-module/#isanimatedattribute "Direct link to isanimatedattribute"/index.html)
Check to find out if a particular attribute on a Layer is animated.
var layerId = api.create("null", "My Null");
api.keyframe(layerId, 0, {"scale.x": 5.});
api.keyframe(layerId, 100, {"scale.x": 1.});
console.log(api.isAnimatedAttribute(layerId, "scale.x"));
graphPreset(layerId:string, attrId:string, presetIndex:int) [](/content/docs/tech-info/scripting/api-module/#graphpreset "Direct link to graphpreset"/index.html)
Sets a preset for a Graph Attribute. The preset index can be: 0: s-curve 1: ramp 2: linear 3: flat
flipGraph(layerId:string, attrId:string, direction:string) [](/content/docs/tech-info/scripting/api-module/#flipgraph "Direct link to flipgraph"/index.html)
Flips the points on a Graph Attribute - valid direction arguments are "horizontal" and "vertical".
var staggerId = api.create("stagger", prefix+"Stagger");
api.flipGraph(staggerId, "graph", "vertical");
addToControlCentre(layerId:string, attrId:string) [](/content/docs/tech-info/scripting/api-module/#addtocontrolcentre "Direct link to addtocontrolcentre"/index.html)
Add an attribute to the Control Centre.
var shapeId = api.create("null", "My Null");
api.addToControlCentre(shapeId, "position.x");
removeFromControlCentre(layerId:string, attrId:string) [](/content/docs/tech-info/scripting/api-module/#removefromcontrolcentre "Direct link to removefromcontrolcentre"/index.html)
Remove an attribute from the Control Centre.
//Create a Null and add position.x to Control Centre
var shapeId = api.create("null", "My Null");
api.addToControlCentre(shapeId, "position.x");
//Then, assuming the null's LayerId is null#1, remove position.x from the Control Centre
api.removeFromControlCentre("null#1", "position.x");
addPreCompOverride(layerId:string, attrId:string) [](/content/docs/tech-info/scripting/api-module/#addprecompoverride "Direct link to addprecompoverride"/index.html)
Add a Pre-Comp Override to an Attribute.
var layerId = api.primitive("ellipse", "My Ellipse");
api.select([layerId]);
var preCompId = api.preCompose();
api.addPreCompOverride(layerId, "generator.radius");
removePreCompOverride(layerId:string, attrId:string) [](/content/docs/tech-info/scripting/api-module/#removeprecompoverride "Direct link to removeprecompoverride"/index.html)
Remove a Pre-Comp Override to an Attribute.
var layerId = api.primitive("ellipse", "My Ellipse");
api.select([layerId]);
var preCompId = api.preCompose();
api.addPreCompOverride(layerId, "generator.radius");
var numOfOverrides = api.listPreCompOverrides(preCompId).length
// Remove Pre-Comp Override
api.removePreCompOverride(layerId, "generator.radius");
var numOfOverridesAfterRemove = api.listPreCompOverrides(preCompId).length
console.log("Overrides after add: " + numOfOverrides + ". Overrides after remove: " + numOfOverridesAfterRemove)
listPreCompOverrides(preCompId:string) → object [](/content/docs/tech-info/scripting/api-module/#listprecompoverrides "Direct link to listprecompoverrides"/index.html)
Return a list of key:value pairs where the key is the Attribute being overridden and the value is the attribute stored on the Pre-Comp.
var layerId = api.primitive("ellipse", "My Ellipse");
api.select([layerId]);
var preCompId = api.preCompose();
api.addPreCompOverride(layerId, "generator.radius");
api.addPreCompOverride(layerId, "position");
console.log(JSON.stringify(api.listPreCompOverrides("compositionReference#1")));
setGradientFromColors(layerId:string, attrId:string, hexColors:[string]) [](/content/docs/tech-info/scripting/api-module/#setgradientfromcolors "Direct link to setgradientfromcolors"/index.html)
Create evenly distributed Color Stops for a gradient attribute from an array of hex color strings.
var gradientId = api.create("gradientShader", "Gradient Shader");
api.setGradientFromColors(gradientId, "generator.gradient", ["#ffffff", "#4ffd7a", "#ffff00", "#ff24e0", "#6437ff", "#ffffff"]);
setGradientInterpolation(layerId:string, attrId:string, interpolation:int) [](/content/docs/tech-info/scripting/api-module/#setgradientinterpolation "Direct link to setgradientinterpolation"/index.html)
Set the interpolation for every Color Stop on a gradient attribute: Linear = 0, Step = 1, Smooth = 2, Crush = 3, Smooth Blend = 4, Contrast = 5.
var gradientId = api.create("gradientShader", "Gradient Shader");
api.setGradientFromColors(gradientId, "generator.gradient", ["#ffffff", "#4ffd7a", "#ffff00", "#ff24e0"]);
api.setGradientInterpolation(gradientId, "generator.gradient", 1);
isAttrDefault(layerId:string, attrId:string) → bool [](/content/docs/tech-info/scripting/api-module/#isattrdefault "Direct link to isattrdefault"/index.html)
Returns true if an attribute value matches its default value.
areAttributeValuesEqual(layerId1:string, attrId1:string, layerId2:string, attrId2:string) → bool [](/content/docs/tech-info/scripting/api-module/#areattributevaluesequal "Direct link to areattributevaluesequal"/index.html)
Returns true if two attributes are identical in value, expression and custom name (if set).
let grad1id = api.create("gradientShader");
let grad2id = api.create("gradientShader");
console.log(api.areAttributeValuesEqual(grad1id, "alpha", grad2id, "alpha")); // true
api.set(grad1id, {"alpha": 50});
console.log(api.areAttributeValuesEqual(grad1id, "alpha", grad2id, "alpha")); // false
console.log(api.areAttributeValuesEqual(grad1id, "generator.gradient", grad2id, "generator.gradient")); // true
api.set(grad1id, {"generator.gradient.0.color": "#d9695f"});
console.log(api.areAttributeValuesEqual(grad1id, "generator.gradient", grad2id, "generator.gradient")); // false
hasAttributeDefinitionOverrides(layerId:string, attrId:string) → bool [](/content/docs/tech-info/scripting/api-module/#hasattributedefinitionoverrides "Direct link to hasattributedefinitionoverrides"/index.html)
Return true if an attribute has any definition overrides (limits).
clearAttributeDefinitionOverrides(layerId:string, attrId:string) [](/content/docs/tech-info/scripting/api-module/#clearattributedefinitionoverrides "Direct link to clearattributedefinitionoverrides"/index.html)
Clear all definition overrides (limits) for an attribute.
getAttributeDefinitionOverride(layerId:string, attrId:string, key:string) → number|null [](/content/docs/tech-info/scripting/api-module/#getattributedefinitionoverride "Direct link to getattributedefinitionoverride"/index.html)
Get a definition override (limit) for an attribute.
keys: "hardMin", "hardMax", "softMin", "softMax", "step"
setAttributeDefinitionOverride(layerId:string, attrId:string, key:string, value:number) [](/content/docs/tech-info/scripting/api-module/#setattributedefinitionoverride "Direct link to setattributedefinitionoverride"/index.html)
Set a definition override (limit) for an attribute.
keys: "hardMin", "hardMax", "softMin", "softMax", "step"
getEffectiveAttributeDefinition(layerId:string, attrId:string) → object [](/content/docs/tech-info/scripting/api-module/#geteffectiveattributedefinition "Direct link to geteffectiveattributedefinition"/index.html)
Get the attribute definition including any overrides which can be set via Edit Limits... in the UI.
Shapes [](/content/docs/tech-info/scripting/api-module/#shapes "Direct link to Shapes"/index.html)
centrePivot(layerId:string, centroid:bool) [](/content/docs/tech-info/scripting/api-module/#centrepivot "Direct link to centrepivot"/index.html)
Centre the Pivot of the specified Layer. If Centroid is true the Pivot will be moved to the centre of mass.
getPivotPosition(layerId:string, worldSpace:bool) → {x:number, y:number} [](/content/docs/tech-info/scripting/api-module/#getpivotposition "Direct link to getpivotposition"/index.html)
Returns the position of a specified Layer's pivot in local or world space.
freezeTransform(layerId:string) [](/content/docs/tech-info/scripting/api-module/#freezetransform "Direct link to freezetransform"/index.html)
Freeze the transform (position, rotation, scale, pivot, skew) of the specified Layer. This can be used to make a Shape's current position its zero position.
resetTransform(layerId:string) [](/content/docs/tech-info/scripting/api-module/#resettransform "Direct link to resettransform"/index.html)
Reset a Shape's transform back to the default state (this will also clear any frozen transformations).
getDrawInstructionsForSelection() → string
Copy the selected Shape(s) as code. The resulting code can be pasted into a new tab and run to create a new Editable Shape based on those copied.
var path = api.getDrawInstructionsForSelection();
console.log(path);
move(x:number,y:number) [](/content/docs/tech-info/scripting/api-module/#move "Direct link to move"/index.html)
Move the selected Shapes.
var layer1Id = api.primitive("ellipse", "Ellipse1");
var layer2Id = api.primitive("ellipse", "Ellipse2");
api.set(layer2Id, {"position": [200, 0]});
api.select([layer1Id, layer2Id]);
api.move(100,100);
Editable Shapes [](/content/docs/tech-info/scripting/api-module/#editable-shapes "Direct link to Editable Shapes"/index.html)
makeEditable(layerId:string, makeACopy:bool) → string [](/content/docs/tech-info/scripting/api-module/#makeeditable "Direct link to makeeditable"/index.html)
This will convert the selected Shape into an Editable Shape, which can then be edited with the getEditablePath and setEditablePath functions.
If makeACopy is set to false the original Layer will be deleted.
var primId = api.primitive("ellipse", "Ellipse");
var editableId = api.makeEditable(primId, false);
getEditablePath(layerId:string, worldSpace:bool) → [object] [](/content/docs/tech-info/scripting/api-module/#geteditablepath "Direct link to geteditablepath"/index.html)
This function returns an Editable Path object which can be edited and then set back to any Editable Shape Layer.
Editable Paths and ordinary Paths (like the one in the Cavalry Module) are distinct. The worldSpace argument can be used to determine if path point coordinates are returned in local – unaware of the Editable Shape's position, rotation and scale – or world space where those transformations are applied. An Editable Path's points have in handles and out handles just like the points that are edited in the Viewport. They also have weight and angle locking settings. Ordinary Paths are constructed using moveTo, lineTo and cubicTo. In an Editable Path, an extra point can be added to the Contour's points array.
The schema is as follows:
[\
\
{\
\
"points": [\
\
{\
\
"position": {\
\
"x": 0.0,\
\
"y": 0.0\
\
},\
\
"outHandle": {\
\
"x": 0.0,\
\
"y": 0.0,\
\
"selected": bool\
\
},\
\
"inHandle": {\
\
"x": 0.0,\
\
"y": 0.0,\
\
"selected": bool\
\
},\
\
"weightLocked": bool,\
\
"angleLocked": bool,\
\
"selected": bool\
\
}\
\
],\
\
"isClosed": bool\
\
}\
\
]
The inHandle and outHandle objects are optional (when they are missing a linear point will be created). Values marked bool need to be true or false.
var multiplier = 1.5;
var primId = api.primitive("ellipse", "Ellipse");
var editableId = api.makeEditable(primId, false);
var path = api.getEditablePath(editableId, false);
for (let contour of path) {
for (let point of contour.points) {
point.inHandle.x *= multiplier;
point.outHandle.x *= multiplier;
point.inHandle.y *= multiplier;
point.outHandle.y *= multiplier;
}
}
api.setEditablePath(editableId, true, path);
setEditablePath(layerId:string, worldSpace:bool, pathObject:object) [](/content/docs/tech-info/scripting/api-module/#seteditablepath "Direct link to seteditablepath"/index.html)
This will set the Editable Path on an Editable Shape (Primitives are not supported). See getEditablePath for details on the Editable Path schema. The worldSpace argument will determine if path point coordinates are set in local space – unaware of the Editable Shape's position, rotation and scale – or world space where those transformations are applied. If the Editable Path is accessed in world space, it should also be set in world space.
This example will flatten the selected bezier points to 0 on the Y axis.
var sel = api.getSelection();
for (let layerId of sel) {
if (api.getLayerType(layerId) != "editableShape") {
continue;
}
let path = api.getEditablePath(layerId, true);
for (let contour of path) {
for (let point of contour.points) {
if (!point.selected) {
continue;
}
point.position.y = 0;
point.inHandle.y = 0;
point.outHandle.y = 0;
}
}
api.setEditablePath(layerId, true, path);
}
makeFirstPoint(layerId:string) [](/content/docs/tech-info/scripting/api-module/#makefirstpoint "Direct link to makefirstpoint"/index.html)
This will make the selected point the first point in an Editable Path. This is like running the command in the Shape menu.
movePoint(x:number, y:number, localSpace:bool) [](/content/docs/tech-info/scripting/api-module/#movepoint "Direct link to movepoint"/index.html)
Move selected points by given X and Y values.
//select some editable points
api.movePoint(0,50, true);
setPointPosition(positionObject:object, localSpace:bool, handles:bool) [](/content/docs/tech-info/scripting/api-module/#setpointposition "Direct link to setpointposition"/index.html)
Move selected points to given X and Y positions. Values in the positionObject are optional, i.e {"x":20} and {"x":20, "y":50} are both valid. Use the handles argument to specify if in/out handles should be moved instead of the point. To move both, run the command twice with handles set to true and false.
//select some editable points
api.setPointPosition({"y":-50}, false, false)
api.setPointPosition({"y":-50}, false, true)
Rendering [](/content/docs/tech-info/scripting/api-module/#rendering "Direct link to Rendering"/index.html)
render(renderQueueItemId:string) [](/content/docs/tech-info/scripting/api-module/#render "Direct link to render"/index.html)
Render a specific Render Queue Item.
var itemId = api.addRenderQueueItem(api.getActiveComp());
api.render(itemId);
renderAll()
Render all Render Queue Items in the Render Manager.
api.addRenderQueueItem(api.getActiveComp());
api.renderAll();
renderPNGFrame(filePath:string, scalePercent:number) [](/content/docs/tech-info/scripting/api-module/#renderpngframe "Direct link to renderpngframe"/index.html)
Render the current frame out as a PNG with a given scale set by scalePercent.
Rendering in this way will only render the visible Layers (i.e any soloed Layers).
The render extension (.png) will be added to the filename.
// This example will export each selected Layer individually as a PNG at 100% and 200% scale.
// Get the selection
var sel = api.getSelection();
for (let layerId of sel) {
// Solo each layer
api.soloLayers([layerId]);
// Build a file path to export the render to
let filePath = api.getRenderPath() + "/" + api.getNiceName(layerId);
// Render out the image at 100% scale.
api.renderPNGFrame(filePath, 100);
// Add @2x to the file path
filePath += "@2x";
// Render out at 200% scale.
api.renderPNGFrame(filePath, 200);
// Log where we put the file
console.log("Rendered layer: "+layerId+" to: "+filePath+".png");
}
// Clear soloing
api.soloLayers([]);
renderSVGFrame(filePath:string, scalePercent:number, skipComps:bool) [](/content/docs/tech-info/scripting/api-module/#rendersvgframe "Direct link to rendersvgframe"/index.html)
Render the current frame out as an SVG with a given scale set by scalePercent.
Setting skipComps to true will mean that Composition backgrounds do not get exported.
Rendering in this way will only render the visible Layers (i.e any soloed Layers).
The render extension (.svg) will be added to the filename.
getRenderQueueItems() → [string]
Return a list of the Render Queue Items in the Render Manager.
api.addRenderQueueItem(api.getActiveComp());
api.addRenderQueueItem(api.getActiveComp());
var items = api.getRenderQueueItems();
for (var item of items) {
console.log(item);
}
addRenderQueueItem(compId:string) → string [](/content/docs/tech-info/scripting/api-module/#addrenderqueueitem "Direct link to addrenderqueueitem"/index.html)
Add a new Render Queue Item to the Render Manager.
var itemId = api.addRenderQueueItem(api.getActiveComp());
console.log(itemId);
connectDynamicIndex(layerId:string, attrId:string) [](/content/docs/tech-info/scripting/api-module/#connectdynamicindex "Direct link to connectdynamicindex"/index.html)
Connect the Render Manager's Dynamic Index to another attribute.
var spreadsheetId = api.create("spreadsheet", "My Spreadsheet");
api.connectDynamicIndex(spreadsheetId, "rowIndex");
api.set(spreadsheetId, {"useFixedRow": true});
getDynamicIndex() → int
Return the current Dynamic Index.
console.log(api.getDynamicIndex());
setDynamicIndexOffset(index:int) [](/content/docs/tech-info/scripting/api-module/#setdynamicindexoffset "Direct link to setdynamicindexoffset"/index.html)
Set the Render Manager's Dynamic Index Offset.
api.setDynamicIndexOffset(10);
backgroundRender(renderQueueItemId:string) [](/content/docs/tech-info/scripting/api-module/#backgroundrender "Direct link to backgroundrender"/index.html)
Render a specific Render Queue Item in the background. Note - there are no notifications for the render's status.
backgroundRenderAll()
Render all (active) Render Queue Items in the background. Note - there are no notifications for the render's status.
cancelRender()
Cancel the current render.
Working with the Scene [](/content/docs/tech-info/scripting/api-module/#working-with-the-scene "Direct link to Working with the Scene"/index.html)
newScene()
Opens a new Scene, discarding any changes to the current Scene.
openScene(filePath:string, force:bool) [](/content/docs/tech-info/scripting/api-module/#openscene "Direct link to openscene"/index.html)
Open a Scene at the given location, this may present a Save Changes dialog unless force is set to true.
saveSceneAs(filePath:string) → bool [](/content/docs/tech-info/scripting/api-module/#savesceneas "Direct link to savesceneas"/index.html)
Save the current Scene to a new location and return a boolean to confirm if it was successful.
saveScene() → bool
Save the current Scene file and return a boolean to confirm if it was successful. If the current Scene has not yet been saved, a dialog will be presented asking where to save the scene.
sceneHasUnsavedChanges() → bool
Return true if there have been any changes made to the Scene since the last save.
console.log(api.sceneHasUnsavedChanges());
importScene(path:string) [](/content/docs/tech-info/scripting/api-module/#importscene "Direct link to importscene"/index.html)
Import a Cavalry Scene (.cv) or Component (.cvc). A .cv file will be added to the Assets Window, a .cvc file will be added to the active Composition.
api.importScene("path/to/scene.cv");
loadAsset(path:string, isSequence:bool) → string [](/content/docs/tech-info/scripting/api-module/#loadasset "Direct link to loadasset"/index.html)
Load an asset with the given path. Set isSequence to true to attempt to load an image sequence from the file path.
// Load an image
api.loadAsset("/Path/To/image.png", false);
// Load an image sequence
api.loadAsset("/Path/To/sequence.00000.png", true);
loadSmartFolderAsset(path:string, type:string) → string [](/content/docs/tech-info/scripting/api-module/#loadsmartfolderasset "Direct link to loadsmartfolderasset"/index.html)
Load a Smart Folder Asset from a file path. The type can be 'image' or 'audio'.
// Load an Image Smart Folder
api.loadSmartFolderAsset("/path/to/smartfolder.png", 'image');
reloadAsset(assetId:string) [](/content/docs/tech-info/scripting/api-module/#reloadasset "Direct link to reloadasset"/index.html)
Reloads an Asset with the given assetId
// First load an Asset, then run:
api.reloadAsset("asset#2");
replaceAsset(assetId:string, string:newPath) [](/content/docs/tech-info/scripting/api-module/#replaceasset "Direct link to replaceasset"/index.html)
Replace a file asset (e.g an image or CSV file).
addAssetToComp(assetId:string/[string]) → string/[string] [](/content/docs/tech-info/scripting/api-module/#addassettocomp "Direct link to addassettocomp"/index.html)
Creates a Footage Shape and Image Shader for each Asset specified and returns the Ids of the newly created Footage Shapes. The argument/return can be a string or an array of strings.
// Import an image/video
var assetId = api.loadAsset("/image.png", false);
// Create the Footage Shape
var footageId = api.addAssetToComp(assetId);
// Find the Image Shader (e.g. to rename it).
var imageShaderId = api.getChildren(footageId);
jsonFromAsset(assetId:string) → object [](/content/docs/tech-info/scripting/api-module/#jsonfromasset "Direct link to jsonfromasset"/index.html)
Given a Text Asset (which is a .json file) or a Spreadsheet Asset, get the JSON object that Asset represents.
For the following example, first select a Text Asset (a JSON file imported into Cavalry).
var sel = api.getSelection();
if (sel.length) {
if (api.getLayerType(sel[0]) == "asset") {
let data = api.jsonFromAsset(sel[0]);
console.log(Object.keys(data).length);
}
}
It's also possible to use jsonFromAsset to query a .csv asset. CSV Assets will contain three members. rows will provide access to the row data. min will provide access to the minimum value of the column (if there is one), and max will give the maximum value.
// Return the first entry in the 'Text' column of a .csv asset (asset#2)
var csv = api.jsonFromAsset("asset#2");
var text = csv["Text"].rows[0]
console.log(text);
textFromAsset(assetId:string) → string [](/content/docs/tech-info/scripting/api-module/#textfromasset "Direct link to textfromasset"/index.html)
Given a Text Asset, get the raw string that Asset represents.
loadGoogleSheet(spreadsheetId:string, sheetId:string) → string [](/content/docs/tech-info/scripting/api-module/#loadgooglesheet "Direct link to loadgooglesheet"/index.html)
Load a Google Sheet Asset. If the sheetId argument is left blank (e.g. "") then the first sheet will be loaded. This function returns the newly created assetId.
info
The spreadsheetId and sheetId can be extracted from a Google Sheet's URL:
https://docs.google.com/spreadsheets/d/[spreadsheetId]/edit#gid=[sheetId]
replaceGoogleSheet(assetId:string, spreadsheetId:string, sheetId:string) [](/content/docs/tech-info/scripting/api-module/#replacegooglesheet "Direct link to replacegooglesheet"/index.html)
Replace an existing Google Sheet Asset with another. If the sheetId argument is left blank (e.g. "") then the first sheet will be loaded.
isFileAsset(assetId:string) → bool [](/content/docs/tech-info/scripting/api-module/#isfileasset "Direct link to isfileasset"/index.html)
Returns true if the Asset is a file asset (image, video, audio, Smart Folder etc.). A Google Sheet, Composition or Group will return false.
getProfileName(assetId:string) → string [](/content/docs/tech-info/scripting/api-module/#getprofilename "Direct link to getprofilename"/index.html)
Returns the ICC profile name of an image/video asset. Returns an empty string for sRGB or untagged images.
isGoogleSheetAsset(assetId:string) → bool [](/content/docs/tech-info/scripting/api-module/#isGoogleSheetAsset "Direct link to isGoogleSheetAsset"/index.html)
Returns true if the Asset is a Google Sheet.
getFontAssetFamilyName(assetId:string) → string [](/content/docs/tech-info/scripting/api-module/#getfontassetfamilyname "Direct link to getfontassetfamilyname"/index.html)
Returns the name of the font family associated with a Font Asset.
getFontAssetStyleName(assetId:string) → string [](/content/docs/tech-info/scripting/api-module/#getfontassetstylename "Direct link to getfontassetstylename"/index.html)
Returns the name of the font style associated with a Font Asset.
setProject(path:string) [](/content/docs/tech-info/scripting/api-module/#setproject "Direct link to setproject"/index.html)
Set the location of projectDescription.json in order to use relative filepaths.
api.setProject("path/to/project");
clearProject()
Clear the Project.
api.clearProject();
getActiveComp() → string
Returns the currently active (open) Composition's id. This can be used to set Composition settings such as Resolution and Frame Range.
console.log(api.getActiveComp());
getComps() → [string]
Returns an array containing all the Compositions in the Scene.
var newCompId = api.createComp("Shiny New Comp");
var allComps = api.getComps();
for (let compId of allComps) {
console.log(compId);
}
createComp(niceName:string) → string [](/content/docs/tech-info/scripting/api-module/#createcomp "Direct link to createcomp"/index.html)
Create a new composition and return its id.
api.createComp("Shiny New Comp");
setActiveComp(compId:string) [](/content/docs/tech-info/scripting/api-module/#setactivecomp "Direct link to setactivecomp"/index.html)
Set the currently active composition.
var newCompId = api.createComp("Shiny New Comp");
api.setActiveComp(newCompId);
preCompose(name:string) → string [](/content/docs/tech-info/scripting/api-module/#precompose "Direct link to precompose"/index.html)
Create a new Composition containing the current selection and then reference that new Composition into the active Composition. The optional name argument specifies the name of the Layer in the Scene Window. The layerId of the newly created Composition Reference is returned. To return the compId of the Composition itself, use getCompFromReference.
// Create two Shapes.
var shape1 = api.primitive("superEllipse", "Super Ellipse");
var shape2 = api.primitive("rectangle", "Rectangle");
// Select them both.
api.select([shape1, shape2]);
// Add the selection to a Pre-Comp (Composition Reference) called 'New Pre-Comp'.
api.preCompose("New Pre-Comp");
getCompFromReference(layerId:string) → string [](/content/docs/tech-info/scripting/api-module/#getcompfromreference "Direct link to getcompfromreference"/index.html)
Given the layerId of a Composition Reference, get the compId of the Composition it references from the Assets Window.
// Create a Shape and select it.
var shape1 = api.primitive("superEllipse", "Super Ellipse");
api.select([shape1]);
// Add the selection to a Pre-Comp (Composition Reference) called 'New Pre-Comp'.
var preCompId = api.preCompose("New Pre-Comp");
// Rename the Composition in the Assets Window to match.
var compId = api.getCompFromReference(preCompId);
api.set(compId, {"niceName": "New Pre-Comp"});
createCompReference(compId:string) → string [](/content/docs/tech-info/scripting/api-module/#createcompreference "Direct link to createcompreference"/index.html)
Create a Composition Reference from an existing Composition and add it to the active Composition.
var newCompId = api.createComp("Shiny New Comp");
api.createCompReference(newCompId);
getAssetWindowLayers(topLevel:bool) → [string] [](/content/docs/tech-info/scripting/api-module/#getassetwindowlayers "Direct link to getassetwindowlayers"/index.html)
This will return an array of all the Layers in the Asset Window. If topLevel is true then only the top level Layers will be returned.
var assetLayerIds = api.getAssetWindowLayers(false);
for (let alId of assetLayerIds) {
console.log(alId);
}
getAssetType(assetId:string) → string [](/content/docs/tech-info/scripting/api-module/#getassettype "Direct link to getassettype"/index.html)
Return the asset type (i.e image, audio, spreadsheet, movie, svg).
// First load an Asset, then run:
console.log(api.getAssetType("asset#2"));
getAssetFilePath(assetId:string) → string [](/content/docs/tech-info/scripting/api-module/#getassetfilepath "Direct link to getassetfilepath"/index.html)
Get the file path of a file asset such as a spreadsheet, image, or font.
var assets = api.getAssetWindowLayers(false);
for (let assetId of assets) {
let type = api.getAssetType(assetId);
if (type != "unknown") {
let filePath = api.getAssetFilePath(assetId);
console.log("Checking: "+filePath+" of type "+type+" exists: "+api.filePathExists(filePath));
}
}
getImageSequenceFilePaths(assetId:string) → [string] [](/content/docs/tech-info/scripting/api-module/#getimagesequencefilepaths "Direct link to getimagesequencefilepaths"/index.html)
Retrieves all the file paths from an image sequence Asset.
// Select an Image Sequence in the Assets Window
var assetId = api.getSelection();
console.log(api.getImageSequenceFilePaths(assetId[0]));
getGoogleSheetAssetURL(assetId:string) → string [](/content/docs/tech-info/scripting/api-module/#getgooglesheetasseturl "Direct link to getgooglesheetasseturl"/index.html)
Return the URL for a given Google Sheet Asset.
var assets = api.getAssetWindowLayers(false);
for (let assetId of assets) {
let type = api.getAssetType(assetId);
if (type == "spreadsheet") {
console.log(api.getGoogleSheetAssetURL(assetId));
}
}
createAssetGroup(niceName:string) → string [](/content/docs/tech-info/scripting/api-module/#createassetgroup "Direct link to createassetgroup"/index.html)
Create a Group in the Assets Window, this will return the layerId of the new Group.
api.createAssetGroup("My Asset Group");
soloLayers(layerIds:[string])
This will solo the Layer ids supplied in the array argument.
// This example will export each selected Layer individually as a PNG at 100% and 200% scale.
// Get the selection
var sel = api.getSelection();
for (let layerId of sel) {
// Solo each layer
api.soloLayers([layerId]);
// Build a file path to export the render to
let filePath = api.getRenderPath() + "/" + api.getNiceName(layerId);
// Render out the image at 100% scale.
api.renderPNGFrame(filePath, 100);
// Add @2x to the file path
filePath += "@2x";
// Render out at 200% scale.
api.renderPNGFrame(filePath, 200);
// Log where we put the file
console.log("Rendered layer: "+layerId+" to: "+filePath+".png");
}
// Clear soloing
api.soloLayers([]);
getAllSceneLayers() → [string]
Return a list of all Layers in a Scene.
var layers = api.getAllSceneLayers();
for (layer of layers) {
console.log(layer);
}
Files and Paths [](/content/docs/tech-info/scripting/api-module/#files-and-paths "Direct link to Files and Paths"/index.html)
Files and paths are absolute, use the methods in this section as the base path if to build paths relative to the Project. Using the ui.scriptLocation variable can be used to build paths relative to a Script.
load(filePath:string) → bool [](/content/docs/tech-info/scripting/api-module/#load "Direct link to load"/index.html)
This will load and run a JavaScript file making the functions contained within it available to use in the current script. This is not a module loader. Scripts loaded in this way are not placed into a namespace/ module and are free functions/objects.
// Contents of script.js
function helloWorld() {
console.log("Hello World.");
}
// Then in Cavalry
api.load("path/to/script.js");
helloWorld();
presentOpenFile(startPath:string, title:string, fileFilter:string) → string [](/content/docs/tech-info/scripting/api-module/#presentopenfile "Direct link to presentopenfile"/index.html)
Open and filter a dialogue window to load/import files. Returns the file name to be loaded or an empty string if the user cancels the dialogue.
The fileFilter is a title, followed by parenthesis containing space separated file type descriptions. e.g. "Data File (*.json *.csv)", "Cavalry File (*.cv *.cvc)", "Palettes (*.pal)".
// Create a button
var button = new ui.Button("Import File");
// Set the onClick callback function
button.onClick = function () {
console.log(api.presentOpenFile(api.getProjectPath(), "Import JSON or CSV", "Data File (*.json *.csv)"));
}
// Add the button to the layout
ui.add(button);
// Show the window
ui.show();
presentSaveFile(startPath:string, title:string, fileFilter:string, defaultFileName:string) → string [](/content/docs/tech-info/scripting/api-module/#presentsavefile "Direct link to presentsavefile"/index.html)
Open a dialogue window to save files. Returns the saved file name or an empty string if the user cancels the dialogue.
The fileFilter is a title, followed by parenthesis containing the file type description. e.g. "Save JSON", "JSON File (*.json)", "Config File.json". Multiple fileFilters can be added by separating the file types with a double semi-colon (;;) – a drop down menu will then appear within the dialogue for a user to choose a file type from.
// Simple example
// Create a button
var button = new ui.Button("Save File");
// Set the onClick callback function
button.onClick = function () {
var filePath = api.presentSaveFile(api.getProjectPath(), "Save JSON", "JSON File (*.json)", "test.json");
api.writeToFile(filePath, "Test file contents", overwrite = false);
}
// Add the button to the layout
ui.add(button);
// Show the window
ui.show();
// Example including a filter for multiple file types
// Create a button
var button = new ui.Button("Save File");
// Set the onClick callback function
button.onClick = function () {
console.log(api.presentSaveFile(api.getProjectPath(), "Save Data", "JSON File (*.json);;CSV File (*.csv)", "Config File"));
}
// Add the button to the layout
ui.add(button);
// Show the window
ui.show()
presentChooseFolder(startPath:string, title:string) → string [](/content/docs/tech-info/scripting/api-module/#presentchoosefolder "Direct link to presentchoosefolder"/index.html)
Presents a dialog for the user to select a folder.
var startPath = "";
if (api.getPlatform() == "macOS") {
startPath = "/macos/start/path"; // Update this path
} else {
startPath = "/windows//start/path"; // Update this path
};
var filePath = api.presentChooseFolder(startPath, "Testing");
console.log(filePath);
exec(scriptId:string, scriptSource:string) → bool [](/content/docs/tech-info/scripting/api-module/#exec "Direct link to exec"/index.html)
Like load, exec will load and run JavaScript but it does not require a saved file.
The first argument is a scriptId. The scriptId exists because Cavalry asks for permission to perform certain tasks (like using the WebAPIs or writing to the hard drive) on a per-script basis. This information is stored using the scriptId so that permission will only be requested once per Id.
We recommend using reverse domain notation com.<yourCompany>.<yourScript> as a basis for scriptIds.
var myScript = "console.log('Hello World!')"
api.exec("com.scenegroup.scriptName", myScript)
getProjectPath() → string
Gets the Project path (if a Project is set). This path does not include a trailing /
console.log(api.getProjectPath());
getRenderPath() → string
Gets the Render path (if a Project is set). This path does not include a trailing /
console.log(api.getRenderPath());
getAssetPath() → string
Gets the Project Asset path (if a Project is set). This path does not include a trailing /
console.log(api.getAssetPath());
getPalettesPath() → string
console.log(api.getPalettesPath());
getScenesPath() → string
Gets the Scene's path (if a Project is set). This path does not include a trailing /
console.log(api.getScenesPath());
getSceneFilePath() → string
If the current Scene has been saved this will return its filepath, otherwise it will return an empty string.
console.log(api.getSceneFilePath());
getPreferencesPath() → string
Get the location of the Cavalry preferences folder.
console.log(api.getPreferencesPath());
getPresetsPath() → string
Get the location of the Cavalry Presets folder.
console.log(api.getPresetsPath());
getAppAssetsPath() → string
Get the location of the App Assets (this is useful for accessing app icons for a script).
var icon = `${api.getAppAssetsPath()}/icons/transform@2x.png`;
var button = new ui.ImageButton(icon);
button.setSize(32, 32);
ui.add(button);
ui.show();
getHomeFolder() → string
Get the location of the User's home directory.
console.log(api.getHomeFolder());
getDesktopFolder() → string
Get the location of the user's desktop directory.
console.log(api.getDesktopFolder());
getDownloadsFolder() → string
Get the location of the User's 'Downloads' directory.
console.log(api.getDownloadsFolder());
getFontsFolder() → string
Get the location of the User's 'Fonts' directory.
console.log(api.getFontsFolder());
getTempFolder() → string
Get the location of the temporary files directory.
console.log(api.getTempFolder());
getPreferencesFolder() → string
Get the location of the user's preferences/configuration directory.
console.log(api.getPreferencesFolder());
getAppDataFolder() → string
Get the location of the user's application data directory.
console.log(api.getAppDataFolder());
filePathExists(path:string) → bool [](/content/docs/tech-info/scripting/api-module/#filepathexists "Direct link to filepathexists"/index.html)
Return whether a path to a file or folder exists.
console.log(api.filePathExists(api.getPreferencesPath()));
getFileNameFromPath(path:string, includeExtension:bool) → string [](/content/docs/tech-info/scripting/api-module/#getfilenamefrompath "Direct link to getfilenamefrompath"/index.html)
Return the file name from a path with an optional argument to include the file extension.
/// will return `file`
console.log(api.getFileNameFromPath("/path/to/file.png"));
/// will return `file.png`
console.log(api.getFileNameFromPath("/path/to/file.png", true));
getExtensionFromPath(path:string) → string [](/content/docs/tech-info/scripting/api-module/#getextensionfrompath "Direct link to getextensionfrompath"/index.html)
Return the extension of a file.
/// will return `.png`
console.log(api.getExtensionFromPath("/path/to/file.png"));
getFolderFromPath(path:string) → string [](/content/docs/tech-info/scripting/api-module/#getfolderfrompath "Direct link to getfolderfrompath"/index.html)
Return the containing folder of a file.
/// will return `/path/to`
console.log(api.getFolderFromPath("/path/to/file.png"));
makeFolder(path:string, overwriteExisting:string=false) → bool [](/content/docs/tech-info/scripting/api-module/#makefolder "Direct link to makefolder"/index.html)
Create a folder at the location given in path and return if the operation was a success. Set the 'overwriteExisting' argument to true to override the error and replace the existing file - proceed with caution.
// Update the example path below and uncomment the line
// var newFolder = api.makeFolder("/path/to/newFolder");
var message = "";
if (newFolder == true) {
message = "New folder created.";
}
else {
message = "New folder failed.";
}
console.log(message);
deleteFilePath(path:string) → bool [](/content/docs/tech-info/scripting/api-module/#deletefilepath "Direct link to deletefilepath"/index.html)
Delete a file from the file system and return true if successful. Typically this can be used for temporary files a user should never see.
danger
deleteFilePath instantly deletes files. They are not sent to the trash so there is no way to retrospectively recover them.
writeToFile(filePath:string, content:string, overwriteExisting:bool=false) → bool [](/content/docs/tech-info/scripting/api-module/#writetofile "Direct link to writetofile"/index.html)
Write a string to a file. Returns if the write was successful. If a file already exists, an error is returned. Set the 'overwriteExisting' argument to true to override the error and replace the existing file - proceed with caution.
Binary data cannot be written from this API, for that, please use writeEncodedToBinaryFile. filePathExists can also be used to add any additional success/warning messages to the console.
Backslashes
JavaScript does not support single backslashes (\) in file paths (it is an escape character) but slashes (/) are valid on Windows. Alternatively, replace single backslashes with double backslashes (\\).
// Export an .obj example
var primId = api.primitive("polygon", "My Polygon");
var mesh = api.get(primId, "polyMesh");
var objContents = "#this is an example obj export from Cavalry\n\n";
objContents += "o testShape\n\n";
var face = "f ";
var path = mesh.getPathAtIndex(0);
var pd = path.pathData();
var index = 1; // obj face index starts at 1
// Add vertices and vertex normals
for (var verb of pd) {
if (verb.type != "close") {
objContents += "v " + verb.point.x.toFixed(4) + " " + verb.point.y.toFixed(4) + " 0.0\n";
objContents += "vn 0.0 0.0 1.0\n"; // Normal vector for 2D plane
face += index + "//" + index + " "; // Vertex and normal indices
}
++index;
}
objContents += "\nusemtl None\n";
objContents += "s off\n";
objContents += face.trim() + "\n";
// This line is commented out as you will need to provide a file path
// api.writeToFile("/some/folder/test.obj", objContents);
writeEncodedToBinaryFile(filePath:string, content:string) → bool [](/content/docs/tech-info/scripting/api-module/#writeencodedtobinaryfile "Direct link to writeencodedtobinaryfile"/index.html)
Write a base64-encoded string to a file and return if the write was successful. Caution - this will overwrite any existing file.
Please note, only files encoded using encodeBinary will be properly decoded.
var encoded = api.encodeBinary("/some/folder/original.png");
api.writeEncodedToBinaryFile("/some/folder/copy.png", encoded);
readFromFile(filePath:string) → string [](/content/docs/tech-info/scripting/api-module/#readfromfile "Direct link to readfromfile"/index.html)
Read a file as a string.
// Please note this file path will need to point to an existing file.
var text = api.readFromFile("/some/folder/test.obj");
console.log(text);
encodeBinary(filePath:string) → string [](/content/docs/tech-info/scripting/api-module/#encodebinary "Direct link to encodebinary"/index.html)
Read a binary file (like an image), and encode it into base64. This can then be stored as a variable in JavaScript for use later (i.e with writeEncodedToBinaryFile).
// Please note this file path will need to point to an existing file.
var encoded = api.encodeBinary("/some/folder/test.png");
api.writeToFile("/some/folder/encoderDump.txt", encoded);
convertSVGToLayers(filename:string) → [string] [](/content/docs/tech-info/scripting/api-module/#convertsvgtolayers "Direct link to convertsvgtolayers"/index.html)
Convert an SVG file to Layers without the need to import the SVG as an asset first.
var svg = api.convertSVGToLayers("/path/to/filename.svg");
console.log(svg);
getFileModifiedDate(path:string) → number [](/content/docs/tech-info/scripting/api-module/#getfilemodifieddate "Direct link to getfilemodifieddate"/index.html)
Gets the last modified time of the file in milliseconds since epoch.
var mod = new Date(api.getFileModifiedDate("/path/to/file.mp4"));
console.log(mod.toDateString());
getFileSize(path:string) → number [](/content/docs/tech-info/scripting/api-module/#getfilesize "Direct link to getfilesize"/index.html)
Gets the file size in kilobytes (KB).
console.log(api.getFileSize("/path/to/file.mp4"));
isDirectory(path:string) → bool [](/content/docs/tech-info/scripting/api-module/#isdirectory "Direct link to isdirectory"/index.html)
Returns true if the path exists and is a directory.
listDirectoryPaths(path:string, includeDirectories:bool=false) → [string] [](/content/docs/tech-info/scripting/api-module/#listdirectorypaths "Direct link to listdirectorypaths"/index.html)
Returns all visible file paths in a directory, optionally including subdirectories.
isFile(path:string) → bool [](/content/docs/tech-info/scripting/api-module/#isfile "Direct link to isfile"/index.html)
Returns true if the path exists and is a regular file.
getAbsolutePath(path:string) → string [](/content/docs/tech-info/scripting/api-module/#getabsolutepath "Direct link to getabsolutepath"/index.html)
Returns an absolute, canonical path string, resolving any aliases/symlinks.
getRelativePath(fromPath:string, toPath:string) → string [](/content/docs/tech-info/scripting/api-module/#getrelativepath "Direct link to getrelativepath"/index.html)
Computes the relative path from one location to another.
listDirectory(path:string) → [string] [](/content/docs/tech-info/scripting/api-module/#listdirectory "Direct link to listdirectory"/index.html)
Returns an array of all file and folder paths directly under the given directory.
listDirectoryRecursive(path:string) → [string] [](/content/docs/tech-info/scripting/api-module/#listdirectoryrecursive "Direct link to listdirectoryrecursive"/index.html)
Returns an array of all file and folder paths under the given directory (recursively).
unzip(zipPath:string, destinationPath:string) → [string] [](/content/docs/tech-info/scripting/api-module/#unzip "Direct link to unzip"/index.html)
Unzips a zip file to a given location, returning a list of extracted top level files.
var zipContents = api.unzip("/path/to/example.zip", "/path/to/unzip/");
console.log(zipContents);
copyFilePath(fromPath:string, toPath:string) → bool [](/content/docs/tech-info/scripting/api-module/#copyfilepath "Direct link to copyfilepath"/index.html)
Copy a file from one specified path to another.
var copy = api.copyFilePath("/path/to/file.jpg", "/path/to/copy/file.jpg");
console.log(copy);
exportSceneAs(filePath:string) → bool [](/content/docs/tech-info/scripting/api-module/#exportsceneas "Direct link to exportsceneas"/index.html)
Export the current Scene to a specified file path. If a .cv file extension is not included it will be automatically added.
var exportAs = api.exportSceneAs("/path/to/file.cv");
console.log(exportAs);
exportSelected(filePath:string) → bool [](/content/docs/tech-info/scripting/api-module/#exportselected "Direct link to exportselected"/index.html)
Export any selected (and connected) Layers to a specified file path. If a .cvc file extension is not included it will be automatically added.
var exportSel = api.exportSelected("/path/to/file.cvc");
console.log(exportSel);
Utilities [](/content/docs/tech-info/scripting/api-module/#utilities "Direct link to Utilities"/index.html)
setClipboardText(stringToCopy:text) [](/content/docs/tech-info/scripting/api-module/#setclipboardtext "Direct link to setclipboardtext"/index.html)
Add a string to the clipboard.
api.setClipboardText("Copy test from Cavalry");
getClipboardText() → string
Return the contents of the clipboard as a string.
api.setClipboardText("Copy test from Cavalry");
console.log(api.getClipboardText());
runProcess(command:string, arguments:[string]) → object [](/content/docs/tech-info/scripting/api-module/#runprocess "Direct link to runprocess"/index.html)
This runs a system process and waits for the result which is returned as an object. GUI scripts that try to run this function will trigger a warning asking for users to trust the script. This is a blocking action, the UI will freeze until the process completes. For non blocking processes see runDetachedProcess below.
caution
Proceed with caution when running system processes to ensure scripts do not compromise system security.
// macOS example
var res = api.runProcess("sh", ["-c", "python3 --version"]);
if (res.error) {
console.log(res.error);
} else {
console.log(res.output);
}
// Windows example
// The command to run (the first argument) would be "cmd.exe" or "path/to/powerShell.exe" and so forth.
var res = api.runProcess("cmd.exe", ["/c echo hello world"]);
if (res.error) {
console.log(res.error);
} else {
console.log(res.output);
}
// Example converting a macOS filepath to Windows
// Set a path to convert
var iconPath = `${api.getAppAssetsPath()}/icons/transform@2x.png`;
// Convert the path to a native filepath (on Windows this will replace all / with \)
iconPath = api.toNativeFilePath(iconPath)
// Run an example command using that path
var result = api.runProcess("cmd.exe", ['/c', 'dir', iconPath]);
console.log(result.output);
// Example using a hard coded file path which requires escaped backslashes
// Note how each argument needs to be a separate entry in the argument array
result = api.runProcess("cmd.exe", ['/c', 'fsutil', 'file', 'queryfileid', 'C:\\Users\\YourUser\\Desktop\\AudioTest.mov']);
console.log(result.error);
console.log(result.output);
runDetachedProcess(command:string, arguments:[string]) [](/content/docs/tech-info/scripting/api-module/#rundetachedprocess "Direct link to rundetachedprocess"/index.html)
This runs a system process in a separate thread. GUI scripts that try to run this function will trigger a warning asking for users to trust the script. This is a non-blocking action.
caution
Proceed with caution when running system processes to ensure scripts do not compromise system security.
// macOS example
api.runDetachedProcess("sh", ["-c", "python3 --version"]);
// Windows example - the command to run (the first argument) would be e.g. "cmd.exe" or "path/to/powerShell.exe".
api.runDetachedProcess("cmd.exe", ["/c echo hello world"]);
openURL(url:string) [](/content/docs/tech-info/scripting/api-module/#openurl "Direct link to openurl"/index.html)
Open a URL in a browser.
api.openURL("http://cavalry.studio");
api.openURL('file:///Users/User/Desktop');
isGuiSession() → bool
Returns true if this is a GUI session of the app, and false if not (e.g the CLI is running).
console.log(api.isGuiSession());
getPlatform() → string
Get the current hardware platform. This will return either macOS or Windows
console.log(api.getPlatform());
getSystemInfo() → {cpu:string, os:string, uniqueId:string} [](/content/docs/tech-info/scripting/api-module/#getsysteminfo "Direct link to getsysteminfo"/index.html)
Return the current hardware system info as an object with the following keys:
- cpu - The current CPU architecture (e.g. "arm64").
- os - The current OS (e.g. "macos").
- uniqueId - A unique identifier that can be used to track a machine for an extended period of time – useful for network operations. Note that this value may change between reboots.
console.log(JSON.stringify(api.getSystemInfo()));
getCavalryVersion() → string
Return the Cavalry version as a string (e.g. "1.5.6").
console.log(api.getCavalryVersion());
toNativeFilePath(filePath:string) → string [](/content/docs/tech-info/scripting/api-module/#tonativefilepath "Direct link to tonativefilepath"/index.html)
Convert a macOS file path to a Windows file path. This replaces / with \ (and escapes them as needed).
console.log(api.toNativeFilePath("/path/to/my folder"));
// This will return "\path\to\my folder" on Windows.
serialise(layerIds:[string], withConnections:bool) [](/content/docs/tech-info/scripting/api-module/#serialise "Direct link to serialise"/index.html)
Convert a list of Layers into their 'save file' representation.
The first argument is an array of strings [string] containing the Layers to be serialised. The second argument is withConnections - if this is true, any input connections will also be serialised. For example, if a Shape in the array is connected to a Color Array, setting withConnections to true will also serialise the Color Array.
var primId = api.primitive("polygon", "My Polygon");
api.set(primId, {"material.materialColor": "#8dc429"});
api.writeToFile("/Users/username/Desktop/textExport.txt", api.serialise([primId], false));
Save as .cvc
By saving serialised files with a .cvc extension, they can then be imported back into a Scene via the File > Import Scene... menu. Files saved with any other extension can be imported using the deserialised function.
deserialise(json:string) [](/content/docs/tech-info/scripting/api-module/#deserialise "Direct link to deserialise"/index.html)
Deserialise a JSON string to Layers. This function is the opposite of serialise.
// Select a Layer
var sel = api.getSelection();
var str = api.serialise(sel, true);
api.deserialise(str);
setPreferenceObject(key:string, preferences:object) [](/content/docs/tech-info/scripting/api-module/#setpreferenceobject "Direct link to setpreferenceobject"/index.html)
Save a preference.
var hello = {first:"Hello, ", second:"World", third:"!"};
api.setPreferenceObject("testKey", hello);
hasPreferenceObject(key:string) → bool [](/content/docs/tech-info/scripting/api-module/#haspreferenceobject "Direct link to haspreferenceobject"/index.html)
Query to see if preference exists.
var hello = {first:"Hello, ", second:"World", third:"!"};
api.setPreferenceObject("testKey", hello);
console.log( api.hasPreferenceObject("testKey") );
getPreferenceObject(key:string) → object [](/content/docs/tech-info/scripting/api-module/#getpreferenceobject "Direct link to getpreferenceobject"/index.html)
Return any existing preferences.
var hello = {first:"Hello, ", second:"World", third:"!"};
api.setPreferenceObject("testKey", hello);
var myPrefs = api.getPreferenceObject("testKey");
console.log(myPrefs.first+myPrefs.second+myPrefs.third);
setUserData(layerId:string, key:string, value:object) [](/content/docs/tech-info/scripting/api-module/#setuserdata "Direct link to setuserdata"/index.html)
Save arbitrary data to a Layer. This could be a string, or an object.
// Save String
var primId1 = api.primitive("star", "Star");
api.setUserData(primId1, "test", "Hello, World!");
console.log(api.getUserDataKey(primId1, "test"));
// Save Object
var primId2 = api.primitive("star", "Star");
api.setUserData(primId2, "test", {type:'Software', model:'Cavalry', starRating:5});
var data = api.getUserDataKey(primId2, "test")
console.log(data.model);
hasUserDataKey(layerId:string, key:string) → bool [](/content/docs/tech-info/scripting/api-module/#hasuserdatakey "Direct link to hasuserdatakey"/index.html)
Checks if a specific key exists within the user data of a specified Layer.
var primId = api.primitive("star", "Star");
api.setUserData(primId, "test", "Hello, World!");
console.log(api.hasUserDataKey(primId, "test"));
getUserDataKey(layerId:string, key:string) → object [](/content/docs/tech-info/scripting/api-module/#getuserdatakey "Direct link to getuserdatakey"/index.html)
Return any existing user data for the given key.
var primId = api.primitive("star", "Star");
api.setUserData(primId, "test", "Hello, World!");
console.log(api.getUserDataKey(primId, "test"));
uuid() → string
Return a UUIDv4 string.
getLayerFromUUID(uuid:string) → string [](/content/docs/tech-info/scripting/api-module/#getlayerfromuuid "Direct link to getlayerfromuuid"/index.html)
Each Layer in Cavalry has a unique identifier (a UUID). Layers based on the UUID can be identified with this API. See the example for how to get a UUID from a Layer.
var primId = api.primitive("star", "Star")
var uuid = api.get(primId, "uuid")
var idCheck = api.getLayerFromUUID(uuid);
console.log(primId+" === "+idCheck);
Timer(callback:object) [](/content/docs/tech-info/scripting/api-module/#timer "Direct link to timer"/index.html)
Timers can be used in UI scripts and can be useful for polling Web APIs. When the Timer is triggered it will call an onTimeout() function on the Timer object. Implement this function to have the Timer execute logic when this happens.
Functions:
start()// start the timer.stop()// stop the timer.isActive()// returns if the timer is currently running.setInterval(interval:int)// set how long the timer is (in milliseconds).setRepeating(repeat:bool)// set if the timer is repeating (trueby default).onTimeout()// Implement this callback function on a timer object and it will be called when the timer runs out.
// Define a callback class to be used by the timer
function Callbacks() {
// This callback will be called whenever the timer times out
this.onTimeout = function () {
console.log("Timer Expired");
}
}
// Create the callback class
var callbackObj = new Callbacks();
// Make the timer and feed it the callback object
var timer = new api.Timer(callbackObj);
isAltHeld() → bool
Check if the Option/Alt key is held down.
info
isAltHeld() cannot be tested in the JavaScript Editor. It can only be tested in a Script run from the Script menu, or from a UI script launched from the JavaScript Editor. This is because Cavalry intercepts Option/Alt clicks for native actions.
isShiftHeld() → bool
Check if the Shift key is held down.
isControlHeld() → bool
Check if the Control (Windows) or ⌘ command (macOS) key is held down.
isMetaHeld() → bool
Check if the Meta (Windows) or control (macOS) key is held down. Note that this deviates from the standard where Meta refers to the ⌘ command key.
getAllLayerTypes(includeExperimentalTypes:bool) → [object] [](/content/docs/tech-info/scripting/api-module/#getalllayertypes "Direct link to getalllayertypes"/index.html)
Return all the user facing types and names of Layers in Cavalry.
var layerTypes = api.getAllLayerTypes(false);
for (data of layerTypes) {
console.log(data.name + ". Type: " + data.type);
}
// data.type - the internal Layer type.
// data.name - the English name of the Layer.
getSuperTypes(layerId:string) → [string] [](/content/docs/tech-info/scripting/api-module/#getsupertypes "Direct link to getsupertypes"/index.html)
Return the SuperTypes of a Layer.
var ellipseId = api.primitive("ellipse", "Ellipse");
console.log(api.getSuperTypes(ellipseId));
encrypt(textToEncrypt:string) → string [](/content/docs/tech-info/scripting/api-module/#encrypt "Direct link to encrypt"/index.html)
Encrypt text. Useful for script authors to automate the encryption of scripts.
console.log(api.encrypt("Hello."));
processEvents()
Flush the event queue to ensure all pending GUI updates have finished.
setCavalryPreference(key:string, value:object) [](/content/docs/tech-info/scripting/api-module/#setcavalrypreference "Direct link to setcavalrypreference"/index.html)
Set a Cavalry preference. Open Preferences.json via 'Help > Show Preferences Folder' for all available preference keys.
api.setCavalryPreference("showGrid", true);
api.setCavalryPreference("gridColor", "#4df24c3d");
getCavalryPreference(key:string) → value:object [](/content/docs/tech-info/scripting/api-module/#getcavalrypreference "Direct link to getcavalrypreference"/index.html)
Get a Cavalry preference's setting or null if there is no preference with the given key or the preference type is unsupported. Open Preferences.json via 'Help > Show Preferences Folder' for all available preference keys.
console.log(api.getCavalryPreference("fontSize"));
saveViewportContentsAsImage(filePath:string) [](/content/docs/tech-info/scripting/api-module/#saveviewportcontentsasimage "Direct link to saveviewportcontentsasimage"/index.html)
Saves the contents of the viewport to a PNG.
encryptFile(filePath:string, newFilePath:string) [](/content/docs/tech-info/scripting/api-module/#encryptfile "Direct link to encryptfile"/index.html)
Encrypts the given file, and saves it to the specified location.
api.encryptFile("path/to/file.sksl", "path/to/encryptedFile.skslc");
isRestrictedLicence() → bool
Returns true if a Starter (free) licence is in use.
updateAppTitleBar()
Force the app's title bar to update. This can be used to e.g. trigger Restricted Mode for Starter users when Pro features are added to a Composition.
getActiveTool() → string
Returns the viewport's active tool.
console.log(api.getActiveTool())