Skip to main content

Cavalry Module

Pro Feature

Pro features are only available with a Professional licence. To upgrade, visit cavalry.scenegroup.co.

Introduction

This module gives access to the Path class, functions for creating noise and random numbers along with a number of utilities to make working with color easier, and, a whole host of maths functions such as clamp, norm, map and dist. The following methods are available to the JavaScript Utility, and the JavaScript Editor. Everything in this module is in the cavalry namespace and so methods need prefixing with cavalry. e.g var distance = cavalry.dist(0,0,100,200);

The examples given are for use in the JavaScript Editor (less setup required to run examples).

Member Functions

Path Class

The Cavalry module contains a Path class which can be used to construct paths which can then be drawn on screen. Path itself contains several methods.

Several of these methods use the word 'param' or 'parameter'. This is a number between 0..1 which represents a progression along the curve's control cage from 0 (the beginning) to 1 (the end). The control cage, formed by the curve's control points, outlines the basic shape of the curve. Note that a 'param' value of 0.5 does not necessarily represent a position half way along the curve. This is because the relationship between the param value and the curve's length is not linear due to the influence of the curve's control points and its resulting shape. To convert length values into param values, use paramAtLength.

Copying Shapes

Right clicking on a Shape in the Viewport and choosing Copy as JavaScript will copy the Shape's information to the clipboard as JavaScript code.

Drawing 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();
path.translate(-300,-30);
path.addText("hello world", 274, -700, 300);
path.addRect(-300,-300,-200,-250);
path.addEllipse(250, -300, 100,60);
// this path can then be returned if on the JavaScript layer
// or used to create an Editable Shape like so
api.createEditable(path, "My Path");

moveTo(x:float, y:float)

Start a new contour.

lineTo(x:float, y:float)

Draw a line to x,y.

cubicTo(cp1X:float, cp1Y:float, cp2X:float, cp2Y:float, endX:float, endY:float)

Draw a cubic bezier with two control points and an end point.

close()

Close the path.

addText(text:string, fontSize:int, positionX:float, positionY:float)

Add text to the path and position it. The text could be added to a separate path and then .append() it into this one if needed. The position arguments may be removed as a result of this.

var path = new cavalry.Path();
path.addText("hello world", 274, -700, 300);
api.createEditable(path, "My Path");

addRect(fromX:float, fromY:float, toX:float, toY:float)

Convenience method for drawing a rectangle.

addEllipse(centreX:float, centreY:float, radiusX:float, radiusY:float)

Convenience method for drawing an ellipse.

clear()

Empty the path.

isClosed → bool

Returns a boolean signifying if the path is closed.

translate(x:float, y:float)

Move the path by x and y.

rotate(degrees:float)

Rotate the path.

scale(x:float, y:float)

Scale the path.

append(pathToAdd:path)

Add one path to another

intersect(intersectPath:path)

Perform a Boolean intersection.

unite(unitePath:path)

Perform a Boolean unite.

difference(differencePath:path)

Perform a Boolean difference.

The below example can be set on the JavaScript Shape.

function boolTest() {
var mainPath = new cavalry.Path();
mainPath.addRect(-100,100,100,-100);
var boolTest = new cavalry.Path();
boolTest.addEllipse(0,0,200,40);
mainPath.difference(boolTest);
return mainPath;
}

boolTest();

convertToCurves()

Resample lines as curves (the algorithm used by the Pencil Tool).

convertToLines(linesPerCurve:int)

Convert (vectorise) any curves into a series of lines.

toObject() → object

Converts the Path to an object that can be saved.

var path = new cavalry.Path();
path.moveTo(0.,0.);
path.lineTo(0.,-100.);
path.lineTo(300.,-100.);
// Convert to an Object
var js = path.toObject();
// Convert from a saved object
path.fromObject(js);
console.log(path.length);

fromObject(objectToRead:object)

Sets the path from an object.

var path = new cavalry.Path();
path.moveTo(0.,0.);
path.lineTo(0.,-100.);
path.lineTo(300.,-100.);
// Convert to an Object
var js = path.toObject();
// Convert from a saved object
path.fromObject(js);
console.log(path.length);

arcTo(x1:float, y1:float, x2:float, y2:float, radius:float)

Draw an arc with two control points and a radius.

back → {x:float, y:float}

Return an object containing x and y keys describing the final point in a path.

var path = new cavalry.Path();
path.addText("Cavalry", 30, 0, 10);
console.log(JSON.stringify(path.back));

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

Return the bounding box of a path.

var path = new cavalry.Path();
path.addText("Some text!", 22, 0, 10);
let bbox = path.boundingBox();
console.log(JSON.stringify(bbox));

empty() → bool

Return if a path is empty or not.

pointCount() → int

Return the number of points in the path.

contains(x:float, y:float) → bool

Return if the point specified by x,y is inside the path (only works on a closed path).

pathData() → object

This returns an array of dictionaries and provides a convenient way to iterate and change an existing path as opposed to creating a new Path Class. Each dictionary contains the verb type variable e.g. moveTo or lineTo along with any 'point' objects relevant to the verb.

The dictionary will contain different objects depending on the verb type:

  • moveTo: contains a point object (with x and y variables).
  • lineTo: contains a point object (with x and y variables).
  • quadTo: contains a cp1 object representing the control point (with x and y variables) along with a point object (with x and y variables). This is the end point of the quadTo verb.
  • cubicTo: contains cp1 and cp2 objects representing the first and second control points (both with x and y variables) along with a point object (with x and y variables). This is the end point of the cubicTo verb.
  • close: contains no points.

setPathData(data:object)

Set the path based on a pathData object.

offset(distance:float, round:bool)

Grow or shrink a closed Path. The round argument determines whether the joins of the rebuilt Path's line segments are rounded or not.

function getPath() {
var path = new cavalry.Path()
path.addRect(0, 0, 200, 200);
path.offset(n0, true);
return path;
}

getPath();

trim(start:float, end:float, travel:float, reverse:bool)

Reduce the length of a Path by clipping it from its start/end points.

function getPath() {
var path = new cavalry.Path()
path.addEllipse(0,0,200,200);
path.trim(0.2, 0.5, 0.0, false);
return path;
}

getPath();

Mesh Class

The Mesh class is a container which can be used to construct multiple Paths and include materials. If unique Materials for each Path are not required, use path.append() to add Paths together.

addPath(path:Path, material:Material)

Add a Path and Material to a Mesh.

count() → int

Returns the number of paths in a Mesh.

empty() → bool

Returns whether or not the Mesh is empty.

clear()

Erases all Paths on the Mesh.

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

Returns a standard bounding box object.

getPathDataAtIndex(index: int) → array[object]

Returns a pathData array, which includes verbs and points. This data is designed for point level modification.

setPathAtIndex(index: int, path:Path object)

Overwrite a path at a given index with a different Path object.

setPathDataAtIndex(index: int, pathData:object)

Sets the pathData at a given depth and index.

setMaterialAtIndex(index: int, material: Material object)

Overwrites the material at a given index with a different Material object.

function getMesh() {
var path = new cavalry.Path()
path.addEllipse(0,0,100,200);

var mesh = new cavalry.Mesh();
var material = new cavalry.Material();
material.fillColor = "#ff24e0";
material.stroke = true;
material.strokeColor = "#000000";
material.strokeWidth = 10;

mesh.addPath(path, material);

return mesh;
}

getMesh();

Material Class

Add materials (Fill and Stroke) to a Mesh.

fill(true:bool)

Enable Fill (defaults to true).

stroke(true:bool)

Enable Stroke (defaults to false).

fillColor(hex:string)

Set the Fill's hex color.

strokeColor(hex:string)

Set the Stroke's hex color.

strokeWidth(width:float)

Set the Stroke's width.

trim(enable:bool)

Enable trim.

trimStart(startPoint:float)

Set the start point of the trim (0..1).

trimEnd(endPoint:float)

Set the end point of the trim (0..1).

trimTravel(travel:float)

Move the trim along the path. 1.0 is a complete cycle of a closed path.

trimReversed(reverse:bool)

Reverses the path direction for the trim effect.

// Example using the n0 Attribute to control the trim.
function getMesh() {
var path = new cavalry.Path()
path.addEllipse(0,0,100,200);

var mesh = new cavalry.Mesh();
var material = new cavalry.Material();
material.fillColor = "#ff24e0";
material.stroke = true;
material.strokeColor = "#000000";
material.strokeWidth = 10;

material.trim = true;
material.trimStart = 0.45;
material.trimEnd = 0.75;
material.trimTravel = n0*0.01;

mesh.addPath(path, material);

return mesh;
}

getMesh();

Measure

length() → float

Return the length of the path.

pointAtParam(param:float) → {x:float, y:float}

Return the position of a point at a given parameter along the path.

tangentAtParam(param:float) → {x:float, y:float}

Return a point object with x,y variables that corresponds to a tangent a given parameter along the path.

angleAtParam(param:float) → float

Return an angle in degrees representing the tangent a given parameter along the path.

paramAtLength(length:float) → float

Given a length, return the corresponding parameter value for that length value.

findClosestPoint(x:float, y:float) → {position:{x:float, y:float},tangent:{x:float,y:float},normal:{x:float,y:float}}

Find the closest point on a path to the given x,y values and return an object with position, normal and tangent variables, each of which has x,y variables.

Math

random(min:float, max:float, seed:int) → float

Returns a random number

for (var i = 1; i < 10; i +=1){
console.log(cavalry.random(0, 10, i));
}

uniform(min:float, max:float, seed:int) → float

Returns random numbers with a uniform distribution.

for (var i = 1; i < 10; i +=1){
console.log(cavalry.uniform(0, 10, i));
}

noise1d(x:float, seed:int, frequency:float) → float

Returns 1d Improved Perlin noise.

for (var i = 1; i < 10; i +=1){
console.log(cavalry.noise1d(i, 0, 1));
}

noise2d(x:float, y:float, seed:int, frequency:float) → float

Returns 2d Improved Perlin noise.

for (var i = 1; i < 10; i +=1){
console.log(cavalry.noise2d(i, api.getFrame(), 0, 1));
}

noise3d(x:float, y:float, z.float, seed:int, frequency:float) → float

Returns 3d Improved Perlin noise.

for (var i = 1; i < 10; i +=1){
console.log(cavalry.noise3d(i, i+100, api.getFrame(), 0, 0.1));
}

dist(x1:float, y1:float, x2:float, y2:float) → float

Get the distance between two points.

var d = cavalry.dist(0,0,100,100)
console.log(d);

map(value:float, inMin:float, inMax:float, outMin:float, outMax:float) → float

Remap a value into a new range.

// remap 30 from the range 0..60 to the range 100..300. Prints 200.
console.log(cavalry.map(30,0,60,100,300));

norm(value:float, min:float, max:float) → float

Normalise a value between 0..1.

// Prints 0.55;
console.log(cavalry.norm(55,0,100));

clamp(value:float, min:float, max:float) → float

Clamp a value min and max.

// Prints 100;
console.log(cavalry.clamp(150,0,100));

lerp(min:float, max:float, t:float) → float

Interpolate between a minimum and maximum value. The value returned is the value at t (between 0 and 1).

angleFromVector(x:float, y:float) → float

Convert a vector into an angle (radians).

var ang = cavalry.angleFromVector(1,0);
console.log(ang);
var vec = cavalry.vectorFromAngle(ang);
console.log(vec["x"]+" "+vec["y"]);

vectorFromAngle(angle:float) → {x:float, y:float}

Convert an angle (radians) into a vector (x, y) with values between 0..1.

var ang = cavalry.angleFromVector(1,0);
console.log(ang);
var vec = cavalry.vectorFromAngle(ang);
console.log(vec["x"]+" "+vec["y"]);

radiansToDegrees(radians:float) → float

Convert a value from radians to degrees.

console.log(cavalry.radiansToDegrees(2));

degreesToRadians(degrees:float) → float

Convert a value from degrees to radians.

console.log(cavalry.degreesToRadians(90));

Color

rgbToHsv(r:float, g:float, b:float, scaled=true) → {h:float, s:float, v:float}

Convert an RGB color to HSV. If the scaled argument is set to true (default) then RGB values should be in the range 0..1. If set to false then RGB values should be in the 0..255 range.

var unscaled = cavalry.rgbToHsv(255,0,255, false);
var scaled = cavalry.rgbToHsv(1,0,1, true);
console.log('Unscaled = ' + JSON.stringify(unscaled) + ' - Scaled = ' + JSON.stringify(scaled));

rgbToHex(r:float, g:float, b:float, scaled=true) → string

Convert an RGB color to a Hex string. If the scaled argument is set to true (default) then RGB values should be in the range 0..1. If set to false then RGB values should be in the 0..255 range.

const label1 = new ui.Label('Unscaled');
label1.setTextColor("#"+cavalry.rgbToHex(255,0,255,false));
ui.add(label1);

const label2 = new ui.Label('Scaled');
label2.setTextColor("#"+cavalry.rgbToHex(1,0,1,true));
ui.add(label2);

ui.show();

hsvToRgb(h:float, s:float, v:float) → {r:float, g:float, b:float}

Convert a HSV color to RGB.

var result = cavalry.hsvToRgb(180,1,0.5);
console.log(JSON.stringify(result));

hsvToHex(h:float, s:float, v:float) → string

Convert a HSV color to a Hex string.

var result = cavalry.rgbToHex(79,253,122);
console.log(result);

hexToRgb(hexValue:string) → {r:float, g:float, b:float}

Convert a Hex value (e.g #ffffff) color to RGB.

var result = cavalry.hexToRgb("#fc5900");
console.log(JSON.stringify(result));

hexToHsv(hexValue:string) → {h:float, s:float, v:float}

Convert a Hex value (e.g #ffffff) color to HSV.

var result = cavalry.hexToHsv("#ff9801");
console.log(JSON.stringify(result));

Text

fontExists(fontFamily:string, fontStyle:string) → bool

Returns true if a font is available to Cavalry.

console.log(cavalry.fontExists("Lato", "Regular")); // prints `true`

getFontFamilies() → [string]

Returns a list of all the font families available to Cavalry.

console.log(cavalry.getFontFamilies());

getFontStyles(string:fontFamily) → [string]

Returns a list of all the available styles for the given font family.

console.log(cavalry.getFontStyles("Lato"));

measureText(string:string, fontFamily:string, fontStyle:string, fontSize:int) → {width:float, height:float, x:float, y:float, centreX:float, centreY:float}

Returns an object representing the bounding box of some text without the need to actually create a text shape.

  • width - The width of the text
  • height - The height of the text
  • x - The left edge of the text
  • y - The top edge of the text
  • centreX - The average of the left and right edges
  • centreY - The average of the top and bottom edges
const measure = cavalry.measureText("Some text to measure", "Lato", "Regular", 72);
console.log(JSON.stringify(measure));

fontMetrics(fontFamily:string, fontStyle:string, fontSize:int) → {top:float, ascent:float, descent:float, bottom:float, leading:int, averageCharacterWidth:float, maxCharacterWidth:float, xMin:float, xMax:float, xHeight:float, capHeight:float}

Returns an object containing information about the given font. The resulting metrics are scaled by the font size.

  • top - greatest extent above origin of any glyph bounding box, typically negative; deprecated with variable fonts
  • ascent - distance to reserve above baseline, typically negative
  • descent - distance to reserve below baseline, typically positive
  • bottom - greatest extent below origin of any glyph bounding box, typically positive; deprecated with variable fonts
  • leading - distance to add between lines, typically positive or zero
  • averageCharacterWidth - average character width, zero if unknown
  • maxCharacterWidth - maximum character width, zero if unknown
  • xMin - greatest extent to left of origin of any glyph bounding box, typically negative; deprecated with variable fonts
  • xMax - greatest extent to right of origin of any glyph bounding box, typically positive; deprecated with variable fonts
  • xHeight - height of lower-case 'x', zero if unknown, typically negative
  • capHeight - height of an upper-case letter, zero if unknown, typically negative
const metrics = cavalry.fontMetrics("Lato", "Regular", 72);
console.log(JSON.stringify(metrics));

Utilities

versionLessThan(version:string) → bool

This will return true if the version of Cavalry in use is less than the specified version. This is useful to add support for features in scripts that depend on the version of Cavalry.

SEMVER

Cavalry uses Semantic Versioning for version numbers.

MAJOR.MINOR.PATCH (e.g. 1.5.0) is used for official releases.

MAJOR.MINOR.PATCH.PRE-RELEASE-TYPE.NUMBER (e.g. 1.6.0-beta.1) is used for pre-release builds.

/// this will return true in Cavalry 1.3.1, and false in Cavalry 1.5.0
console.log(cavalry.versionLessThan("1.4.0"));