コンテンツにスキップ

API モジュール

以下の API はすべて api 名前空間にあります。 これらは JavaScript Editor でのみ使用可能で、 JavaScript Layers.

この名前空間のすべてのコマンドは api. で始める必要があります。例: api.create("null", "My Null");

この API は Web と通信し( Web APIsを参照)、シェルコマンドを実行できます。 runProcess を参照してください。

レイヤーと属性を扱う際には、layerIdattrId を知ることが重要です。

layerId を見つけるには:

  1. Right click on a layer in the Viewport, Scene Window or its header bar in the Attribute Editor.
  2. Copy Layer Id を選択します。

これによりレイヤーの Id がクリップボードにコピーされます。

attrId を見つけるには:

  1. Right click on an attribute in the Attribute Editor.
  2. コンテキストメニューから Copy Scripting Path を選択します。
  3. リストからオプションを選択してクリックします。

これにより属性の Id がクリップボードにコピーされます。

これらの Id はスクリプト内で使用できます。以下の例では, basicShape#1layerId で、 position.xattrId です。

api.get("basicShape#1", "position.x");

プレイヘッドを特定のフレームに移動します。

// Move the playhead to frame 100api.setFrame(100);

プレイヘッドがあるフレーム番号を返します。

// Move the playhead to frame 50 and then print that frame number to the Console.api.setFrame(50);console.log(api.getFrame());

再生を開始します。

再生を停止します(UI スクリプトから呼び出す必要があります)。

アクティブな Composition からすべてのレイヤー Id を返し、‘トップレベル’レイヤーでフィルタリングするオプションがあります。

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: 1console.log(topLevelIds.length)// Get all the layers in the compositionvar allIds = api.getCompLayers(false);// Prints: 2console.log(allIds.length)

アクティブな Composition 内の特定のタイプのすべてのレイヤーを返します。

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));}

指定されたレイヤーの親 Composition の Id を返します。

var shapeId = api.create("basicShape");console.log(api.getParentComp(shapeId));

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 aroundvar 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");

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)}

A convenience function for removing Time Markers. This forwards to api.Layer(layerId).

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);

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);

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.

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.

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())));

Get a list of all the Attributes that have been added to the Control Centre.

console.log(api.getControlCentreAttributes(api.getActiveComp()));

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));

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));

Creates a Primitive Shape.

/// returns the layerId for the new shapevar primId = api.primitive("rectangle", "My Rectangle");

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 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);

Delete a Layer.

/// Delete all render queue itemsvar items = api.getRenderQueueItems();for (var layer of items) { api.deleteLayer(layer);}

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()));

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));

Returns true if the given Layer is from an external developer.

Reset all Attributes on a Layer back to the default state.

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));}

Selects the specified Layers.

var primId = api.primitive("rectangle", "My Rectangle");api.select([primId]);

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 a Layer with an option to also duplicate any input connections.

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)

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);

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");

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));

Return the ‘nice name’ of a Layer.

var nullId = api.create("null", "My Null");console.log(api.getNiceName(nullId));

Rename a Layer.

/// rename all selected itemsvar sel = api.getSelection();sel.forEach(function (item, index) { api.rename(item, "My Name "+index);});

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);

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});

Returns true if a Shape has a Stroke.

var primId = api.primitive("rectangle", "Rectangle");api.setStroke(primId, true);console.log(api.hasStroke(primId));

Enable/disable the Fill for a Shape.

var primId = api.primitive("rectangle", "Rectangle");api.setFill(primId, false);api.setStroke(primId, true);

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}

「getBoundingBox(layerId:string, worldSpace:bool) → {x:number, y:number, width:number, height:number, centre:{x:number, y:number}, left:number, right:number, top:number, bottom:number}」という見出しのセクション

Return the bounding box of the specified Layer.

var primId = api.primitive("polygon", "My Polygon");var bbox = api.getBoundingBox(primId, true);console.log(JSON.stringify(bbox));

getSelectionBoundingBox() → {x:number, y:number, width:number, height:number, centre:{x:number, y:number}, left:number, right:number, top:number, bottom:number}

「getSelectionBoundingBox() → {x:number, y:number, width:number, height:number, centre:{x:number, y:number}, left:number, right:number, top:number, bottom:number}」という見出しのセクション

Return the world space bounding box of the selected Layers.

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));

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));

Returns true if a specified Layer has transform Attributes (e.g. Position and Scale).

Returns true if a specified Layer has its 3d transform Attributes activated.

Return the first frame of a Clip.

var sel = api.getSelection();for (let layerId of sel) { console.log(api.getInFrame(layerId));}

Set the first frame of a Clip.

var layerId = api.primitive("rectangle", "Rectangle");api.setInFrame(layerId, 50);

Return the last frame of a Clip.

var sel = api.getSelection();for (let layerId of sel) { console.log(api.getOutFrame(layerId));}

Set the last frame of a Clip.

var layerId = api.primitive("rectangle", "Rectangle");api.setOutFrame(layerId, 50);

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));

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());

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());

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();

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();

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();

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();

Checks if a specified Layer is a Shape.

var shape1 = api.primitive("ellipse", "Ellipse");console.log(api.isShape(shape1));

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);

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 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");

Returns the version of a specified Layer – useful for third-party developers.

Returns true if the first version is less than the second version.

let isLower = api.compareVersions("1.0", "2.0");console.log(isLower) // trueisLower = api.compareVersions("3.0.1", "3.0");console.log(isLower) // false

Returns true if the specified layer requires a Pro licence to use.

console.debug(api.isProLayerType("extrude"));

Load the given Layer’s UI into the Attribute Editor.

var shapeId = api.create("basicShape");api.showInAttributeEditor(shapeId);

Clear the Attribute Editor.

api.clearAttributeEditor();

Returns true if the Composition layer has been imported as part of a Reference.

// Via Assets Windowvar 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 Windowvar 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));

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 values for a Layer’s attributes.

// Create a Rectangle and set its Size, Position, Rotation and Fill Colorvar 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 Stylevar textId = api.create("textShape", "My Text");api.set(textId, {"font":{"font":"Arial", "style":"Bold"}});
// Collapse the hierarchy of a layerapi.set("basicShape#1", {"hierarchy": false});

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))

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 Id
  • type // e.g double, string, int2
  • prefix // the prefix used in the UI
  • placeholder // a string attribute’s placeholder (e.g. A Stroke’s Dash Pattern contains Dash, Gap (e.g. “4, 2“))
  • isAttrReadOnly // true if the attribute is read only
  • allowsAspectRatioLocking // the attribute’s proportions can be constrained
  • numericInfo // an object where any of the child keys can be null
    • hardMin // the minimum value allowed
    • hardMax // the maximum value allowed
    • softMin // the minimum value that can be set by scrubbing in the UI
    • softMax // the maximum value that can be set by scrubbing in the UI
    • step // the increment values increase/decrease when scrubbing
    • isBound // this checks if hardMin and hardMax exist. i.e. the attributeis a slider
  • multiline // true if the attribute is a multi-line string
  • enumValues // the valid indices for dropdown attributes
  • children // child attribute definitions (for example position attributes have three children, x, y and z).
  • isArray // true if the attribute is an array
  • isCompound // 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.

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 upvar ellipseId = api.primitive("ellipse", "Ellipse");api.set(ellipseId, {"generator.radius.x": 10, "generator.radius.y": 10, "hidden": true});// Create a Duplicatorvar duplicatorId = api.create("duplicator", "Duplicator");// Connect the Ellipse to the Duplicatorapi.connect(ellipseId, "id", duplicatorId, "shapes");// Change the Distribution on the Duplicator to a Custom Distributionapi.setGenerator(duplicatorId, "generator", "circleDistribution");// Set the Distribution countapi.set(duplicatorId, {"generator.count": 10});

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"));

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);}

Returns the current Generator type (which can be used with setGenerator).

var ellipseId = api.primitive("ellipse", "My Ellipse")console.log(api.getCurrentGeneratorType(ellipseId, "generator"))

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 Rectangleapi.connect(starId, "position.y", rectId, "position.y");// Add an attribute expressionapi.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 Oscillatorvar oscillatorId = api.create("oscillator", "Oscillator");api.set(oscillatorId, {"strength": 1500});api.connect(oscillatorId, "id", starId, "position.y");api.play();

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"));

Returns an Attribute’s Attribute Expression.

var rectId = api.primitive("rectangle", "Rectangle");api.connect(rectId, "position.x", rectId, "position.y");api.setAttributeExpression(rectId, "position.y", "*2");console.log(api.getAttributeExpression(rectId, "position.y"));

connect(fromLayerId:string, fromAttrId:string, toLayerId:string, toAttrId:string, force:bool)

「connect(fromLayerId:string, fromAttrId:string, toLayerId:string, toAttrId:string, force:bool)」という見出しのセクション

Connect one attribute to another. The result or output of a Layer is referred to as the id connection. Optionally forcing a connection will overwrite any existing connections.

var starId = api.primitive("star", "Star");var ellipseId = api.primitive("ellipse", "Ellipse");var pathfinderId = api.create("pathfinder", "Pathfinder");api.set(starId, {"generator.radius": 300});api.set(ellipseId, {"generator.radius": [50,50], "material.materialColor": "#4ffd7a"});// Connect the result of the Star to the Pathfinderapi.connect(starId, "id", pathfinderId, "inputShape");// Connect the result of the Pathfinder to the Text.Positionapi.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)

「disconnect(fromLayerId:string, fromAttrId:string, toLayerId:string, toAttrId:string)」という見出しのセクション

Remove connections between attributes.

var primId = api.primitive("rectangle", "Rectangle");var oscillatorId = api.create("oscillator", "Oscillator");api.connect(oscillatorId, "id", primId, "rotation");console.log(api.getInConnection(primId, "rotation"));api.disconnect(oscillatorId, "id", primId, "rotation");console.log(api.getInConnection(primId, "rotation"));

Disconnect an Attribute’s input connection.

api.disconnectInput("basicShape#1", "position.x");

Disconnect all the output connections from an Attribute.

api.disconnectOutputs("basicShape#1", "position.x");

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"));

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"));

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);}

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"]});

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);

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 integer 0 Bezier, 1 Linear, 2 Step (optional).

Example of modifying keyframe values and frames:

var primId = api.primitive("rectangle", "My Rectangle");api.keyframe(primId, 0, {"scale.x": 5.});api.keyframe(primId, 100, {"scale.x": 1.});api.modifyKeyframe(primId, {"scale.x": {"frame": 0, "newValue": 3.5, "newFrame": 10}});

Example of setting all keyframes to step interpolation.

var ellipseId = api.primitive("ellipse", "Ellipse");// Create some values to set as keyframesvar keyValues = [-200,200,-300, 300]var keyTime = 0;// Set some keyframes for us to modifyfor (let value of keyValues) { api.keyframe(ellipseId, keyTime, {"position.x":value}); keyTime+=40;}// Get the keyframe timesvar 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}});}

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 ellipsevar ellipseId = api.primitive("ellipse", "Ellipse");// Create some values to set as keyframesvar keyValues = [-200,200,-300, 300]var keyTime = 0;// Set some keyframes for us to modifyfor (let value of keyValues) { api.keyframe(ellipseId, keyTime, {"position.x":value}); keyTime+=40;}// Get the keyframe timesvar 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 Shapevar ellipseId = api.primitive("ellipse", "Ellipse");// Store some values to set as keyframesvar keyValues = [-200,200,-300, 300]var keyTime = 0;// Set some keyframes to modifyfor (let value of keyValues) { api.keyframe(ellipseId, keyTime, {"position.x":value}); keyTime+=40;}// Get the keyframe timesvar 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}});}

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 }});

Reset all four speed/influence fields on a keyframe.

api.clearKeyframeVelocity("basicShape#1", {"position.x": { frame: 30 }});

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"));

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());

Set the keyframe selection. To clear the keyframe selection send an empty array through.

// Create a Shape and add some keyframes to scale.xvar 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"]);

Get the attribute path for a given keyframe.

var keyIds = api.getSelectedKeyframeIds();for (let keyId of keyIds) { console.log(api.getAttributeFromKeyframeId(keyId))}

Resynchronise path keyframe data after using set() on Path Animation keyframes.

magicEasing(layerId:string, attrId:string, frame:int, easingName:string, expression:string)

「magicEasing(layerId:string, attrId:string, frame:int, easingName:string, expression:string)」という見出しのセクション

Apply Magic Easing to an Attribute’s keyframe and optionally add an expression.

// Add SlowOut Magic Easingvar 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 Easingvar 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”

Get the keyframe times for an attribute.

Delete all keyframes on an attribute.

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"));

Reset an Attribute back to its default value.

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});

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

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, Purpleapi.reorderArrayAttr(colorId, "array", 2, 0);// Purple, Green, Yellow

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"));

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 Attributevar 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);

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"));

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"));

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);

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);

Rename a specified Attribute for a Layer.

var arrayId = api.create("valueArray", "My Value Array");api.renameAttribute(arrayId, "array.0", "Example Name");

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"));

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));

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);

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);

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);}

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.

Deselect attributes by their full paths (e.g., “layerId.attrId.subAttr”).

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);

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);}

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"));

Sets a preset for a Graph Attribute. The preset index can be: 0: s-curve 1: ramp 2: linear 3: flat

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");

Add an attribute to the Control Centre.

var shapeId = api.create("null", "My Null");api.addToControlCentre(shapeId, "position.x");

Remove an attribute from the Control Centre.

//Create a Null and add position.x to Control Centrevar 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 Centreapi.removeFromControlCentre("null#1", "position.x");

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");

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 Overrideapi.removePreCompOverride(layerId, "generator.radius");var numOfOverridesAfterRemove = api.listPreCompOverrides(preCompId).lengthconsole.log("Overrides after add: " + numOfOverrides + ". Overrides after remove: " + numOfOverridesAfterRemove)

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")));

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"]);

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);

Returns true if an attribute value matches its default value.

areAttributeValuesEqual(layerId1:string, attrId1:string, layerId2:string, attrId2:string) → bool

「areAttributeValuesEqual(layerId1:string, attrId1:string, layerId2:string, attrId2:string) → bool」という見出しのセクション

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")); // trueapi.set(grad1id, {"alpha": 50});console.log(api.areAttributeValuesEqual(grad1id, "alpha", grad2id, "alpha")); // falseconsole.log(api.areAttributeValuesEqual(grad1id, "generator.gradient", grad2id, "generator.gradient")); // trueapi.set(grad1id, {"generator.gradient.0.color": "#d9695f"});console.log(api.areAttributeValuesEqual(grad1id, "generator.gradient", grad2id, "generator.gradient")); // false

Return true if an attribute has any definition overrides (limits).

Clear all definition overrides (limits) for an attribute.

getAttributeDefinitionOverride(layerId:string, attrId:string, key:string) → number|null

「getAttributeDefinitionOverride(layerId:string, attrId:string, key:string) → number|null」という見出しのセクション

Get a definition override (limit) for an attribute.

keys: “hardMin”, “hardMax”, “softMin”, “softMax”, “step”

setAttributeDefinitionOverride(layerId:string, attrId:string, key:string, value:number)

「setAttributeDefinitionOverride(layerId:string, attrId:string, key:string, value:number)」という見出しのセクション

Set a definition override (limit) for an attribute.

keys: “hardMin”, “hardMax”, “softMin”, “softMax”, “step”

Get the attribute definition including any overrides which can be set via Edit Limits… in the UI.

Centre the Pivot of the specified Layer. If Centroid is true the Pivot will be moved to the centre of mass.

Returns the position of a specified Layer’s pivot in local or world space.

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.

Reset a Shape’s transform back to the default state (this will also clear any frozen transformations).

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 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);

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);

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);

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);}

This will make the selected point the first point in an Editable Path. This is like running the command in the Shape menu.

Move selected points by given X and Y values.

//select some editable pointsapi.movePoint(0,50, true);

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 pointsapi.setPointPosition({"y":-50}, false, false)api.setPointPosition({"y":-50}, false, true)

Render a specific Render Queue Item.

var itemId = api.addRenderQueueItem(api.getActiveComp());api.render(itemId);

Render all Render Queue Items in the Render Manager.

api.addRenderQueueItem(api.getActiveComp());api.renderAll();

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 selectionvar 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 soloingapi.soloLayers([]);

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.

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);}

Add a new Render Queue Item to the Render Manager.

var itemId = api.addRenderQueueItem(api.getActiveComp());console.log(itemId);

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});

Return the current Dynamic Index.

console.log(api.getDynamicIndex());

Set the Render Manager’s Dynamic Index Offset.

api.setDynamicIndexOffset(10);

Render a specific Render Queue Item in the background. Note - there are no notifications for the render’s status.

Render all (active) Render Queue Items in the background. Note - there are no notifications for the render’s status.

Cancel the current render.

Opens a new Scene, discarding any changes to the current Scene.

Open a Scene at the given location, this may present a Save Changes dialog unless force is set to true.

Save the current Scene to a new location and return a boolean to confirm if it was successful.

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.

Return true if there have been any changes made to the Scene since the last save.

console.log(api.sceneHasUnsavedChanges());

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");

Load an asset with the given path. Set isSequence to true to attempt to load an image sequence from the file path.

// Load an imageapi.loadAsset("/Path/To/image.png", false);// Load an image sequenceapi.loadAsset("/Path/To/sequence.00000.png", true);

Load a Smart Folder Asset from a file path. The type can be ‘image’ or ‘audio’.

// Load an Image Smart Folderapi.loadSmartFolderAsset("/path/to/smartfolder.png", 'image');

Reloads an Asset with the given assetId

// First load an Asset, then run:api.reloadAsset("asset#2");

Replace a file asset (e.g an image or CSV file).

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/videovar assetId = api.loadAsset("/image.png", false);// Create the Footage Shapevar footageId = api.addAssetToComp(assetId);// Find the Image Shader (e.g. to rename it).var imageShaderId = api.getChildren(footageId);

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);

Given a Text Asset, get the raw string that Asset represents.

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.

The spreadsheetId and sheetId can be extracted from a Google Sheet’s URL:

https://docs.google.com/spreadsheets/d/[spreadsheetId]/edit#gid=[sheetId]

Replace an existing Google Sheet Asset with another. If the sheetId argument is left blank (e.g. "") then the first sheet will be loaded.

Returns true if the Asset is a file asset (image, video, audio, Smart Folder etc.). A Google Sheet, Composition or Group will return false.

Returns the ICC profile name of an image/video asset. Returns an empty string for sRGB or untagged images.

Returns true if the Asset is a Google Sheet.

Returns the name of the font family associated with a Font Asset.

Returns the name of the font style associated with a Font Asset.

Set the location of projectDescription.json in order to use relative filepaths.

api.setProject("path/to/project");

Clear the Project.

api.clearProject();

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());

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);}

Create a new composition and return its id.

api.createComp("Shiny New Comp");

Set the currently active composition.

var newCompId = api.createComp("Shiny New Comp");api.setActiveComp(newCompId);

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");

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"});

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);

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);}

Return the asset type (i.e image, audio, spreadsheet, movie, svg).

// First load an Asset, then run:console.log(api.getAssetType("asset#2"));

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)); }}

Retrieves all the file paths from an image sequence Asset.

// Select an Image Sequence in the Assets Windowvar assetId = api.getSelection();console.log(api.getImageSequenceFilePaths(assetId[0]));

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)); }}

Create a Group in the Assets Window, this will return the layerId of the new Group.

api.createAssetGroup("My Asset Group");

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 selectionvar 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 soloingapi.soloLayers([]);

Return a list of all Layers in a Scene.

var layers = api.getAllSceneLayers();for (layer of layers) { console.log(layer);}

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.

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.jsfunction helloWorld() { console.log("Hello World.");}
// Then in Cavalryapi.load("path/to/script.js");helloWorld();

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 buttonvar button = new ui.Button("Import File");// Set the onClick callback functionbutton.onClick = function () { console.log(api.presentOpenFile(api.getProjectPath(), "Import JSON or CSV", "Data File (*.json *.csv)"));}// Add the button to the layoutui.add(button);// Show the windowui.show();

presentSaveFile(startPath:string, title:string, fileFilter:string, defaultFileName:string) → string

「presentSaveFile(startPath:string, title:string, fileFilter:string, defaultFileName:string) → string」という見出しのセクション

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 buttonvar button = new ui.Button("Save File");// Set the onClick callback functionbutton.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 layoutui.add(button);// Show the windowui.show();
// Example including a filter for multiple file types// Create a buttonvar button = new ui.Button("Save File");// Set the onClick callback functionbutton.onClick = function () { console.log(api.presentSaveFile(api.getProjectPath(), "Save Data", "JSON File (*.json);;CSV File (*.csv)", "Config File"));}// Add the button to the layoutui.add(button);// Show the windowui.show()

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);

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)

Gets the Project path (if a Project is set). This path does not include a trailing /

console.log(api.getProjectPath());

Gets the Render path (if a Project is set). This path does not include a trailing /

console.log(api.getRenderPath());

Gets the Project Asset path (if a Project is set). This path does not include a trailing /

console.log(api.getAssetPath());

Gets the Project Asset path (if a Project is set). This path does not include a trailing /

console.log(api.getPalettesPath());

Gets the Scene’s path (if a Project is set). This path does not include a trailing /

console.log(api.getScenesPath());

If the current Scene has been saved this will return its filepath, otherwise it will return an empty string.

console.log(api.getSceneFilePath());

Get the location of the Cavalry preferences folder.

console.log(api.getPreferencesPath());

Get the location of the Cavalry Presets folder.

console.log(api.getPresetsPath());

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();

Get the location of the User’s home directory.

console.log(api.getHomeFolder());

Get the location of the user’s desktop directory.

console.log(api.getDesktopFolder());

Get the location of the User’s ‘Downloads’ directory.

console.log(api.getDownloadsFolder());

Get the location of the User’s ‘Fonts’ directory.

console.log(api.getFontsFolder());

Get the location of the temporary files directory.

console.log(api.getTempFolder());

Get the location of the user’s preferences/configuration directory.

console.log(api.getPreferencesFolder());

Get the location of the user’s application data directory.

console.log(api.getAppDataFolder());

Return whether a path to a file or folder exists.

console.log(api.filePathExists(api.getPreferencesPath()));

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));

Return the extension of a file.

/// will return `.png`console.log(api.getExtensionFromPath("/path/to/file.png"));

Return the containing folder of a file.

/// will return `/path/to`console.log(api.getFolderFromPath("/path/to/file.png"));

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);

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.

deleteFilePath instantly deletes files. They are not sent to the trash so there is no way to retrospectively recover them.

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.

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 examplevar 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 normalsfor (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);

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);

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);

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);

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);

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());

Gets the file size in kilobytes (KB).

console.log(api.getFileSize("/path/to/file.mp4"));

Returns true if the path exists and is a directory.

Returns all visible file paths in a directory, optionally including subdirectories.

Returns true if the path exists and is a regular file.

Returns an absolute, canonical path string, resolving any aliases/symlinks.

Computes the relative path from one location to another.

Returns an array of all file and folder paths directly under the given directory.

Returns an array of all file and folder paths under the given directory (recursively).

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);

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);

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);

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);

Add a string to the clipboard.

api.setClipboardText("Copy test from Cavalry");

Return the contents of the clipboard as a string.

api.setClipboardText("Copy test from Cavalry");console.log(api.getClipboardText());

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 を参照してください。

Proceed with caution when running system processes to ensure scripts do not compromise system security.

// macOS examplevar 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 convertvar 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 pathvar 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 arrayresult = api.runProcess("cmd.exe", ['/c', 'fsutil', 'file', 'queryfileid', 'C:\\Users\\YourUser\\Desktop\\AudioTest.mov']);console.log(result.error);console.log(result.output);

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.

Proceed with caution when running system processes to ensure scripts do not compromise system security.

// macOS exampleapi.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"]);

Open a URL in a browser.

api.openURL("http://cavalry.studio");api.openURL('file:///Users/User/Desktop');

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());

Get the current hardware platform. This will return either macOS or Windows

console.log(api.getPlatform());

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()));

Return the Cavalry version as a string (e.g. “1.5.6”).

console.log(api.getCavalryVersion());

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.

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));

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 a JSON string to Layers. This function is the opposite of serialise.

// Select a Layervar sel = api.getSelection();var str = api.serialise(sel, true);api.deserialise(str);

Save a preference.

var hello = {first:"Hello, ", second:"World", third:"!"};api.setPreferenceObject("testKey", hello);

Query to see if preference exists.

var hello = {first:"Hello, ", second:"World", third:"!"};api.setPreferenceObject("testKey", hello);console.log( api.hasPreferenceObject("testKey") );

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);

Save arbitrary data to a Layer. This could be a string, or an object.

// Save Stringvar primId1 = api.primitive("star", "Star");api.setUserData(primId1, "test", "Hello, World!");console.log(api.getUserDataKey(primId1, "test"));// Save Objectvar 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);

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"));

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"));

Return a UUIDv4 string.

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);

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 (true by 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 timerfunction Callbacks() { // This callback will be called whenever the timer times out this.onTimeout = function () { console.log("Timer Expired"); }}// Create the callback classvar callbackObj = new Callbacks();// Make the timer and feed it the callback objectvar timer = new api.Timer(callbackObj);

Check if the Option/Alt key is held down.

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.

Check if the Shift key is held down.

Check if the Control (Windows) or ⌘ command (macOS) key is held down.

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.

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.

Return the SuperTypes of a Layer.

var ellipseId = api.primitive("ellipse", "Ellipse");console.log(api.getSuperTypes(ellipseId));

Encrypt text. Useful for script authors to automate the encryption of scripts.

console.log(api.encrypt("Hello."));

Flush the event queue to ensure all pending GUI updates have finished.

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");

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"));

Saves the contents of the viewport to a PNG.

Encrypts the given file, and saves it to the specified location.

api.encryptFile("path/to/file.sksl", "path/to/encryptedFile.skslc");

Returns true if a Starter (free) licence is in use.

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.

Returns the viewport’s active tool.

console.log(api.getActiveTool())