Prototyper Docs

Get started

Prototyper is a Figma plugin lets you make high-fidelity prototypes using code via the open-source Framer Library JavaScript framework. Create animations and interactions that bring your design to life.

How it works

Prototyper takes your currently selected frame on the Figma canvas and converts each individual layer into an image that renders as a preview on the right-hand side of the plugin.

Each layer is turned into a variable that you can reference in the code editor on the left-hand side of the plugin to add animations and interactions.

1. Layers

Layers can be images, text and more.
They have a hierachy and properties defining their position, appearance and interactivity.

2. Animation

Animate states or layer properties like scale and color with various easing or spring curves, time and delay options.

More on LayersMore on Animation

3. States

States are stored sets of layer properties with values. You can animate states, switch instantly or cycle between them.

4. Events

Events are used to detect and respond to user interactions, animations that start or end, values that change and more.

More on StatesMore on Events

Align

The Align functions help you quickly position an object on the screen relative to its parent. Use these to place a Layer to the top, bottom, left, right or center of its parent. They can be used as layer properties, in states and animations.

// Create a layer an position it in the center
let animationOptions, i
let layerA = new Layer({
	x: Align.center,
	y: Align.center
})

// Create a state in the bottom right corner
layerA.states = {
	stateA: {
		x: Align.right,
		y: Align.bottom
	},
	stateB: {
		x: Align.left,
		y: Align.top
	}
}

layerA.onTap(() => layerA.stateCycle())

The Align functions calculate the correct value for x or y dynamically at the moment you actually want to position them. So if you have a state that puts a layer in the bottom right position, it will always do so, even if you resize the screen in between switching states.

You can also optionally use offsets:

layerA = new Layer({
    x: Align.center(-100), // 100 pixels left from the center
    y: Align.top(100) // 100 pixels from the top
})

Please note that left and right only work for the x property, and top and bottom only for the y property. Center works for both. Align is a more flexible alternative to layer.center() that works well with Auto-Code direct editing.

align.bottom(offset)

Position the layer to the bottom of its parent. If there is no parent, it will use the Screen. Bottom only works for the y layer property. It can be used as a property, in states and in animations.

Arguments

  1. offset — A number (optional).
layerA = new Layer({
    y: Align.bottom
})

let layerB = new Layer({
    y: Align.bottom(-100) // 100 pixels from the bottom
})

align.center(offset)

Place the layer in the center, relative to its parent. If there is no parent, it will use the Screen. It can be used as a property, in states and in animations.

Arguments

  1. offset — A number (optional).
layerA = new Layer({
    x: Align.center,
    y: Align.center
})

layerB = new Layer({
    x: Align.center(+100),
    y: Align.center(-100)
})

align.left(offset)

Position the layer to the left of its parent. If there is no parent, it will use the Screen. Left only works for the x layer property. It can be used as a property, in states and in animations.

Arguments

  1. offset — A number (optional).
layerA = new Layer({
    x: Align.left
})

layerB = new Layer({
    x: Align.left(100) // 100 pixels from the left
})

align.right(offset)

Place the layer to the right of its parent. If there is no parent, it will use the Screen. Right only works for the x layer property. It can be used as a property, in states and in animations.

Arguments

  1. offset — A number (optional).
layerA = new Layer({
    x: Align.right
})

layerB = new Layer({
    x: Align.right(-100) // 100 pixels from the right
})

align.top(offset)

Position the layer to the top of its parent. If there is no parent, it will use the Screen. Top only works for the y layer property. It can be used as a property, in states and in animations.

Arguments

  1. offset — A number (optional).
layerA = new Layer({
    y: Align.top
})

layerB = new Layer({
    y: Align.top(100) // 100 pixels from the top
})

Animation

Animation objects manage animations targeted on a layer. This is what is created by the layer’s animate function. The only difference is that animation objects don’t start immediately, you have to explicitly execute start().

The animation options allow you to define curves, timing, delays and more. Layers can run multiple animations at the same time. If animations affect the same layer properties, only the last one will run.

Properties

  1. layer — A layer object, the targeted layer.
  2. properties or state — An object with target values for the animated properties or a State object.
  3. options — An object with all the animation options like curve, time and more. (Optional)

Example: Layer and properties

Here, we create a new Animation for layerA. Once we start the animation, it will move horizontally from 0 to 100. Note that we left out many optional arguments. By default, the animation will take 1 second, with an ease curve.

layerA = new Layer

// Animate the layer to the right
let animationA = new Animation(layerA,
    {x: 100}
)

animationA.start()

Example: Layer and states

Animate a layer using a layer state by inserting the State object instead of layer properties.

layerA = new Layer

layerA.states.stateA = {x: 100}

// Animate the layer to the right
let animationB = new Animation(layerA, layerA.states.stateA)

animationB.start()

Example: Multiple properties and time

Multiple properties can be animated at once. Here, we animate the x and opacity properties, with a duration of 5 seconds.

layerA = new Layer

// Animate multiple properties for 5 seconds
const animationC = new Animation(layerA, {
    x: 100,
    opacity: 0.5,
    options: {
        time: 5
    }
})

animationC.start()

Example: Repeat and delay

When using repeat, the end values of properties will be reset to their starting position instantly. In the example below, there is a 2 second delay between every repeat.

layerA = new Layer

// Repeat an animation 5 times, delay for 2 seconds
const animationD = new Animation(layerA, {
    x: 100,
    options: {
        repeat: 5,
        delay: 2
    }
})

animationD.start()

Animation Curves

  1. Bezier.linear — Constant speed.
  2. Bezier.ease — Ease curve.
  3. Bezier.easeIn — Ease-in curve.
  4. Bezier.easeOut — Ease-out curve.
  5. Bezier.easeInOut — Ease-in-out curve.
  6. Spring — A spring curve with damping.

Example: Bezier

layerA = new Layer

// Animate with a bezier curve
animationA = new Animation(layerA, {
    x: 100,
    opacity: 0.5,
    options: {
        curve: Bezier(0.25, 0.1, 0.25, 1)
    }
})

Example: Spring

The default spring can be used along with the time property.

  1. damping — Bounciness of the spring.
  2. mass — Mass of the animating layer. (Optional)
  3. velocity — Velocity at the start. (Optional)
layerA = new Layer

// Animate with a spring curve
animationA = new Animation(layerA, {
    x: 100,
    options: {
        curve: Spring({damping: 0.5}),
        time: 0.5
    }
})

Example: Classic Spring

The classic spring cannot be used with the time property.

  1. tension — Strength of the spring.
  2. friction — Weight of the spring.
  3. velocity — Velocity at the start. (Optional)
  4. tolerance — Minimal threshold before the animation ends. (Optional)
layerA = new Layer

// Animate with a spring curve
animationA = new Animation(layerA, {
    x: 100,
    options: {
        curve: Spring({tension: 250, friction: 25})
    }
})

Animatable Properties

Only numeric layer properties and color can be animated:

  • x, y, z
  • minX, midX, maxX
  • minY, midY, maxY
  • width, height
  • opacity
  • rotation, rotationX, rotationY, rotationZ
  • scale scaleX, scaleY, scaleZ
  • originX, originY, perspective
  • scrollX, scrollY
  • borderRadius, borderWidth
  • shadowX, shadowY, shadowBlur, shadowSpread
  • blur, brightness, saturate
  • hueRotate, contrast, invert, grayscale, sepia

Multiple Properties

You can start multiple animations targeting the same layer, as long as they don’t target the same properties. If you start two animations both targeting x for the same layer, the first one will be cancelled.

Performance

Most properties benefit from GPU accelerated drawing. You can animate many of them smoothly. But some properties need to involve the CPU to animate, and are therefore more expensive to render:

  • width
  • height
  • scrollX
  • scrollY
  • borderRadius
  • borderWidth

animation.start()

Start the animation.

layerA = new Layer

animationA = new Animation(layerA,
    {x: 100})

// Nothing will move until we start
animationA.start()

animation.stop()

Stop the animation.

layerA = new Layer

animationA = new Animation(layerA,
    {x: 100})

animationA.start()

// Stop the animation
animationA.stop()

animation.reverse()

Create a new animation with all reverse values.

layerA = new Layer

animationA = new Animation(layerA,
    {x: 100})

animationB = animationA.reverse()

// Alternate between the two animations
animationA.on(Events.AnimationEnd, animationB.start)
animationB.on(Events.AnimationEnd, animationA.start)

animationA.start()

animation.reset()

Reset the layer to its default state.

layerA = new Layer

animationA = new Animation(layerA,
    {x: 100})

animationA.start()

// On animation end reset the animation
animationA.on(Events.AnimationEnd, () => animationA.reset())

animation.restart()

Reset the layer to its default state and start the animation again.

layerA = new Layer

animationA = new Animation(layerA,
    {x: 100})

animationA.start()

// On animation end restart the animation
animationA.on(Events.AnimationEnd, () => animationA.restart())

animation.finish()

Stop the currently active animation and jump to its end state.

layerA = new Layer

animationA = new Animation(layerA,
    {x: 100}, {
        options: {
            time: 3
        }
    }
)

animationA.start()

// Finish the animation after a 1 second delay
Utils.delay(1, () => animationA.finish())

BackgroundLayer

A background layer is just a normal layer, but it scales with your window, so it always covers the entire canvas. If the background layer has a parent, the background will inherit the size of the parent.

layerA = new BackgroundLayer({
    backgroundColor: "white"
})

Colors can be defined by keywords, but also rgb and hex values.

// Hex value for white
layerA = new BackgroundLayer({
    backgroundColor: "#ffffff"
})

// RGB value for white
layerA = new BackgroundLayer({
    backgroundColor: "rgb(255,255,255)"
})

// RGBA value for white
layerA = new BackgroundLayer({
    backgroundColor: "rgba(255,255,255,1)"
})

Canvas

The Canvas object contains the size for the current entire document in pixels. It will change if you resize your document by resizing the window it is in.

Canvas.backgroundColor <string>

Sets the background color of the canvas.

// Change the canvas background color
Canvas.backgroundColor = "#28affa"

Canvas.image <string>

Sets the background image of the canvas. You can set it as a link. The image will always fit to cover the canvas, and will never be stretched.

// Hosted images
Canvas.image = "https://source.unsplash.com/random"

Canvas.width <number>

The width of the current entire document in pixels. (Read-only)

print(Canvas.width)
// Output: 640

Canvas.height <number>

The height of the current entire document in pixels. (Read-only)

print(Canvas.height)
// Output: 480

Canvas.size <object>

The width and height of the current entire document in pixels. (Read-only)

print(Canvas.size)
// Output: { width:640, height: 480 }

Canvas.frame <object>

The x, y, width and height of the current entire document in pixels. (Read-only)

print(Canvas.frame)
// Output: { x:0, y:0, width:640, height: 480 }

Canvas.convertPointToScreen(point)

Converts a point from the Canvas to the Screen.

let point = {
    x: 20,
    y: 40
}
let pointInScreen = Canvas.convertPointToScreen(point)

Canvas.convertPointToLayer(point, layer)

Converts a point from the Canvas to a layer.

point = {
    x: 20,
    y: 40
}

let layer = new Layer

let pointInLayer = Canvas.convertPointToLayer(point, layer)

Color

The Color object can be used to define, detect, modify and mix colors. Colors can be defined using either a string value or an object. All colors are converted to a Color object with r, g, b, h, s, l and an a value.

let bg = new BackgroundLayer({
    backgroundColor: "#28affa"
})

print(bg.backgroundColor)
// <Color "#28affa">

Supported color models: CSS Names, HEX, RGB, RGBA, HSL and HSLA.

// Multiple ways to define the same color:
let blue = new Color("blue")
blue = new Color("#28AFFA")
blue = new Color("rgb(255, 0, 102)")
blue = new Color("rgba(255, 0, 102, 1)")
blue = new Color("hsl(201, 95, 57)")
blue = new Color("hsla(201, 95, 57, 1)")

You can also create new Color objects and pass in strings, or objects:

// Define a color with a HEX string
bg = new BackgroundLayer({
    backgroundColor: new Color("#fff")
})

// Define a color with an RGB object
layerA = new Layer({
    backgroundColor: new Color({r: 255, g: 255, b: 255})
})

// Define a color with an HSL object
layerB = new Layer({
    backgroundColor: new Color({h: 360, s: 1, l: 1, a: 1})
})

Color Models

You can animate the background color, text color and shadow color of a layer. By default, color transitions use HUSL. With the colorModel property, you can specify in which model to animate. We support rgb, hsl and husl.

bg = new BackgroundLayer({
    backgroundColor: "blue"
})

// Animate in RGB
bg.animate({
    backgroundColor: "red",
    options: {
        colorModel: "rgb"
    }
})

color.lighten(amount)

Add white and return a lightened color.

Arguments

  1. amount — A number, from 0 to 100. Set to 10 by default.
// Create a new color, lighten it
blue = new Color("#28affa").lighten(20)

layerA = new Layer({
    backgroundColor: blue
})

color.darken(amount)

Add black and return a darkened color.

Arguments

  1. amount — A number, from 0 to 100. Set to 10 by default.
// Create a new color, darken it
blue = new Color("#28affa").darken(20)

layerA = new Layer({
    backgroundColor: blue
})

color.saturate(amount)

Increase the saturation of a color.

Arguments

  1. amount — A number, from 0 to 100. Set to 10 by default.
// Create a new Color, saturate it
blue = new Color("#877DD7").saturate(100)

layerA = new Layer({
    backgroundColor: blue
})

color.desaturate(amount)

Decrease the saturation of a color.

Arguments

  1. amount — A number, from 0 to 100. Set to 10 by default.
// Create a new Color, desaturate it
blue = new Color("#28affa").desaturate(25)

layerA = new Layer({
    backgroundColor: blue
})

color.grayscale()

Return a fully desaturated color.

// Create a new Color
const yellow = new Color("yellow")

// Convert it to gray
const gray = yellow.grayscale()

layerA = new Layer({
    backgroundColor: gray
})

color.gray(amount, alpha)

Generates a transparent white background.

Arguments

  1. amount — A number representing the amount of white.
  2. alpha — A number representing the alpha. <span>(Optional)
layer = new Layer
layer.backgroundColor = Color.gray(0.5)

color.alpha(amount)

Increase the alpha value, also known as opacity, of the color.

Arguments

  1. amount — A number, from 0 to 1. Set to 1 by default.
// Create a new Color, increase the opacity
blue = new Color("#28affa").alpha(.5)

layerA = new Layer({
    backgroundColor: blue
})

Color.mix(colorA, colorB, fraction, limit, model)

Blend two colors together, optionally based on user input. The fraction defines the distribution between the two colors, and is set to 0.5 by default.

Arguments

  1. colorA — A color, the first one
  2. colorB— A color, the second one
  3. fraction — A number, from 0 to 1. <span>(Optional)
  4. limit — A boolean, set to false by default. <span>(Optional)
  5. model — A string, the color model used to mix. <span>(Optional)
// Mix red with yellow
const orange = Color.mix("red", "yellow", 0.5)

The limit defines if the color can transition beyond its range. This is applicable when transitioning between colors, using Utils.modulate. Below, the limit is set to true, so the transition cannot extend beyond the second color.

// Create new Layer
layerA = new Layer({
    backgroundColor: "red"
})

// Enable dragging
layerA.draggable.enabled = true

// On move, transition its color to yellow
layerA.on(Events.Move, function(offset) {

// Map the dragging distance to a number between 0 and 1
    const fraction = Utils.modulate(offset.x, [0, Screen.width], [0,1], true)

// Mix the colors, enable the limit, transition in HUSL
    return layerA.backgroundColor =
        Color.mix("red", "yellow", fraction, true, "husl")
})

Color.random()

Returns a Color instance with a random color value set.

const random = Color.random()

Color.isColor(value)

Checks if the value is a valid color object or color string. Returns true or false.

Arguments

  1. value — An object or string, representing a color
print(Color.isColor(new Color("red"))) // true
print(Color.isColor("red")) // true

Color.isColorObject(value)

Checks if the value is a valid color object. Returns true or false.

Arguments

  1. value — An object, representing a color
print(Color.isColorObject(new Color("red"))) // true
print(Color.isColorObject("red")) // false

Color.isColorString(value)

Checks if the value is a color string. Returns true or false.

Arguments

  1. value — A string, representing a color
print(Color.isColorString("red")) // true
print(Color.isColorString("#28affa")) // true

Color.toHexString()

Returns the hexadecimal string representation of a color.

Arguments

  1. value — An object or string, representing a color
blue = new Color("blue")
print(blue.toHexString()) // "#0000ff"

Color.toRgbString()

Returns the RGB string representation of a color.

Arguments

  1. value — An object or string, representing a color
blue = new Color("blue")
print(blue.toRgbString()) // "rgb(0, 0, 255)"

Color.toHslString()

Returns the HSL string representation of a color.

Arguments

  1. value — An object or string, representing a color
blue = new Color("blue")
print(blue.toHslString()) // "hsl(240, 100%, 50%)"

Defaults

The Prototyper.Defaults allows you to override the default properties for Layers and Animations when they are created. For example, all new layers get a light blue background color so you can see them. You can override that color here.

// Override the default background color for layers
Prototyper.Defaults.Layer.backgroundColor = "red"

// Override the default corner radius for layers
Prototyper.Defaults.Layer.borderRadius = 10

layerA = new Layer

print(layerA.backgroundColor)
// Output: "red"

print(layerA.borderRadius)
// Output: 10

Here is an example to set the default animation curve. Note that those will also be used for layer.states switches unless you override them for a layer or state with the animationOptions property.

// Override the default animation options for all Animations
Prototyper.Defaults.Animation =
    {curve: Spring({damping: 0.75})}

// Override the default corner radius for layers
Prototyper.Defaults.Layer.borderRadius = 10

layerA = new Layer

layerA.animate({
    x: 100
})

// The animation will now use the spring curve

Draggable

Layers can be made horizontally and/or vertically draggable. They can be tossed around with momentum. To control where they end up, you can define a specific area that a layer can be dragged within. They can optionally be dragged beyond this area, but they will then bounce back by default.

layer.draggable.enabled <boolean>

Enable dragging for the layer.

layerA = new Layer
layerA.draggable.enabled = true

layer.draggable.horizontal <boolean>

Enable or disable horizontal movement.

layerA = new Layer
layerA.draggable.enabled = true

// Disable horizontal dragging
layerA.draggable.horizontal = false

layer.draggable.vertical <boolean>

Enable or disable vertical movement.

layerA = new Layer
layerA.draggable.enabled = true

// Disable vertical dragging
layerA.draggable.vertical = false

layer.draggable.speedX <number>

Modify the horizontal dragging speed. The value is in pixels per mouse moved pixels. The default value is 1. When set lower then 1 dragging will be slower than mouse movement and vice versa. You can set the value to 0 to disable horizontal dragging.

layerA = new Layer
layerA.draggable.enabled = true

// Make horizontal dragging slow
layerA.draggable.speedX = 0.1

// Make horizontal dragging fast
layerA.draggable.speedX = 10

layer.draggable.speedY <number>

Modify the vertical dragging speed. The value is in pixels per mouse moved pixels. The default value is 1. When set lower then 1 dragging will be slower than mouse movement and vice versa. You can set the value to 0 to disable vertical dragging.

layerA = new Layer
layerA.draggable.enabled = true

// Make vertical dragging slow
layerA.draggable.speedY = 0.1

// Make vertical dragging fast
layerA.draggable.speedY = 10

layer.draggable.constraints <object>

Constraints for the area this layer can be dragged within. If you also set the x and y properties as constraints, the layer will snap to that position on DragStart. The layer will animate to the new point on click.

layerA = new Layer
layerA.draggable.enabled = true

// Set dragging constraints
layerA.draggable.constraints = {
    x: 0,
    y: 0,
    width: 200,
    height: 200
}

layer.draggable.constraintsOffset <object>

Get the offset position of a layer, compared to its dragging contraints. If you set the dragging constraints to { x: 100, y: 100 }, the layer will still be initially positioned at x: 0, y: 0. After dragging, the layer will be bound to its dragging contraints. This offset can be measured with constraintsOffset.

layerA = new Layer
layerA.draggable.enabled = true

// Set dragging constraints
layerA.draggable.constraints = {
    x: 100,
    y: 100,
    width: 200,
    height: 200
}

// Get the constraintsOffset
print(layerA.draggable.constraintsOffset)

// Returns { x:-100, y:-100 }

layer.draggable.isBeyondConstraints <boolean>

See if the draggable layer is currently beyond its dragging constraints. (Read-only)

layerA = new Layer
layerA.draggable.enabled = true

// Set dragging constraints
layerA.draggable.constraints = {
    x: 100,
    y: 100,
    width: 400,
    height: 400
}

// On move, see if the layer is beyond constraints or not
layerA.on(Events.Move, () => print(layerA.draggable.isBeyondConstraints))

layer.draggable.overdrag <boolean>

Enable or disable dragging beyond the set constraints.

layerA = new Layer
layerA.draggable.enabled = true

layerA.draggable.constraints = {
    x: 0,
    y: 0,
    width: 200,
    height: 200
}

// Disable dragging beyond constraints
layerA.draggable.overdrag = false

layer.draggable.overdragScale <number>

Set the dragging resistance when dragging beyond constraints. The scale is defined with a number between 0 and 1. The default value is 0.5.

layerA = new Layer
layerA.draggable.enabled = true

layerA.draggable.constraints = {
    x: 0,
    y: 0,
    width: 200,
    height: 200
}

// Increase resistance when dragging beyond constraints
layerA.draggable.overdragScale = 0.25

layer.draggable.momentum <boolean>

Enable or disable momentum/inertia simulation. Enabled by default.

layerA = new Layer
layerA.draggable.enabled = true

// Disable momentum
layerA.draggable.momentum = false

layer.draggable.momentumOptions <object>

Options for momentum simulation on DragEnd.

layerA = new Layer
layerA.draggable.enabled = true

// Define friction and tolerance of momentum
layerA.draggable.momentumOptions = {
    friction: 2.1,
    tolerance: 0.1
}

layer.draggable.bounce <boolean>

Spring animation when momentum runs beyond constraints.

layerA = new Layer
layerA.draggable.enabled = true

layerA.draggable.constraints = {
    x: 0,
    y: 0,
    width: 200,
    height: 200
}

// Snap back after dragging beyond constraints
layerA.draggable.bounce = false

layer.draggable.bounceOptions <object>

Options for the spring animations when momentum runs beyond constraints.

layerA = new Layer
layerA.draggable.enabled = true

layerA.draggable.constraints = {
    x: 0,
    y: 0,
    width: 200,
    height: 200
}

// Define friction, tension and tolerance of bounce
layerA.draggable.bounceOptions = {
    friction: 40,
    tension: 200,
    tolerance: 0.0001
}

layer.draggable.velocity <object>

Current velocity for the draggable layer. The velocity is read-only.

layerA = new Layer
layerA.draggable.enabled = true

// On DragMove, print the x and y velocity
layerA.draggable.on(Events.DragMove, () => print(layerA.draggable.velocity))

layer.draggable.direction <string>

Current dragging direction. Returns "up", "down", "left" or "right". (Read-only)

layerA = new Layer
layerA.draggable.enabled = true

// Print the current direction
layerA.on(Events.DragMove, () => print(layerA.draggable.direction))

layer.draggable.angle <number>

Current angle (in degrees) for the draggable layer. (Read-only)

layerA = new Layer
layerA.draggable.enabled = true

// Print the current angle
layerA.on(Events.DragMove, () => print(layerA.draggable.angle))

layer.draggable.updatePosition(point)

Function to override the final value before setting it. Allows you to add your own behaviour to a draggable. This allows you to create draggable layers that snap between certain distances.

Arguments

  1. point — An object with x and y properties.
layerA = new Layer
layerA.draggable.enabled = true

// Round numbers to a set amount
const round = (number, nearest) => Math.round(number / nearest) * nearest

// Drag in increments of 20px
layerA.draggable.updatePosition = function(point) {
    point.x = round(point.x, 20)
    point.y = round(point.y, 20)
    return point
}

layer.draggable.directionLock <boolean>

Snap to horizontal/vertical direction after a certain threshold.

layerA = new Layer
layerA.draggable.enabled = true

// Allow dragging only in one direction at a time
layerA.draggable.directionLock = true

layer.draggable.directionLockThreshold <object>

The thresholds for lock directions. The x and y values represent the distance you can drag in a certain direction before it starts locking.

layerA = new Layer
layerA.draggable.enabled = true

// Snap horizontally after dragging 50px
// Snap vertically instantly
layerA.draggable.directionLock = true

layerA.draggable.directionLockThreshold = {
    x: 50,
    y: 0
}

layer.draggable.pixelAlign <boolean>

Snap to pixels while dragging to avoid subpixel-antialiasing.

layerA = new Layer
layerA.draggable.enabled = true

// Snap to pixel while dragging
layerA.draggable.pixelAlign = true

layer.draggable.isDragging <boolean>

Whether the layer is currently being dragged (returns false when animating). (Read-only)

layerA = new Layer
layerA.draggable.enabled = true

// Check if the layer is being dragged
layerA.on(Events.DragMove, () => print(layerA.draggable.isDragging))

layer.draggable.isAnimating <boolean>

Whether the layer is currently being animated by a momentum or bounce animation. (Read-only)

layerA = new Layer
layerA.draggable.enabled = true

// Check if the layer is animating
layerA.on(Events.DragMove, () => print(layerA.draggable.isAnimating))

layer.draggable.isMoving <boolean>

Whether the layer is currently moving, either by dragging or by a momentum/bounce animation. (Read-only)

layerA = new Layer
layerA.draggable.enabled = true

// Check if the layer is moving
layerA.on(Events.DragMove, () => print(layerA.draggable.isMoving))

layer.draggable.offset <object>

Get the x and y position of the draggable layer, relative to the Screen. (Read-only)

layerA = new Layer
layerA.draggable.enabled = true

// Get the x and y position of the layer
layerA.on(Events.DragMove, () => print(layerA.draggable.offset))

layer.draggable.layerStartPoint <object>

Get the x and y position of a draggable layer. (Read-only)

layerA = new Layer
layerA.draggable.enabled = true

// On DragStart, get the current x and y position
layerA.on(Events.DragStart, () => print(layerA.draggable.layerStartPoint))

layer.draggable.cursorStartPoint <object>

Get the x and y position of the cursor, relative to the Canvas. (Read-only)

layerA = new Layer
layerA.draggable.enabled = true

// On DragStart, get x and y position of the cursor
layerA.on(Events.DragStart, () => print(layerA.draggable.cursorStartPoint))

layer.draggable.layerCursorOffset <object>

Get the x and y position of the cursor, relative to the draggable layer. If you click in the top left-corner, it returns { x: 0, y: 0 }. (Read-only)

layerA = new Layer
layerA.draggable.enabled = true

// Get the cursor position within the layer
layerA.on(Events.DragStart, () => print(layerA.draggable.layerCursorOffset))

layer.draggable.propagateEvents <boolean>

Set the propagateEvents property of a draggable layer. Set to true by default. This is useful when working with draggable layers within ScrollComponents or PageComponents, or nested Components.

Let's say you'd like to have a draggable layer within the scroll.content layer. By default, moving the layer will also move the scroll.content. This is because both layers will listen to the dragging events.

To prevent any draggable children from passing events to its parent, set propagateEvents to false. This applies to all nested draggable layers.

let scroll = new ScrollComponent({
    width: Screen.width,
    height: Screen.height
})

scroll.content.backgroundColor = "#28affa"

layerA = new Layer({
    parent: scroll.content,
    backgroundColor: "#fff"
})

layerA.draggable.enabled = true

// Setting propagateEvents to false allows you to drag layerA
// without also scrolling within the ScrollComponent
layerA.draggable.propagateEvents = false

Events

Events are things that you can listen for. They can originate from the user, like a touch or click, or from an animation that ends. Most objects support event listening in Prototyper, but you will most often listen for events on layers.

When an event is called, the first argument is the event information. Depending on the event, this can contain mouse positions, mouse deltas etc. The second argument is always the layer that the event occurred to.

To listen for an event, you can use the on function:

layerA = new Layer
layerA.name = "Layer A"

layerA.on(Events.Click, (event, layer) => print("Clicked", layer.name))

// Output: "Clicked", "Layer A"

To stop listening for an event, you can use the off function:

layerA = new Layer
layerA.name = "Layer A"

let clickHandler = (event, layer) => print("Clicked", layer.name)

layerA.on(Events.Click, clickHandler)
layerA.off(Events.Click, clickHandler)

Tap Events

Tap events receive the gesture event properties.

  1. Events.Tap — Tap a layer.
  2. Events.SingleTap — Same as Tap.
  3. Events.DoubleTap — Quickly tap a layer twice.
layerA = new Layer

layerA.on(Events.Tap, event => print("Tap"))

//`#`

layerA = new Layer

layerA.on(Events.DoubleTap, event => print("Double tap"))

Tap Event Shortcuts

// For Events.Tap
layerA.onTap(() => print("Tap"))

// For Events.SingleTap
layerA.onSingleTap(() => print("Single tap"))

// For Events.DoubleTap
layerA.onDoubleTap(() => print("Double tap"))

ForceTap Events

ForceTap events receive the gesture event properties.

  1. Events.ForceTap — Tap with high pressure.
  2. Events.ForceTapChange — Tap pressure sensitivity change.
  3. Events.ForceTapStart — Start tap with high pressure.
  4. Events.ForceTapEnd — End tap with high pressure.
layerA = new Layer

layerA.on(Events.ForceTap, event => print("Force tap"))

ForceTap Event Shortcuts

// For Events.ForceTap
layerA.onForceTap(() => print("Force tap"))

// For Events.ForceTapChange
layerA.onForceTapChange(() => print("Change of force tap pressure"))

// For Events.ForceTapStart
layerA.onForceTapStart(() => print("Start force tap"))

// For Events.ForceTapEnd
layerA.onForceTapEnd(() => print("End force tap"))

LongPress Events

LongPress events receive the gesture event properties.

  1. Events.LongPress — A long press.
  2. Events.LongPressStart — Start of long press.
  3. Events.LongPressEnd — End of long press.
// Detect a long press
layer.on(Events.LongPress, event => print("Long press"))

LongPress Event Shortcuts

// For Events.LongPress
layerA.onLongPress(() => print("Long press"))

// For Events.LongPressStart
layerA.onLongPressStart(() => print("Start long press"))

// For Events.LongPressEnd
layerA.onLongPressEnd(() => print("End long press"))

Swipe Events

Swipe events receive the gesture event properties.

Basic

  1. Events.Swipe — Swipe a layer.
  2. Events.SwipeStart — Start swiping a layer.
  3. Events.SwipeEnd — End swiping a layer.
layerA = new Layer

layerA.on(Events.Swipe, event => print(event.distance))

Swipe Event Shortcuts

// For Events.Swipe
layerA.onSwipe(() => print("Currently swiping"))

// For Events.SwipeStart
layerA.onSwipeStart(() => print("Start swiping"))

// For Events.SwipeEnd
layerA.onSwipeEnd(() => print("End swiping"))

Up

  1. Events.SwipeUp — Upwards swiping.
  2. Events.SwipeUpStart — Start swiping up.
  3. Events.SwipeUpEnd — End swiping up.
layerA = new Layer

layerA.on(Events.SwipeUp, event => print(event.distance))

SwipeUp Event Shortcuts

// For Events.SwipeUp
layerA.onSwipeUp(() => print("Currently swiping up"))

// For Events.SwipeUpStart
layerA.onSwipeUpStart(() => print("Start swiping up"))

// For Events.SwipeUpEnd
layerA.onSwipeUpEnd(() => print("End swiping up"))

Right

  1. Events.SwipeRight — Right swiping.
  2. Events.SwipeRightStart — Start swiping right.
  3. Events.SwipeRightEnd — End swiping right.
layerA = new Layer

layerA.on(Events.SwipeRight, event => print(event.distance))

SwipeRight Event Shortcuts

// For Events.SwipeRight
layerA.onSwipeRight(() => print("Currently swiping right"))

// For Events.SwipeRightStart
layerA.onSwipeRightStart(() => print("Start swiping right"))

// For Events.SwipeRightEnd
layerA.onSwipeRightEnd(() => print("End swiping right"))

Down

  1. Events.SwipeDown — Downwards swiping.
  2. Events.SwipeDownStart — Start swiping down.
  3. Events.SwipeDownend — End swiping down.
layerA = new Layer

layerA.on(Events.SwipeDown, event => print(event.distance))

SwipeDown Event Shortcuts

// For Events.SwipeDown
layerA.onSwipeDown(() => print("Currently swiping down"))

// For Events.SwipeDownStart
layerA.onSwipeDownStart(() => print("Start swiping down"))

// For Events.SwipeDownEnd
layerA.onSwipeDownEnd(() => print("End swiping down"))

Left

  1. Events.SwipeLeft — Left swiping.
  2. Events.SwipeLeftStart — Start swiping left.
  3. Events.SwipeLeftEnd — End swiping left.
layerA = new Layer

layerA.on(Events.SwipeLeft, event => print(event.distance))

SwipeLeft Event Shortcuts

// For Events.SwipeLeft
layerA.onSwipeLeft(() => print("Currently swiping left"))

// For Events.SwipeLeftStart
layerA.onSwipeLeftStart(() => print("Start swiping left"))

// For Events.SwipeLeftEnd
layerA.onSwipeLeftEnd(() => print("End swiping left"))

Pan Events

Pan events receive the gesture event properties.

  1. Events.Pan — Pan in any direction
  2. Events.PanStart — Start panning.
  3. Events.PanMove — While panning.
  4. Events.PanEnd — End of panning.
  5. Events.PanLeft — Left panning.
  6. Events.PanRight — Right panning.
  7. Events.PanUp — Upwards panning.
  8. Events.PanDown — Downwards panning.
layerA = new Layer

// Detect a panning gesture
layerA.on(Events.Pan, event => print(event.distance))

Pan Event Shortcuts

// For Events.Pan
layerA.onPan(() => print("Currently panning"))

// For Events.PanStart
layerA.onPanStart(() => print("Start panning"))

// For Events.PanMove
layerA.onPanMove(() => print("Currently panning"))

// For Events.PanEnd
layerA.onPanEnd(() => print("End panning"))

// For Events.PanLeft
layerA.onPanLeft(() => print("Panning left"))

// For Events.PanRight
layerA.onPanRight(() => print("Panning right"))

// For Events.PanUp
layerA.onPanUp(() => print("Panning up"))

// For Events.PanDown
layerA.onPanDown(() => print("Panning down"))

Pinch Events

Pinch events receive the gesture event properties.

  1. Events.Pinch — Two pointers moving inwards or outwards.
  2. Events.PinchStart — Start pinching.
  3. Events.PinchEnd — End of pinching.
layerA = new Layer
layerA.pinchable.enabled = true

layerA.on(Events.Pinch, () => print(layerA.scale, layerA.rotation))

Pinch Event Shortcuts

// For Events.Pinch
layerA.onPinch(() => print("Currently pinching"))

// For Events.PinchStart
layerA.onPinchStart(() => print("Start pinching"))

// For Events.PinchEnd
layerA.onPinchEnd(() => print("End pinching"))

Scale Events

Scale events receive the gesture event properties.

  1. Events.Scale — Scale a layer with two pointers.
  2. Events.ScaleStart — Start scaling.
  3. Events.ScaleEnd — End scaling.
layerA = new Layer
layerA.pinchable.enabled = true

layerA.on(Events.Scale, () => print(layerA.scale))

Scale Event Shortcuts

// For Events.Scale
layerA.onScale(() => print("Currently scaling"))

// For Events.ScaleStart
layerA.onScaleStart(() => print("Start scaling"))

// For Events.ScaleEnd
layerA.onScaleEnd(() => print("End scaling"))

Rotate Events

Rotate events receive the gesture event properties.

  1. Events.Rotate — Rotate a layer with two pointers.
  2. Events.RotateStart — Start rotating.
  3. Events.RotateEnd — End of rotating.
layerA = new Layer
layerA.pinchable.enabled = true

layerA.on(Events.Rotate, () => print(layerA.rotation))

Rotate Event Shortcuts

// For Events.Rotate
layerA.onRotate(() => print("Currently rotating"))

// For Events.RotateStart
layerA.onRotateStart(() => print("Start rotating"))

// For Events.RotateEnd
layerA.onRotateEnd(() => print("End rotating"))

Touch Events

  1. Events.TouchStart — Start a touch/click.
  2. Events.TouchMove — Touch move or mouse drag.
  3. Events.TouchEnd — End touch or click.
layerA = new Layer

// Returns the event and the layer
layerA.on(Events.TouchStart, (event, layer) => print(event, layer))

Touch Event Shortcuts

// For Events.TouchStart
layerA.onTouchStart(() => print("Start touch"))

// For Events.TouchMove
layerA.onTouchMove(() => print("Touch move"))

// For Events.TouchEnd
layerA.onTouchEnd(() => print("End touch"))

Click Events

  1. Events.Click — Click or touch (no delay on mobile).
layerA = new Layer

// Returns the event and the layer
layerA.on(Events.Click, (event, layer) => print(event, layer))

Click Event Shortcuts

// For Events.Click
layerA.onClick(() => print("Click"))

Mouse Events

  1. Events.MouseUp — Releasing the mouse click.
  2. Events.MouseDown — Pressing the mouse click.
  3. Events.MouseOver — Hover with mouse cursor.
  4. Events.MouseOut — Unhover with mouse cursor.
  5. Events.MouseMove — While the mouse cursor moves.
  6. Events.MouseWheel — Scrolling the mouse.
layerA = new Layer

// Returns the event and the layer
layerA.on(Events.MouseOver, (event, layer) => print(event, layer))

Mouse Event Shortcuts

// For Events.mouseup
layerA.onMouseUp(() => print("mouseup"))

// For Events.MouseDown
layerA.onMouseDown(() => print("mousedown"))

// For Events.MouseOver
layerA.onMouseOver(() => print("mouseover"))

// For Events.MouseOut
layerA.onMouseOut(() => print("mouseout"))

// For Events.MouseMove
layerA.onMouseMove(() => print("mousemove"))

// For Events.MouseWheel
layerA.onMouseWheel(() => print("mousewheel"))

Animation Events

  1. Events.AnimationStart — Animation start event, gets called when the animation starts.
  2. Events.AnimationStop — Animation stop event, when an animation is finished or gets stopped half way.
  3. Events.AnimationEnd — Animation end event, only gets called when the animation is completely finished.
layerA = new Layer

layerA.animate({
    x: 100
})

// Returns the animation and the layer
layerA.on(Events.AnimationEnd, (animation, layer) => print(animation, layer))

Animation Event Shortcuts

// For Events.AnimationStart
layerA.onAnimationStart(() => print("Animation started"))

// For Events.AnimationStop
layerA.onAnimationStop(() => print("Animation stopped"))

// For Events.AnimationEnd
layerA.onAnimationEnd(() => print("Animation ended"))

State Events

  1. Events.StateSwitchStart — Switch start event, gets called when the state starts switching.
  2. Events.StateSwitchStop — Switch stop event, when a switch fully finishes or gets stopped half way.
  3. Events.StateSwitchEnd — Switch end event, only gets called when the switch completely finishes.

(StateSwitch deprecated the StateWillSwitch and StateDidSwitch events)

layerA = new Layer

layerA.states.rotate =
    {rotation: 90}

layerA.stateSwitch("rotate")

// Returns the old and new state
layerA.on(Events.StateSwitchEnd, (from, to) => print(from, to))

State Event Shortcuts

// For Events.StateSwitchStart
layerA.onStateSwitchStart(() => print("Will switch state"))

// For Events.StateSwitchStop
layerA.onStateSwitchStop(() => print("Did switch state"))

// For Events.StateSwitchEnd
layerA.onStateSwitchEnd(() => print("Did switch state"))

Drag Events

  1. Events.Move — The layer is moving.
  2. Events.DragStart — Start of drag.
  3. Events.Drag — While dragging.
  4. Events.DragEnd — End of drag.
  5. Events.DragAnimationStart — Did start momentum/bounce animation.
  6. Events.DragAnimationEnd — Did end momentum/bounce animation.
  7. Events.DirectionLockStart — Did start lock direction.
layerA = new Layer
layerA.draggable.enabled = true

// Returns the offset (x, y) and the layer
layerA.on(Events.Move, (offset, layer) => print(offset, layer))

//`#`

layerA = new Layer
layerA.draggable.enabled = true

// Returns the event and the layer
layerA.on(Events.DragStart, (event, layer) => print(event, layer))

Drag Event Shortcuts

// For Events.Move
layerA.onMove(() => print("Moving"))

// For Events.DragStart
layerA.onDragStart(() => print("Start of drag"))

// For Events.Drag
layerA.onDrag(() => print("Dragging"))

// For Events.DragEnd
layerA.onDragEnd(() => print("End of drag"))

// For Events.DragAnimationStart
layerA.onDragAnimationStart(() => print("Start of drag animation"))

// For Events.DragAnimationEnd
layerA.onDragAnimationEnd(() => print("End of drag animation"))

// For Events.DirectionLockStart
layerA.onDirectionLockStart(() => print("Start of direction lock"))

Scroll Events

  1. Events.Move — The layer is moving.
  2. Events.ScrollStart — Start scrolling.
  3. Events.Scroll — While scrolling.
  4. Events.ScrollEnd — End of scroll.
  5. Events.ScrollAnimationDidStart — Did start momentum/bounce animation.
  6. Events.ScrollAnimationDidEnd — Did end momentum/bounce animation.
scroll = new ScrollComponent
layerA = new Layer({
    parent: scroll.content
})

// Returns the event and the layer
scroll.on(Events.ScrollStart, (event, layer) => print(event, layer))

Scroll Event Shortcuts

// For Events.Move
scroll.onMove(() => print("Moving"))

// For Events.ScrollStart
scroll.onScrollStart(() => print("Start of scroll"))

// For Events.Scroll
scroll.onScroll(() => print("Scrolling"))

// For Events.ScrollEnd
scroll.onScrollEnd(() => print("End of scroll"))

// For Events.ScrollAnimationDidStart
scroll.onScrollAnimationDidStart(() => print("Start of scroll animation"))

// For Events.ScrollAnimationDidEnd
scroll.onScrollAnimationDidEnd(() => print("End of scroll animation"))

EdgeSwipe Events

EdgeSwipe events receive the gesture event properties.

Basic

  1. Events.EdgeSwipe — Swipe from any edge of the screen.
  2. Events.EdgeSwipeStart — Start edge swipe.
  3. Events.EdgeSwipeEnd — End edge swipe.
// Swipe from any edge of the screen
Screen.on(Events.EdgeSwipe, event => print(event.distance))

EdgeSwipe Event Shortcuts

// For Events.EdgeSwipe
Screen.onEdgeSwipe(() => print("Swiping from edge"))

// For Events.EdgeSwipeStart
Screen.onEdgeSwipeStart(() => print("Start swiping from edge"))

// For Events.EdgeSwipeEnd
Screen.onEdgeSwipeEnd(() => print("End swiping from edge"))

Top

  1. Events.EdgeSwipeTop — Edge swipe from top.
  2. Events.EdgeSwipeTopStart — Start edge swipe from top.
  3. Events.EdgeSwipeTopEnd — End edge swipe from top.
// Swipe from the top edge of the screen
Screen.on(Events.EdgeSwipeTop, event => print(event.distance))

EdgeSwipeTop Event Shortcuts

// For Events.EdgeSwipeTop
Screen.onEdgeSwipeTop(() => print("Swiping from top edge"))

// For Events.EdgeSwipeTopStart
Screen.onEdgeSwipeTopStart(() => print("Start swiping from top edge"))

// For Events.EdgeSwipeTopEnd
Screen.onEdgeSwipeTopEnd(() => print("End swiping from top edge"))

Right

  1. Events.EdgeSwipeRight — Edge swipe from right.
  2. Events.EdgeSwipeRightStart — Start edge swipe from right.
  3. Events.EdgeSwipeRightEnd — End edge swipe from right.
// Swipe from the right edge of the screen
Screen.on(Events.EdgeSwipeRight, event => print(event.distance))

EdgeSwipeRight Event Shortcuts

// For Events.EdgeSwipeRight
Screen.onEdgeSwipeRight(() => print("Swiping from right edge"))

// For Events.EdgeSwipeRightStart
Screen.onEdgeSwipeRightStart(() => print("Start swiping from right edge"))

// For Events.EdgeSwipeRightEnd
Screen.onEdgeSwipeRightEnd(() => print("Start swiping from right edge"))

Bottom

  1. Events.EdgeSwipeBottom — Edge swipe from bottom.
  2. Events.EdgeSwipeBottomStart — Start edge swipe from bottom.
  3. Events.EdgeSwipeBottomEnd — End edge swipe from bottom.
// Swipe from the bottom edge of the screen
Screen.on(Events.EdgeSwipeBottom, event => print(event.distance))

EdgeSwipeBottom Event Shortcuts

// For Events.EdgeSwipeBottom
Screen.onEdgeSwipeBottom(() => print("Swiping from bottom edge"))

// For Events.EdgeSwipeBottomStart
Screen.onEdgeSwipeBottomStart(() => print("Start swiping from bottom edge"))

// For Events.EdgeSwipeBottomEnd
Screen.onEdgeSwipeBottomEnd(() => print("End swiping from bottom edge"))

Left

  1. Events.EdgeSwipeLeft — Edge swipe from left.
  2. Events.EdgeSwipeLeftStart — Start edge swipe from left.
  3. Events.EdgeSwipeLeftEnd — End edge swipe from left.
// Swipe from the left edge of the screen
Screen.on(Events.EdgeSwipeLeft, event => print(event.distance))

EdgeSwipeLeft Event Shortcuts

// For Events.EdgeSwipeLeft
Screen.onEdgeSwipeLeft(() => print("Swiping from left edge"))

// For Events.EdgeSwipeLeftStart
Screen.onEdgeSwipeLeftStart(() => print("Start swiping from left edge"))

// For Events.EdgeSwipeLeftEnd
Screen.onEdgeSwipeLeftEnd(() => print("End swiping from left edge"))

Transition Events

  1. Events.TransitionStart — Transition start event, when the transition begins.
  2. Events.TransitionHalt — Transition halt event, when a transition gets interrupted.
  3. Events.TransitionStop — Transition stop event, when a transition completely finishes.
  4. Events.TransitionEnd — Transition end event, when a transition completely finishes.
layerA = new Layer

let flow = new FlowComponent
flow.showOverlayRight(layerA)

flow.on(Events.TransitionStart, () => print("Transition started"))

Transition Event Shortcuts

// For Events.TransitionStart
flow.onTransitionStart(() => print("Transition started"))

// For Events.TransitionHalt
flow.onTransitionHalt(() => print("Transition halted"))

// For Events.TransitionStop
flow.onTransitionStop(() => print("Transition stopped"))

// For Events.TransitionEnd
flow.onTransitionEnd(() => print("Transition ended"))

Value Events

The Value Change events can be used for the SliderComponent or the RangeSliderComponent. The min and max-value events can only be used with Range Sliders.

  1. Events.SliderValueChange — Slider value change.
  2. Events.SliderMinValueChange — Minimum value change. (range sliders only)
  3. Events.SliderMaxValueChange — Maximum value change. (range sliders only)
let slider = new SliderComponent({
    x: Align.center,
    y: Align.center
})

slider.on(Events.SliderValueChange, () => print(slider.value))

Slider Event Shortcuts

// For Events.SliderValueChange
slider.onValueChange(() => print(slider.value))

// For Events.SliderMinValueChange
range.onMinValueChange(() => print(range.minValue))

// For Events.SliderMaxValueChange
range.onMaxValueChange(() => print(range.maxValue))

Change Events

The "change" event allows you to listen to properties as they're changing. Below is a full overview of properties you can listen for:

  1. "change:x" — New x position.
  2. "change:y" — New y position.
  3. "change:point" — New x or y position.
  4. "change:width" — New width value.
  5. "change:height" — New height value.
  6. "change:size" — New width or height values.
  7. "change:frame" — New x, y, width or height values.
  8. "change:scale" — New scale value.
  9. "change:rotation" — New rotation value.
  10. "change:borderRadius" — New borderRadius value.
  11. "change:currentPage" — New currentPage layer.
  12. "change:style" — New style declaration.
  13. "change:html" — New html declaration.
  14. "change:children" — Added or removed children.
  15. "change:parent" — Added or removed parent.

For example, you can get the x position of a layer while it's animating. Note that it'll return the exact, sub-pixel values.

layerA = new Layer

layerA.animate({
    x: 100
})

layerA.on("change:x", () => print(layerA.x))

The "change" events can be used to link property changes to one another, with modulate. In the example below, we'll rotate the layer. The returned values are used to move the second layer horizontally.

layerA = new Layer
layerB = new Layer({
    x: 100
})

// We rotate layerA from 0 to 180 degrees.
layerA.animate({
    rotation: 180
})

// When the rotation value from layerA changes
layerA.on("change:rotation", function() {

// Use the values to move layerB from 100 to 300
    const x = Utils.modulate(layerA.rotation, [0, 180], [100, 300], true)
    return layerB.x = x
})

Gesture Event Properties

Every gesture receives an event object with the following set of properties. The touchCenter, touchDistance, touchOffset, scale and rotation properties only return values when using multi-touch Events.

Positioning

  1. event.point — Current x and y position
  2. event.start — Start x and y position.
  3. event.previous — Previous x and y position.
layerA = new Layer
layerA.pinchable.enabled = true

layerA.on(Events.Pinch, event => print(event.point))

Offset

  1. event.offset — Current x and y offset.
  2. event.offsetTime — Current duration since start.
  3. event.offsetAngle — Current angle since start.
  4. event.offsetDirection — Current direction since start.
layerA = new Layer

layerA.on(Events.Pan, event => print(event.offset))

Deltas

  1. event.delta — Offset since last event.
  2. event.deltaTime — Time since last event.
  3. event.deltaAngle — Angle change since last event.
  4. event.deltaDirection — Direction change since last event.
layerA = new Layer

layerA.on(Events.Swipe, event => print(event.delta))

Velocity & Force

  1. event.velocity — Current speed in x and y values.
  2. event.force — Current pressure sensitivity of a tap.
layerA = new Layer

layerA.on(Events.Swipe, event => print(event.velocity))

Input

  1. event.fingers — Amount of fingers on screen.
  2. event.touchCenter — Center point between two fingers.
  3. event.touchDistance — Distance between two fingers.
  4. event.touchOffset — Offset between two fingers.
layerA = new Layer

layerA.on(Events.Rotate, event => print(event.fingers))

Scale & Rotation

  1. event.scale — Scale value from two fingers.
  2. event.scaleDirection — Current scaling direction (up or down).
  3. event.rotation — Rotation value from two fingers.
layerA = new Layer
layerA.pinchable.enabled = true

layerA.on(Events.Pinch, event => print(event.scaleDirection))

Events.touchEvent(event)

Extract the touch event from a given event on mobile.

layerA = new Layer

layerA.on(Events.Click, function(event, layer) {
    let myTouchEvent
    return myTouchEvent = Events.touchEvent(event)
})

Events.wrap(event)

Wrap a given DOM Element so we can keep track of the events and destroy them when needed. If you want to bind events to arbitrary dom element you should use this.

Events.wrap(window).addEventListener("resize", event => print("Page is resizing"))

Extras

Extras are optional parts of Prototyper that have specific tasks like preloading, touch emulation and hints. In general, they are enabled automatically based on where your prototype is shown. But extras are often overridable explicitly by you, if you require specific behaviour.

Hints

Hints are used to highlight layers that a user can interact with, such as taps, swipes, etc. They are mainly to help users discover what a project can do when they see it for the first time.

By default, hints are enabled both in Prototyper and when you share your prototypes with others. If you click anywhere outside of an interactive layer or outside of the device, purple rectangles will indicate the tappable or scrollable areas.

You can enable or disable hints for your entire projects like this:

Prototyper.Extras.Hints.disable()

Or enable them like this:

Prototyper.Extras.Hints.enable()

If you would like to show hints directly after a page loads, without any clicks you can do this:

Prototyper.Extras.Hints.enable()
Prototyper.Extras.Hints.showHints()

Some notes:

  • Draggable or scrollable areas will highlight if you tap them, but did not scroll.
  • Draggable or scrollable areas will only highlight if they can either scroll horizontal or vertically.
  • Layers with rounded corners will get a hint with rounded corners.
  • Rotated layers are currently unsupported.
  • Invisible layers will not show hints, unless they are set to invisible or their opacity is 0. They will show a hint if they are covered by another layer but still respond to taps.

Customization

You can override layers (or components based on layers) to customize the hint indicator (by default a purple rectangle). This is great when you want to disable the highlight on a specific layer, or have a specific visiual hint.

This is how you disable a hint on a specific layer:

layerA = new Layer
layerA.onTap(() => print("layerA"))

layerB = new Layer({x: 220})
layerB.onTap(() => print("layerB"))

// Set an empty function on showHint
layerB.showHint = () => print("nope")

And you can customize the hint the same way:

layerA = new Layer
layerA.onTap(() => print("layerA"))

layerB = new Layer({x: 220})
layerB.onTap(() => print("layerB"))

layerB.showHint = function(hintFrame) {

// Create a hint layer, this will automatically be
    // placed in the hints context on top of everything.
    const hint = new Layer({
        frame: hintFrame,
        backgroundColor: "red",
        opacity: 0.5
    })

// Add a cool animation
    hint.animate({
        scale: 1.3,
        opacity: 0,
        options: {
            time: 0.5
        }
    })

// Remove the layer when done
    return hint.onAnimationEnd(() => hint.destroy())
}

Preloader

When you open a project, our preloader makes sure your media is loaded before fully displaying. It analyzes the images and video you use and downloads them in the background, all while showing a circular progress indicator. When everything is fully loaded, it displays your project simultaneously.

A preloader vastly improves the user's experience because it avoids displaying your project in an incomplete state. When users interact with a prototype that is still loading, performance can suffer due to images being decompressed on the same thread that handles user interaction.

By default the preloader is only enabled outside of Prototyper, such as when you share a project online or via mirroring.

You can force enable the preloader like this:

Prototyper.Extras.Preloader.enable()

Or disable it like this:

Prototyper.Extras.Preloader.disable()

Customization

You can customize the preloader image with any image, such as your logo. To do so, use the setLogo() function:

Prototyper.Extras.Preloader.enable()
Prototyper.Extras.Preloader.setLogo("https://source.unsplash.com/random")

Manually adding images

While the preloader often does a great job of discovering the main images used in your project, it may fail to locate specific images that were used at arbitrary points. The preloader also allows you to add these images manually using Prototyper.Extras.Preloader.addImage().

In the example below, the preloader cannot discover the image that layerB uses because it only gets created after a tap, and theoretically could be any url. So in this scenarios, we add the image manually at the top of the prototype.

Prototyper.Extras.Preloader.enable()
Prototyper.Extras.Preloader.addImage("https://source.unsplash.com/random")

layerA = new Layer({point: Align.center})

layerA.onTap(() => layerB = new Layer({
    image: "https://source.unsplash.com/random"}))

Some notes:

  • Device images are not counted against the preloader and are shown instantly because they are likely cached.
  • There is a 30 second hard timeout on the preloader, after which your project gets shown even if not all images are loaded.
  • Cached images load faster the second time you visit a project.
  • Video preloading is based on the canplay event when enough buffer is available to play them.
  • Loading errors are counted as loaded, so that the project appears even if some images are missing.
  • The progress is based on image count and not loaded bytes, so if you have many small images and one big one, the last step may be significantly longer. Unfortunately, there is no great way to get progress based on size today.

FlowComponent

The FlowComponent helps you transition and navigate between multiple screens. It’s built on two basic functions: showNext to transition to a new layer, and showPrevious to cycle back through previous layers. You can also use it to design overlays like modals, and fixed elements like a tab bar. The FlowComponent fires Transition events. Learn more about them here.

Properties

  1. layer — A layer object, the targeted layer.
  2. options — An object with all the animation options like curve, time and more. (Optional)
// Create layer
layerA = new Layer({
    size: Screen.size
})

// Create FlowComponent
flow = new FlowComponent

// Show the layer
flow.showNext(layerA, {animate: true})

flow.showNext(layer, options)

Transition to a new layer. By default, it will animate to the layer, except if it’s the first layer added to the FlowComponent. If the width or height of the layer exceeds that of its parent, it will become scrollable. It also automatically detects whether to become vertically or horizontally scrollable.

Arguments

  1. layer — A layer object.
  2. options.animate — A boolean, sets whether the layer animates. (Optional)
  3. options.scroll — A boolean, sets whether the layer becomes scrollable. (Optional)
// Create layer
layerA = new Layer({
    size: Screen.size
})

// Create FlowComponent
flow = new FlowComponent

// Show the layer
flow.showNext(layerA)

Set animate to false to switch between layers without a transition.

// Create layers
layerA = new Layer({
    size: Screen.size,
    backgroundColor: "#00AAFF"
})

layerB = new Layer({
    size: Screen.size,
    backgroundColor: "#FFCC33"
})

// Create FlowComponent and show layer
flow = new FlowComponent
flow.showNext(layerA)

// Instantly show layerB on click
layerA.onClick(() => flow.showNext(layerB, {animate: false}))

flow.showPrevious(options)

Transition to the previous layer. By default, it will animate to the layer.

Arguments

  1. options.animate — A boolean, sets whether the layer animates. (Optional)
  2. options.scroll — A boolean, sets whether the layer becomes scrollable. (Optional)
// Create layer
layerA = new Layer
layerB = new Layer

// Create FlowComponent
flow = new FlowComponent
flow.showNext(layerA)

// Switch to layerA on click
layerA.onClick(() => flow.showNext(layerB))

// Return to the previous on click
layerB.onClick(() => flow.showPrevious())

flow.showOverlayCenter(layer, options)

Overlay a layer from the center, like a modal dialog.

Arguments

  1. layer — A layer object.
  2. options.animate — A boolean, sets whether the layer animates. (Optional)
  3. options.scroll — A boolean, sets whether the layer becomes scrollable. (Optional)
  4. options.modal — A boolean, sets whether the overlay becomes clickable. (Optional)
// Create layer
layerA = new Layer({
    size: Screen.size
})

// Create FlowComponent
flow = new FlowComponent

// Overlay the modal layer
flow.showOverlayCenter(layerA)

The modal argument is set to false by default. If you would like the overlay to be clickable and return to the previous screen, you can enable this boolean.

// Create layer
layerA = new Layer({
    backgroundColor: "#00AAFF",
    size: Screen.size
})

layerB = new Layer({
    borderRadius: 40,
    backgroundColor: "#FFF",
    size: 500
})

// Create FlowComponent
flow = new FlowComponent
flow.showNext(layerA)

// Show modal, overlay is not clickable
layerA.onClick(() => flow.showOverlayCenter(layerB, {modal: true}))

flow.showOverlayTop(layer, options)

Overlay a layer from the top, like a notification screen.

Arguments

  1. layer — A layer object.
  2. options.animate — A boolean, sets whether the layer animates. (Optional)
  3. options.scroll — A boolean, sets whether the layer becomes scrollable. (Optional)
  4. options.modal — A boolean, sets whether the overlay becomes clickable. (Optional)
// Create layer
layerA = new Layer({
    size: Screen.size
})

// Create FlowComponent
flow = new FlowComponent

// Overlay the layer
flow.showOverlayTop(layerA)

flow.showOverlayRight(layer, options)

Overlay a layer from the right.

Arguments

  1. layer — A layer object.
  2. options.animate — A boolean, sets whether the layer animates. (Optional)
  3. options.scroll — A boolean, sets whether the layer becomes scrollable. (Optional)
  4. options.modal — A boolean, sets whether the overlay becomes clickable. (Optional)
// Create layer
layerA = new Layer({
    size: Screen.size
})

// Create FlowComponent
flow = new FlowComponent

// Overlay the layer
flow.showOverlayRight(layerA)

flow.showOverlayBottom(layer, options)

Overlay a layer from the bottom.

Arguments

  1. layer — A layer object.
  2. options.animate — A boolean, whether the layer animates. (Optional)
  3. options.scroll — A boolean, whether the layer becomes scrollable. (Optional)
  4. options.modal — A boolean, sets whether the overlay becomes clickable. (Optional)
// Create layer
layerA = new Layer({
    size: Screen.size
})

// Create FlowComponent
flow = new FlowComponent

// Overlay the layer
flow.showOverlayBottom(layerA)

flow.showOverlayLeft(layer, options)

Overlay a layer from the left.

Arguments

  1. layer — A layer object.
  2. options.animate — A boolean, sets whether the layer animates. (Optional)
  3. options.scroll — A boolean, sets whether the layer becomes scrollable. (Optional)
  4. options.modal — A boolean, sets whether the overlay becomes clickable. (Optional)
// Create layer
layerA = new Layer({
    size: Screen.size
})

// Create FlowComponent
flow = new FlowComponent

// Overlay the layer
flow.showOverlayLeft(layerA)

flow.transition(layer, transition, options)

Create a custom transition. The transitions use states internally to cycle back and forward. There are three layers (current, next and background) with two states each (back and forward). If you don’t define a specific state, the FlowComponent assumes you don’t want to animate that layer.

Arguments

  1. layer — A layer object.
  2. transition — A function with the animation states.
  3. options.animate — A boolean, sets whether the layer animates. (Optional)
  4. options.scroll — A boolean, sets whether the layer becomes scrollable. (Optional)
// Custom transition
const scaleTransition = function(nav, layerA, layerB, overlay) {
    let transition
    return transition = {
        layerA: {
            show: {
                scale: 1.0,
                opacity: 1
            },
            hide: {
                scale: 0.5,
                opacity: 0
            }
        },
        layerB: {
            show: {
                scale: 1.0,
                opacity: 1
            },
            hide: {
                scale: 0.5,
                opacity: 0
            }
        }
    }
}

// Create layers
layerA = new Layer({
    backgroundColor: "#00AAFF",
    size: Screen.size
})

layerB = new Layer({
    backgroundColor: "#FFCC33",
    size: Screen.size
})

// Create FlowComponent
flow = new FlowComponent
flow.showNext(layerA)

// Switch to layerB with custom transition
layerA.onClick(() => flow.transition(layerB, scaleTransition))

The custom transition is a function that returns an object with states. Inside the function you have access to the arguments current FlowComponent, layerA, layerB and the overlay. If you don’t pass states for layerA, layerB or the overlay, it will leave the layer as is on a transition.

flow.current <layer>

The layer (screen) that is currently visible.

// Create layer
layerA = new Layer({
    size: Screen.size
})

// Create FlowComponent, add layer
flow = new FlowComponent
flow.showNext(layerA)

// Get current screen
print(flow.current)

flow.scroll <layer>

The automatically generated ScrollComponent layer. Any child layer that exceeds the width or height of the FlowComponent are automatically made scrollable. You can target the ScrollComponent with flow.scroll.

// Create layer
layerA = new Layer({
    width: Screen.width,
    height: Screen.height + 100
})

// Create FlowComponent, add layer
flow = new FlowComponent
flow.showNext(layerA)

// Adjust contentInset
flow.scroll.contentInset =
    {top: 100}

All scroll events are available when using flow.scroll. These events will only apply to the layer (or screen) that is currently visible.

// Create layer
layerA = new Layer({
    width: Screen.width,
    height: Screen.height + 100
})

// Create FlowComponent, add layer
flow = new FlowComponent
flow.showNext(layerA)

// Listen to scroll event
flow.scroll.onMove(function() {})
//...

Note that if you listen to scrolling events directly on the FlowComponent, like flow.onScroll, the event will apply to all scrollable child layers.

// Applies to any child layer
flow.onMove(function() {})
//...

// Applies to the currently visible layer
flow.scroll.onMove(function() {})
//...

flow.header <layer>

Add a sticky header to a scrollable screen, like a a fixed navigation bar.

// Create navigation layer
const navBar = new Layer

// Create FlowComponent
flow = new FlowComponent

// Anchor layer to the top
flow.header = navBar

flow.footer <layer>

Add a sticky footer to a scrollable screen, like a a fixed tab bar.

// Create tab bar layer
const tabBar = new Layer

// Create FlowComponent
flow = new FlowComponent

// Anchor layer to the bottom
flow.footer = tabBar

Gradient

The Gradient object can be used to create, customize and animate gradients. It consists of two colors (start, end) and an angle indicating its direction.

let gradient = new Gradient({
    start: "#05F",
    end: "#0DF"
})

The start and end values also accept Color objects.

gradient = new Gradient({
    start: new Color("#05F"),
    end: new Color("#0DF")
})

You can apply a gradient to a layer directly by using the layer.gradient property.

blue = new Gradient({
    start: "#05F",
    end: "#0DF"
})

layerA = new Layer({
    gradient: blue
})

All properties of the gradients object can be animated, too.

blue = new Gradient({
    start: "#05F",
    end: "#0DF"
})

const purple = new Gradient({
    start: "#30F",
    end: "#B8F"
})

layerA = new Layer({
    gradient: blue
})

layerA.animate({
    gradient: purple
})

gradient.start <string>

The start color. Set to black by default.

gradient = new Gradient({
    start: "#05F"
})

gradient.end <string>

The end color. Set to white by default.

gradient = new Gradient({
    start: "#05F",
    end: "#0DF"
})

gradient.angle <number>

The angle of the gradient. Set to 0 by default.

gradient = new Gradient({
    start: "#0DF",
    end: "#05F",
    angle: 180
})

Layer

Layers are the basic containers of Prototyper, which can contain images, videos, or text. You can position layers with numeric values and dynamic values. Layers contain many properties that define their appearance, such as opacity, rotation and scale. Layers can also be nested to adjust their hierarchy.

To create a layer, use the new keyword. Every layer has a set of default properties: a blue background, and a default width and height of 100.

layerA = new Layer

You can set layer properties when creating them:

layerA = new Layer({
    x: 100,
    y: 100,
    width: 250,
    height: 250,
    opacity: 0.5,
    backgroundColor: "white"
})

And you can also override them later:

layerA = new Layer({
    x: 100,
    y: 100
})

layerA.x = 200

layer.id <number>

A unique identification number for this layer. No other layer will have this number. The layer id is read only and cannot be changed.

layerA = new Layer
print(layerA.id)
// Output: 1

layer.name <string>

The name of a layer.

layerA = new Layer
layerA.name = "Button"

print(layerA.name)
// Output: "Button"

layer.x <number>

The x property of a layer defines its x position relative to the top left corner.

layerA = new Layer
layerA.x = 500

layer.y <number>

The y property of a layer defines its y position relative to the top left corner.

layerA = new Layer
layerA.y = 500

layer.z <number>

The z property of a layer defines its position in space, also known as depth. The larger this value, the further away the object is from the point of view.

Remember that you will have to enable perspective on a parent layer before you can see this effect. Also note the z property is different from layer.index (z-index) which defines the order for layers when they all have the same z value.

layerA = new Layer
layerA.z = 500

layer.width <number>

The width of the layer in pixels.

layerA = new Layer
layerA.width = 500

layer.height <number>

The height of the layer in pixels.

layerA = new Layer
layerA.height = 500

layer.minX <number>

The left edge location of the layer. Same as layer.x.

layerA = new Layer({
    x: 100,
    y: 100,
    width: 100,
    height: 100
})

print(layerA.minX)
// Output: 100

layer.minY <number>

The top edge location of the layer. Same as layer.y.

layerA = new Layer({
    x: 100,
    y: 100,
    width: 100,
    height: 100
})

print(layerA.minY)
// Output: 100

layer.maxX <number>

The right edge location of the layer.

layerA = new Layer({
    x: 100,
    y: 100,
    width: 100,
    height: 100
})

print(layerA.maxX)
// Output: 200

layerA.maxX = 500
print(layerA.x)
// Output: 400

layer.maxY <number>

The bottom edge location of the layer.

layerA = new Layer({
    x: 100,
    y: 100,
    width: 100,
    height: 100
})

print(layerA.maxY)
// Output: 200

layerA.maxY = 500
print(layerA.y)
// Output: 400

layer.midX <number>

The horizontal center for the layer.

layerA = new Layer({
    x: 100,
    y: 100,
    width: 100,
    height: 100
})

print(layerA.midX)
// Output: 150

layerA.midX = 500
print(layerA.x)
// Output: 450

layer.midY <number>

The vertical center for the layer.

layerA = new Layer({
    x: 100,
    y: 100,
    width: 100,
    height: 100
})

print(layerA.midY)
// Output: 150

layerA.midY = 500
print(layerA.y)
// Output: 450

layer.midPoint <object>

Set or capture the midX, and midY values of a layer.

layerA = new Layer

print(layerA.midPoint)
// Output: { x: 100, y: 100 }

layerA.midPoint = {
    x: 150,
    y: 200
}

print(layerA.midPoint)
// Output: { x: 150, y: 200 }

print(layerA.x)
// Output: 50

layer.point <object>

Set or capture the x, and y values of a layer.

layerA = new Layer

print(layerA.point)
// Output: { x: 0, y: 0 }

layerA.point = {
    x: 10,
    y: 200
}

print(layerA.point)
// Output: { x: 10, y: 200 }

print(layerA.x)
// Output: 10

layer.size <object>

Allows you to set or capture the width and height values of a layer.

layerA = new Layer

print(layerA.size)
// Output: { width: 100, height: 100 }

layerA.size = {
    width: 10,
    height: 10
}

print(layerA.size)
// Output: { width: 10, height: 10 }

print(layerA.width)
// Output: 10

layer.frame <object>

Allows you to set or capture the x, y, width and height values of a layer.

layerA = new Layer

print(layerA.frame)
// Output: { x: 100, y: 100, width: 100, height: 100 }

layerA.frame = {
    x: 10,
    y: 200,
    width: 10,
    height: 10
}

print(layerA.frame)
// Output: { x: 10, y: 200, width: 10, height: 10 }

print(layerA.x)
// Output: 10

layer.props <object>

Gets or sets all properties for this layer.

layerA = new Layer

// Get current layer properties
print(layerA.props)
// Output: { x: 100, y: 100, ...}

// Set properties
layerA.props = {
    rotation: 90,
    opacity: 0.5
}

layer.center()

Center this layer in its parent. If there is no parent, it will be centered relative to the screen.

layerA = new Layer({
    width: 500,
    height: 500
})

layerB = new Layer({
    parent: layerA,
    width: 100,
    height: 100
})

layerB.center()

print(layerB.x, layerB.y)
// Output: 200, 200

layer.centerX(offset)

Center this layer horizontally in its parent. If there is no parent it will be centered relative to the screen. The offset is a pixel offset from the center and optional.

Arguments

  1. offset — A number that offsets the position.
layerA = new Layer({
    width: 500,
    height: 500
})

layerB = new Layer({
    parent: layerA,
    width: 100,
    height: 100
})

layerB.centerX()
print(layerB.x, layerB.y)
// Output: 200, 0

layerB.centerX(20)
print(layerB.x, layerB.y)
// Output: 220, 0

layer.centerY(offset)

Center this layer vertically in its parent. If there is no parent it will be centered relative to the screen. The offset is a pixel offset from the center and optional.

Arguments

  1. offset — A number that offsets the position.
layerA = new Layer({
    width: 500,
    height: 500
})

layerB = new Layer({
    parent: layerA,
    width: 100,
    height: 100
})

layerB.centerY()
print(layerB.x, layerB.y)
// Output: 0, 200

layerB.centerY(20)
print(layerB.x, layerB.y)
// Output: 0, 220

layer.pixelAlign()

Round the x and y values of this layer to whole numbers. Allows you to snap layers on the pixel. This is useful when dynamically centering layers.

layerA = new Layer({
    x: 100.18293,
    y: 10.12873
})

layerA.pixelAlign()

print(layerA.x, layerA.y)
// Output: 100, 10

layer.screenFrame <object>

Allows you to set or capture the absolute position of this layer on the screen, ignoring the inherited position from its parents.

layerA = new Layer({
    x: 100
})

layerB = new Layer({
    parent: layerA,
    x: 100
})

print(layerB.screenFrame)
// Output: { x: 200, y: 0, width: 100, height: 100 }

layerB.screenFrame = {
    x: 400,
    y: 0,
    width: 100,
    height: 100
}

print(layerB.x)
// Output: 300

layer.contentFrame()

The calculated frame for the total size of all the children combined.

layerA = new Layer
layerB = new Layer({
    parent: layerA,
    x: 0,
    width: 100
})

let layerC = new Layer({
    parent: layerA,
    x: 100,
    width: 300
})

print(layerA.contentFrame())
// Output: { x: 0, y: 0, width: 400, height: 100 }

layer.centerFrame()

The calculated frame, centered within its parent. If there is no parent, it will be centered relative to the screen.

layerA = new Layer({
    width: 500,
    height: 500
})

layerB = new Layer({
    parent: layerA,
    width: 100,
    height: 100
})

print(layerB.centerFrame())
// Output: { x: 200, y: 200, width: 100, height: 100 }

layer.backgroundColor <string>

Sets the background color for this layer. The color is expressed as a string in the CSS color format. Layers have a light blue background color by default.

layerA = new Layer

layerA.backgroundColor = "red"
layerA.backgroundColor = "#00ff00"
layerA.backgroundColor = "rgba(134, 12, 64, 0.3)"
layerA.backgroundColor = "transparent"

// Remove the background color
layerA.backgroundColor = ""

layer.color <string>

Sets the text color for this layer. The color is expressed as a string in the CSS color format. Layers have a white text color by default.

layerA = new Layer

layerA.color = "red"
layerA.color = "#00ff00"
layerA.color = "rgba(134, 12, 64, 0.3)"
layerA.color = "transparent"

// Remove the color
layerA.color = ""

layer.gradient <object>

Sets the gradient of this layer. By default, gradients made in Code have a start color of #FFF, an end color of #000 and an angle set to 0. Gradients can be used alongside the backgroundColor property, too.

layerA = new Layer

// Set a gradient
layerA.gradient = {
    start: "#05F",
    end: "#0DF",
    angle: 0
}

layer.image <string>

Sets the background-image url or path for this layer. You can set it as a full url. The image will always fit to cover the layer, and will never be stretched. You can remove an image by setting it to null or an empty string.

// Hosted images
layerA.image = "https://source.unsplash.com/random"

Setting an image will remove the default background color of a layer. Set the background color to another color than the default to show it behind the image.

// Show a color where the image is transparent
layerA = new Layer({
    image: "images/logo.png",
    backgroundColor: "blue"
})

You can be notified of when an image is loaded and ready to display with the Events.ImageLoaded event. If there is an error loading an image (like not found) it will throw an Events.ImageLoadError event.

layerA = new Layer

// Listen to the loading event
layerA.on(Events.ImageLoaded, () => print("The image loaded"))

layerA.on(Events.ImageLoadError, () => print("The image couldn't be loaded"))

layerA.image = "images/logo.png"

layer.visible <boolean>

Sets whether the layer should be visible or not.

layerA = new Layer
layerA.visible = false

layer.opacity <number>

Sets the opacity for this layer. Opacity is defined with a number between 0 and 1 where 0 is invisible and 1 fully opaque.

layerA = new Layer
layerA.opacity = 0.5

layer.clip <boolean>

Sets whether the layer should clip its children. Clipping is disabled by default.

layerA = new Layer({
    width: 100,
    height: 100
})

layerB = new Layer({
    width: 200,
    height: 200,
    parent: layerA
})

layerA.clip = true

layer.ignoreEvents <boolean>

Enable or disable any user events added to layers. When disabled, no user events on the layer will be emitted. The default value for this is true. Prototyper automatically disables it when you add an event listener.

layerA = new Layer

layerA.on(Events.Click, () => print("Click!"))

// Now it won't respond to a click
layerA.ignoreEvents = true

// Now it will
layerA.ignoreEvents = false

layer.originX <number>

Sets the x origin for scale, rotate and skew transformations. The origin is defined as a number, where 0 is the left edge of the layer and 1 the right edge. The default value is 0.5, the center of the layer.

layerA = new Layer
layerA.rotation = 45
layerA.originX = 0
layerA.originX = 1

layer.originY <number>

Sets the y origin for scale, rotate and skew transformations. The origin is defined as a number, where 0 is the top edge of the layer and 1 the bottom edge. The default value is 0.5, the center of the layer.

layerA = new Layer
layerA.rotation = 45
layerA.originY = 0
layerA.originY = 1

layer.originZ <number>

Sets the z origin for 3D transformations. The origin is defined in pixels. Positive values bring 3D layers closer to you, and negative values further way.

layerA = new Layer({
    originZ: -45,
    rotationY: 90
})

layer.perspective <number>

Sets the perspective for child layers. Perspective gives depth to 3d properties like rotationX, rotationY. The rotation is set from 1 to Infinity where 1 is a huge perspective. Setting perspective to 0 gives you an isometric effect. Perspective is disabled by default.

layerA = new Layer

// Set the perspective for all sub layers
layerA.perspective = 100

layerB = new Layer({
    parent: layerA,
    rotationX: 30,
    rotationY: 30
})

layer.flat <boolean>

Enable or disable 3D properties for all children of the layer.

// Enable flat on its children
layerA = new Layer({
    width: 200,
    height: 200,
    x: 100,
    y: 100,
    clip: false,
    flat: true
})

// Rotate horizontally
layerA.rotationX = 45

// With flat enabled, adjusting z has no effect
layerB = new Layer({
    parent: layerA,
    z: 25
})

layer.backfaceVisible <boolean>

Defines whether a layer should be visible when not facing the screen. This is useful when an element is rotated, and you don't want to see its backside.

layerA = new Layer
layerA.backfaceVisible = false

layer.rotation <number>

Sets the rotation, relative to its transform origin. The rotation is defined in degrees between 0 and 360. The default value is 0.

layerA = new Layer
layerA.rotation = 45

layer.rotationX <number>

Sets the x rotation, relative to its transform origin. The rotation is defined in degrees between 0 and 360. The default value is 0.

layerA = new Layer
layerA.rotationX = 45

layer.rotationY <number>

Sets the y rotation, relative to its transform origin. The rotation is defined in degrees between 0 and 360. The default value is 0.

layerA = new Layer
layerA.rotationY = 45

layer.rotationZ <number>

Sets the z rotation, relative to its transform origin. The rotation is defined in degrees between 0 and 360. Same as layer.rotation.

layerA = new Layer
layerA.rotationZ = 45

layer.scale <number>

Sets the scale, relative to its transform origin. The default scale is

  1. Any number smaller then one will decrease the size and vice versa.
layerA = new Layer
layerA.scale = 2

layer.scaleX <number>

Sets the horizontal scale, relative to its transform origin. The default scale is 1. Any number smaller then one will decrease the size and vice versa.

layerA = new Layer
layerA.scaleX = 2

layer.scaleY <number>

Sets the vertical scale, relative to its transform origin. The default scale is 1. Any number smaller then one will decrease the size and vice versa.

layerA = new Layer
layerA.scaleY = 2

layer.parent <Layer object>

Sets the parent for this layer. You can set the parent to null if you want the layer to live at the root of your document. (Alias: superLayer)

layerA = new Layer
layerB = new Layer

layerB.parent = layerA

print(layerB.parent)
// Output: <Object:Layer layerA>

layer.children <Array>

All the child layers of this layer. (Alias: subLayers)

layerA = new Layer

layerB = new Layer({
    parent: layerA
})

layerC = new Layer({
    parent: layerA
})

print(layerA.children)
// Output: [<Object:Layer layerB>, <Object:Layer layerC>]

layer.childrenWithName(name)

All child layers of this layer, filtered by name. (Alias: subLayersByName)

Arguments

  1. name — A string of the layer name.
layerA = new Layer

layerB = new Layer({
    name: "navigation",
    parent: layerA
})

layerC = new Layer({
    name: "button",
    parent: layerA
})

print(layerA.childrenWithName("button"))
// Output: [<Object:Layer layerC>]

layer.siblings <Array>

All sibling layers of this layer. (Alias: siblingLayers)

layerA = new Layer

layerB = new Layer({
    parent: layerA
})

layerC = new Layer({
    parent: layerA
})

print(layerB.siblings)
// Output: [<Layer layerC id:3 (0,0) 200x200>]

layer.siblingsWithName(name)

All sibling layers of this layer, filtered by name.

Arguments

  1. name — A string of the layer name.
layerA = new Layer

layerB = new Layer({
    name: "navigation",
    parent: layerA
})

layerC = new Layer({
    name: "button",
    parent: layerA
})

print(layerB.siblingsWithName("button"))
// Output: [<Object:Layer name:button layerC>]

layer.descendants <Array>

All descendant layers of this layer. These include layers that are nested multiple levels deep, so also the child layers of its own child layers.

layerA = new Layer

layerB = new Layer({
    parent: layerA
})

layerC = new Layer({
    parent: layerB
})

print(layerA.descendants)
// Output: [<Layer id:2 name:layerB (0,0) 200x200>, <Layer id:3 name:layerC (0,0) 200x200>]

layer.ancestors()

All ancestor layers of this layer. These include layers that are nested multiple levels deep, so also the parent layers of its own parent layer.

layerA = new Layer

layerB = new Layer({
    parent: layerA
})

layerC = new Layer({
    parent: layerB
})

print(layerC.ancestors())
// Output: [<Layer id:2 name:layerB (0,0) 200x200>, <Layer id:1 name:layerA (0,0) 200x200>]

layer.addChild(layer)

Add a layer as a child to this layer. This will set the parent of the added layer. (Alias: addSubLayer)

Arguments

  1. layer — A layer object.
layerA = new Layer
layerB = new Layer

layerA.addChild(layerB)

print(layerB.parent)
// Output: <Object:Layer layerA>

layer.removeChild(layer)

Remove a layer from the children of this layer. (Alias: removeSubLayer)

Arguments

  1. layer — A layer object.
layerA = new Layer
layerB = new Layer({
    parent: layerA
})

layerA.removeChild(layerB)

print(layerB.parent)
// Output: null

Layer.select(selector)

Select a layer with a specific name.

layer = new Layer({
    name: "a"
})

print(Layer.select("a"))

Layer.selectAll(selector)

Select all layers with a specific name.

layer = new Layer({
    name: "a"
})

layerB = new Layer({
    name: "a"
})

print(Layer.selectAll("a"))

layer.selectChild(selector)

Select a child layer with a specific name.

layer = new Layer({
    name: "a"
})

print(layer.selectChild("a"))

layer.selectAllChildren(selector)

Select all child layers with a specific name.

layer = new Layer({
    name: "a"
})

print(layer.selectAllChildren("a"))

layer.index <number>

The order index for this layer. Sibling layers with a higher index (and the same z value) will drawn on top of this layer, and those with a lower index below.

The layer index increases by order of insertion. So if you add a layer as a child and the highest sibling index value is 5, the index of the inserted layer will be 6 (5 + 1). Or, the last inserted layer will always be on top.

layerA = new Layer
layerB = new Layer

// Draw layerB on top
layerA.index = 2
layerB.index = 1

layer.placeBefore(layer)

Places this layer before another layer. This changes the layer.index property for at least one of the layers. This method only works on layers that have the same parent, or no parent at all.

Arguments

  1. layer — A layer object.
layerA = new Layer
layerB = new Layer

// Draw layerB on top
layerB.placeBefore(layerA)

layer.placeBehind(layer)

Places this layer behind another layer. This changes the layer.index property for at least one of the layers. This method only works on layers that have the same parent, or no parent at all.

Arguments

  1. layer — A layer object.
layerA = new Layer
layerB = new Layer

// Draw layerB on top
layerA.placeBehind(layerB)

layer.bringToFront()

Places this layer in front of all other layers with the same parent.

layerA = new Layer
layerB = new Layer
layerC = new Layer

// Draw layerA on top
layerA.bringToFront()

layer.sendToBack()

Places this layer behind all other layers with the same parent.

layerA = new Layer
layerB = new Layer
layerC = new Layer

// Draw layerC last
layerC.sendToBack()

layer.html <string>

Insert HTML content into this layer. The html can be anything, from text, to input and form elements to canvas or SVG content.

If you need to target any of the created elements, remember that they are only available after Prototyper rendered them. To reliably get a reference to a DOM element, use layer.querySelector or layer.querySelectorAll.

If the content that gets inserted needs user interaction, it's best to set layer.ignoreEvents to false. To retain the layer structure, the content is placed within an element that gets created when you set HTML for the first time.

layerA = new Layer

// Add simple text content
layerA.html = "Hello"

// Add inline styled text content
layerA.html = "I'm <span style='color:red'>Koen"

// Add an input field
layerA.html = "<input type='text' value='Hello'>"

// Add a div with a canvas element and get a reference
layerA.html = "<div><canvas id='canvas'></canvas></div>"
const canvasElement = layerA.querySelectorAll("#canvas")

layer.style <object>

Set or get CC style properties for the layer.

Next to the standard CSS property names you can also camelCase naming. For example, layer.style["border-color"] is the same as layer.style.borderColor. For a full list see this overview.

layerA = new Layer

// Modify a single style property
layerA.style["outline"] = "1px solid red"

// Modify set of style properties
layerA.style = {
    "outline": "1px solid red",
    "padding": "10px"
}

// Get a specific style property
print(layerA.style["outline"])
// Output: "1px solid red"

layer.computedStyle()

Get all the current applied CSS style properties for the layer. Note that this is an expensive operation for the browser. For a full reference on computed style, see this overview.

layerA = new Layer
layerA.backgroundColor = "red"

print(layer.computedStyle()["background-color"])
// Output: "red"

layer.classList <ClassList object>

A list of class attributed for the layer. Also contains methods to add, remove, toggle and check for classes. For a full reference, see this overview.

layerA = new Layer

// Add the class .red
layerA.classList.add("red")

// Remove the class .red
layerA.classList.remove("red")

// Toggle the class .red
layerA.classList.toggle("red")

// See if the layer has class .red
print(layerA.classList.contains("red"))
// Output: true

layer.destroy()

This will remove a layer from the hierarchy and remove all its listeners. If the layer has children they will be destroyed too.

layerA = new Layer
layerA.destroy()

layer.copy()

This will copy a layer and all its children. The layers will have all the same properties as their copied counterparts (same position and looks). The event listeners will not be copied.

layerA = new Layer
layerB = new Layer({
    parent: layerA
})

layerC = layerA.copy()

layer.copySingle()

This will copy a layer without its children. Event listeners aren't copied.

layerA = new Layer
layerB = new Layer({
    parent: layerA
})

layerC = layerA.copySingle()

layer.blur <number>

Adds a gaussian blur to the layer. Gaussian blur is defined in pixels. The default value is 0.

layerA = new Layer
layerA.blur = 10

layer.backgroundBlur <number>

Adds a background blur to the layer. Background Blur is defined in pixels. The default value is 0. Please note that this may not work in every browser, and can produce rendering artifacts.

layerA = new Layer
layerA.backgroundBlur = 10

layer.blending <string>

Set the blending mode of the layer.

// Use soft light blending
layerA = new Layer({
    blending: Blending.softLight
})

Blending Options

  1. Blending.normal — Normal (default) blending mode.

<!-- end list -->

  1. Blending.darken — Darken blending mode.
  2. Blending.multiply — Multiply blending mode.
  3. Blending.colorBurn — Color Burn blending mode.

<!-- end list -->

  1. Blending.lighten — Lighten blending mode.
  2. Blending.screen — Screen blending mode.
  3. Blending.colorDodge — Color Dodge blending mode.

<!-- end list -->

  1. Blending.overlay — Overlay blending mode.
  2. Blending.softLight — Soft Light blending mode.
  3. Blending.hardLight — Hard Light blending mode.

<!-- end list -->

  1. Blending.difference — Difference blending mode.
  2. Blending.exclusion — Exclusion blending mode.

<!-- end list -->

  1. Blending.hue — Hue blending mode.
  2. Blending.saturation — Saturation blending mode.
  3. Blending.color — Color blending mode.
  4. Blending.luminosity — Luminosity blending mode.

Alternatively, you can use a string notation.

// Use overlay blending
layerA = new Layer({
    blending: "overlay"
})

layer.brightness <number>

Brightens or darkens a layer. Brightness is defined with a number. Setting brightness to 0 produces a completely black layer, while the value that produces a completely white layer depends on the color of your layer or image.

layerA = new Layer
layerA.brightness = 10

layer.saturate <number>

Saturates a layer. Saturation is defined with a number between 0 and 100 where 0 removes all saturation and 100 is default.

layerA = new Layer
layerA.saturate = 50

layer.hueRotate <number>

Sets the hue of a layer. The hue rotation is defined in degrees between 0 and 360. The default value is 0.

layerA = new Layer
layerA.hueRotate = 180

layer.contrast <number>

Sets the contrast of a layer. Contrast is defined with a number between 0 and 100 where 0 is removes all contrast. The default value is 100.

layerA = new Layer
layerA.contrast = 50

layer.invert <number>

Inverts the color of a layer. Invert is defined with a number between 0 and 100. The invert property inverts all colors and brightness values of a layer. Setting invert to 100 on a colored layer replaces all hues with their complementary colors. The default value is 0.

layerA = new Layer
layerA.invert = 100

layer.grayscale <number>

Grayscale converts all colors to gray. Grayscale is defined with a number between 0 and 100 where 100 turns all colors to a shade of gray. The default value is 0.

layerA = new Layer
layerA.grayscale = 100

layer.sepia <number>

Adds a sepia tone to your layer. Sepia is defined with a number between 0 to 100. The default value is 0.

layerA = new Layer
layerA.sepia = 100

layer.shadows <array>

Layers can have multiple shadows. You can inspect all included shadows by printing out the shadows property.

layerA = new Layer({
    shadow1: {
        y: 10,
        blur: 20
    },
    shadow2: {
        y: 2,
        blur: 4
    }
})

print(layerA.shadows)

You can also use the shadows property to copy all shadows from one layer to another, without having to reference them one-by-one.

layerB = new Layer
layerB.shadows = layerA.shadows

You can set a specific shadow by using shadow with a number appended, like shadow1. These numeric properties range from 1—9, so the maximum amount of shadows you could add using them is 9.

layerA = new Layer({
    shadow1: {
        y: 10,
        blur: 20,
        color: "red"
    }
})

layer.shadowX <number>

Defines the shadow direction on the x-axis. A positive value will produce a shadow from the right edge of a layer, whereas a negative value will produce a shadow from the left edge. A visible shadow will only appear if the shadowColor property is also defined.

layerA = new Layer
layerA.shadowX = 10

layer.shadowY <number>

Defines the shadow direction on the y-axis. A positive value will produce a shadow from the bottom edge of a layer, whereas a negative value will produce a shadow from the top edge. A visible shadow will only appear if the shadowColor property is also defined.

layerA = new Layer
layerA.shadowY = 10

layer.shadowBlur <number>

Adds a Gaussian blur to the shadowX or shadowY property. shadowBlur is defined with a number. The default value is 0.

layerA = new Layer
layerA.shadowY = 1
layerA.shadowBlur = 4

layer.shadowSpread <number>

Makes shadows larger in all directions. The shadow is expanded by the given value. Negative values cause the shadow to contract. If shadowX, shadowY and shadowBlur are all set to 0, this will appear as a border. A visible shadow will only appear if the shadowColor property is also defined.

layerA = new Layer
layerA.shadowY = 1
layerA.shadowBlur = 4
layerA.shadowSpread = 2

layer.shadowColor <string>

Sets the color of a layers shadow. The color is expressed as a string in the CSS color format.

layerA = new Layer
layerA.shadowY = 1
layerA.shadowBlur = 4
layerA.shadowColor = "rgba(0,0,0,0.2)"

layer.shadowType <string>

Defines the type of shadow: inner or outer.

layerA = new Layer
layerA.shadowY = 1
layerA.shadowBlur = 4
layerA.shadowType = "inner"

layer.borderRadius <number>

Rounds the corners of a layer in pixels. To create circles, set the property to a high value (50-100) or divide the layers width/height by two.

layerA = new Layer
layerA.borderRadius = 3

// To create a circle:
layerA.borderRadius = layerA.width/2

layer.borderColor <string>

Set the border color of this layer. The color is expressed as a string in the css color format.

layerA = new Layer
layerA.borderColor = "red"
layerA.borderWidth = 2

layer.borderWidth <number>

Set the width of the layer border in pixels.

layerA = new Layer
layerA.borderWidth = 2
layerA.borderColor = "red"

layer.animate(properties or state, options)

Animate a layer by creating a new animation object with a set of layer properties or a state name. The optional animation options allow you to define how the layer animates using curves, timing and more. You can run multiple animations at a time as long as they don’t alter the same layer properties.

Arguments

  1. properties or state — The layer properties or name of the state.
  2. options — An object with all the animation options like curve, time and more. (Optional)

Example: Animate with properties

layerA = new Layer

// Animate the x position
layerA.animate({
    x: 200
})

Example: Animate with properties and options

layerA = new Layer

// Animate the x position with options
layerA.animate({
    x: 200,
    options: {
        curve: Spring({damping: 0.5}),
        time: 0.5
    }
})

Example: Animate with states

layerA = new Layer

// Create a new state
layerA.states.stateA =
    {x: 200}

// State animation
layerA.animate("stateA")

Example: Animate with states and options

layerA = new Layer

// Create a new state
layerA.states.stateA =
    {x: 200}

// State animation with options
layerA.animate("stateA", {
    curve: Spring({damping: 0.5}),
    time: 0.5
})

layer.animationOptions <object>

The animation options manage how and when the layer will be animated. Edit things like the curve and timing to change the appearance of an animation.

Once set, the animation options are set for every animation performed on the layer, unless they’re overruled. You can also set the animation options for individual layer states.

Properties

  1. curve — A string, set to ease by default. (Optional)
  2. curveOptions — An object with the options of the set curve. (Optional)
  3. time — A number, the duration in seconds. (Optional)
  4. delay — A number, the delay of the animation. (Optional)
  5. repeat — A number, the amount of times it repeats. (Optional)
  6. colorModel — A string, the model to animate colors in. (Optional)
  7. instant — A boolean, instantly jump to the end of an animation. (Optional)
layerA = new Layer

layerA.animationOptions = {
    curve: Bezier.ease,
    time: 0.25
}

layer.animations()

Returns all the current running animations for this layer.

layerA = new Layer

layerA.animate({
    x: 100
})

layerA.animate({
    y: 100
})

print(layerA.animations())
// Output: [<Object Animation>, <Object Animation>]

layer.isAnimating <boolean>

A read-only property that checks if a layer is animating.

layerA = new Layer

layerA.animate({
    x: 100
})

print(layerA.isAnimating)
// Result: True

layer.animateStop()

Immediately stop all animations running on this layer.

layerA = new Layer

// Stop an animation immediately
layerA.animate({
    x: 100
})

layerA.animateStop()

layer.stateSwitch(name)

Instantly switch to a state without animating. (layer.stateSwitch() deprecated layer.states.switchInstant())

Arguments

  1. name — A string, the name of the state.
layerA = new Layer

layerA.states.stateA =
    {x: 100}

layerA.stateSwitch("stateA")

layer.stateCycle(states, options)

Cycle through all the layer states. Once we reach the end of the cycle we start at the beginning again. You can provide an array of state names for the ordering, if you don’t it will order based on when a state was added.

You can also add an animation options parameter to change the animation for a cycle.

(layer.stateCycle() deprecated layer.states.next())

Arguments

  1. states — An array of state names. (Optional)
  2. options — An object with all the animation options like curve, time and more. (Optional)
layerA = new Layer

layerA.states = {
    stateA: {
        x: 100
    },
    stateB: {
        x: 200
    }
}

// Every time we call this we cycle to the next state
layerA.stateCycle(["stateA", "stateB"])

layer.stateNames <Array>

A read-only property that returns an array with names of all states assigned to a layer.

layerA = new Layer

layerA.states = {
    stateA: {
        x: 100
    },
    stateB: {
        y: 100
    }
}

print(layerA.stateNames)
// Result: ["stateA", "stateB"]

layer.convertPointToCanvas(point)

Converts a point from a layer to the Canvas.

point = {
    x: 20,
    y: 40
}

layer = new Layer

let pointInCanvas = layer.convertPointToCanvas(point)

layer.convertPointToScreen(point)

Converts a point from a layer to the Screen.

point = {
    x: 20,
    y: 40
}

layer = new Layer

pointInScreen = layer.convertPointToScreen(point)

layer.convertPointToLayer(point, layer)

Converts a point from a layer to another layer.

point = {
    x: 20,
    y: 40
}

layerA = new Layer
layerB = new Layer

const pointInLayerB = layerA.convertPointToLayer(point, layerB)

layer.on(eventName, handler)

Start listening to an event on this layer.

When an event is called the first argument is the event information. Depending on the specific event this can contain mouse positions, mouse deltas etc. The second argument is always the layer that the event occurred to.

layerA = new Layer
layerA.name = "layerA"

layerA.on(Events.Click, (event, layer) => print("Clicked", layer.name))

// Output: "Clicked", "layerA"

layer.off(eventName, handler)

Stop listening to an event on this layer.

layerA = new Layer
layerA.name = "layerA"

clickHandler = (event, layer) => print("This layer was clicked", layer.name)

layerA.on(Events.Click, clickHandler)
layerA.off(Events.Click, clickHandler)

PageComponent

The PageComponent is based on the ScrollComponent, but designed for displaying paginated instead of continuous content. It supports content layers of different sizes, and can snap to layers based on location and scroll velocity.

// Create a new PageComponent and only allow horizontal scrolling.
let page = new PageComponent({
    width: Screen.width,
    height: Screen.height,
    scrollVertical: false
})

// Define the first page
let pageOne = new Layer({
    width: page.width,
    height: page.height,
    parent: page.content,
    backgroundColor: "#28affa"
})

Let's add a second page now. Read more about the addPage method.

// Define second page
let pageTwo = new Layer({
    width: page.width,
    height: page.height,
    backgroundColor: "#90D7FF"
})

// Add the second page to the right
page.addPage(pageTwo, "right")

Another way to go about adding content is by using a for loop.

// Create a new PageComponent and only allow horizontal scrolling.
page = new PageComponent({
    width: Screen.width,
    height: Screen.height,
    scrollVertical: false,
    backgroundColor: "#fff"
})

// Create 5 new layers and add them to the page.content
for (let number = 0 number < 5 number++) {
    const pageContent = new Layer({
        width: page.width,
        height: page.height,
        x: page.width * number,
        backgroundColor: Utils.randomColor(0.5),
        parent: page.content
    })

// Visualize the current page number
    pageContent.html = (pageContent.html = number + 1)

// Center the current page number
    pageContent.style = {
        "font-size" : "100px",
        "font-weight" : "100",
        "text-align" : "center",
        "line-height" : `${page.height}px`
    }
}

page.originX <number>

Defines how pages will be horizontally snapped to. The origin is defined as a number between 0 and 1, where 0 is the left-edge and 1 the right-edge. The default value is 0.5, the center.

page = new PageComponent
page.originX = 0

page.originY <number>

Defines how pages will be vertically snapped to. The origin is defined as a number between 0 and 1, where 0 is the top-edge and 1 the bottom-edge. The default value is 0.5, the center.

page = new PageComponent
page.originY = 0

page.velocityThreshold <number>

The velocityThreshold influences the role velocity plays in snapping to a different page. Besides the scrolling distance, the PageComponent also takes your scrolling speed (velocity) into account.

page = new PageComponent
page.velocityThreshold = 0.2

To better understand the effects of adjusting the velocityThreshold, you can print out your velocity after scrolling. If you want switching between pages to be based mostly on distance, increase the velocityThreshold.

// Increase the velocityThreshold
page.velocityThreshold = 5

// After switching between pages, print the velocity
page.on(Events.ScrollEnd, () => print(Math.abs(page.velocity.x)))

page.animationOptions <object>

Set the animation options for the PageComponent. This defines the animation that occurs on ScrollEnd, when snapping to a page.

page = new PageComponent

page.animationOptions = {
    curve: Bezier.ease,
    time: 0.25
}

page.currentPage <Layer object>

Get the current page layer. (Read-only)

page = new PageComponent

// Get the current page layer
print(page.currentPage)

Note that you have to have pages within the page.content layer. You can also listen to the "change:currentPage" event to get the new currentPage, after it has been changed.

page = new PageComponent

// When the current page changes, print the new one
page.on("change:currentPage", () => print(page.currentPage))

page.closestPage <Layer object>

Get the closest page layer. (Read-only)

page = new PageComponent

// Get the current page layer
print(page.closestPage)

Note that you have to have pages within the page.content layer. You can also listen to the Scroll event to get the page closest page while scrolling.

// Create a new PageComponent and only allow horizontal scrolling.
page = new PageComponent

// Print the closest page while scrolling
page.on(Events.Scroll, () => print(page.closestPage))

page.nextPage(direction, currentPage)

Get the next page. Takes two arguments: direction and the currentPage. By default, the direction is set to "right" and the currentPage will be the first page.

page = new PageComponent({
    width: Screen.width,
    height: Screen.height
})

pageOne = new Layer({
    width: page.width,
    height: page.height,
    parent: page.content,
    backgroundColor: "#28affa"
})

pageTwo = new Layer({
    width: page.width,
    height: page.height,
    backgroundColor: "#90D7FF"
})

page.addPage(pageTwo, "right")
print(page.nextPage())

We can also set the currentPage to any other page. For instance, we can look which layer is at the left of the second page.

// Get the page to the left of pageTwo
print(page.nextPage("left", pageTwo))

// Returns pageOne

page.previousPage <Layer object>

Get the previous page. Effectively the same as getting the page on the left using page.nextPage("left"). (Read-only)

page = new PageComponent

// Get the previous page
print(page.previousPage)

page.snapToPage(page, animate, animationOptions)

Snap to a specific page. Takes three arguments: a page.content layer, animate (true or false) and animation options. By default, animate is set to true and the animationCurve use a spring curve.

page = new PageComponent({
    width: Screen.width
})

In the example above, we can customize the scrolling animation by defining custom animationOptions as well.

// Define a slower easing curve
page.snapToPage(
    pageTwo,
    true,
    (animationOptions = {time: 2})
)

page.snapToNextPage(direction, animate, animationOptions)

Snap to a specific the next page. Takes three arguments: direction, animate (true or false) and animation options. By default, the direction is set to "right" and animate is true.

page = new PageComponent({
    width: Screen.width,
    height: Screen.height
})

pageOne = new Layer({
    width: page.width,
    height: page.height,
    parent: page.content,
    backgroundColor: "#28affa"
})

pageTwo = new Layer({
    width: page.width,
    height: page.height,
    backgroundColor: "#90D7FF"
})

page.addPage(pageTwo, "right")

// Automatically scroll to pageTwo
page.snapToNextPage()

This allows you to snap to pages in any direction. For example, we can start on the first page by snapping to it without animating, and then animate back to the first page.

// Start at page two by default
page.snapToPage(pageTwo, false)

// Scroll back to the page at its left, which is pageOne
page.snapToNextPage("left", true)

page.snapToPreviousPage()

Snaps to the previous page. It keeps track of all previously visited pages, included the direction.

page = new PageComponent

// Snap to the previous page
page.snapToPreviousPage()

page.addPage(direction)

Add a new page to the page.content layer of the PageComponent. It takes two arguments: a layer (page) and a direction ("right" or "bottom").

page = new PageComponent({
    width: Screen.width,
    height: Screen.height
})

// The first page, placed directly within the page.content
pageOne = new Layer({
    width: page.width,
    height: page.height,
    parent: page.content,
    backgroundColor: "#28affa"
})

// Second page
pageTwo = new Layer({
    width: page.width,
    height: page.height,
    backgroundColor: "#90D7FF"
})

// Third page
const pageThree = new Layer({
    width: page.width,
    height: page.height,
    backgroundColor: "#CAECFF"
})

// Add the second and third page to the right
page.addPage(pageTwo, "right")
page.addPage(pageThree, "right")

If you're looking to add pages to the left, you can initially add them to the right, and instantly switch to a different page, using snapToPage().

page = new PageComponent({
    width: Screen.width,
    height: Screen.height
})

pageOne = new Layer({
    width: page.width,
    height: page.height,
    parent: page.content,
    backgroundColor: "#28affa"
})

pageTwo = new Layer({
    width: page.width,
    height: page.height,
    backgroundColor: "#90D7FF"
})

// Add a page to the right
page.addPage(pageTwo, "right")

// Start at the second page by default
page.snapToPage(pageTwo, false)

page.horizontalPageIndex(page)

Get the index for a page component with horizontal pages. This is a number between 0 and the number of pages minus 1.

page = new PageComponent({
    width: Screen.width,
    height: Screen.height
})

let pageA = new Layer({
    size: page.size
})

let pageB = new Layer({
    size: page.size
})

page.addPage(pageA, "right")
page.addPage(pageB, "right")

print(page.horizontalPageIndex(pageA))
// Prints: 0

print(page.horizontalPageIndex(pageB))
// Prints: 1

page.verticalPageIndex(page)

Get the index for a page component with vertical pages. This is a number between 0 and the number of pages minus 1.

page = new PageComponent({
    width: Screen.width,
    height: Screen.height
})

pageA = new Layer({
    size: page.size
})

pageB = new Layer({
    size: page.size
})

page.addPage(pageA, "bottom")
page.addPage(pageB, "bottom")

print(page.verticalPageIndex(pageA))
// Prints: 0

print(page.verticalPageIndex(pageB))
// Prints: 1

Pinchable

Pinchable layers can be scaled and rotated with two fingers. By default, both of these properties are enabled. You can also define custom scale ranges, by defining minimum and maximum values. To pinch layers within Prototyper, hold the alt key while moving your cursor.

layer.pinchable.enabled <boolean>

Enable pinching for the layer.

layerA = new Layer
layerA.pinchable.enabled = true

layer.pinchable.threshold <number>

The minimal distance between two pointers before the gesture is recognized. Set to 0 by default.

layerA = new Layer
layerA.pinchable.enabled = true

// Set the minimal distance to 10
layerA.pinchable.threshold = 10

layer.pinchable.centerOrigin <boolean>

Sets the transform origin of your pinchable layer to the center point between your fingers. Set to true by default.

layerA = new Layer
layerA.pinchable.enabled = true

// Always scale from the center of the layer
layerA.pinchable.centerOrigin = false

layer.pinchable.scale <boolean>

Enable or disable scaling on pinch. Set to true by default.

layerA = new Layer
layerA.pinchable.enabled = true

// Disable scale on pinch
layerA.pinchable.scale = false

layer.pinchable.scaleIncrements <number>

Scale the pinchable layer incrementally.

layerA = new Layer
layerA.pinchable.enabled = true

// Scale in increments of 0.5 (0.5, 1, 1.5, 2)
layerA.pinchable.scaleIncrements = 0.5

layer.pinchable.minScale <number>

Set the minimal scale value of the pinchable layer.

layerA = new Layer
layerA.pinchable.enabled = true

// Set the minimal scale to 0.5
layerA.pinchable.minScale = 0.5

layer.pinchable.maxScale <number>

Set the maximal scale value of the pinchable layer.

layerA = new Layer
layerA.pinchable.enabled = true

// Set the maximal scale to 2
layerA.pinchable.maxScale = 2

layer.pinchable.scaleFactor <number>

Set the scaling factor of the pinchable layer. Set to 1 by default.

layerA = new Layer
layerA.pinchable.enabled = true

// Increase scaling speed by 2
layerA.pinchable.scaleFactor = 2

layer.pinchable.rotate <boolean>

Enable or disable rotation on pinch. Set to true by default.

layerA = new Layer
layerA.pinchable.enabled = true

// Disable scale on pinch
layerA.pinchable.rotate = false

layer.pinchable.rotateIncrements <number>

Rotate the pinchable layer incrementally.

layerA = new Layer
layerA.pinchable.enabled = true

// Rotate in increments of 15 degrees
layerA.pinchable.rotateIncrements = 15

layer.pinchable.rotateFactor <number>

Set the rotation factor of the pinchable layer. Set to 1 by default.

layerA = new Layer
layerA.pinchable.enabled = true

// Increase the rotation speed by 2
layerA.pinchable.rotateFactor = 2

Print

Printing allows you to inspect variables on runtime. It works similarly to console.log, only when using print, the output is shown directly within your prototype. Note that you need to use print() in Javascript (but not in CoffeeScript). We will omit these in the rest of the docs.

print("Hello")
// Output: "Hello"

You can inspect any type of value, and even multiple at the same time.

layerA = new Layer({
    x: 10,
    y: 20
})

// A single property value
print(layerA.x)
// Output: 10

// Multiple values
print(layerA.x, print(layerA.y))
// Output: 10, 20

RangeSliderComponent

The RangeSliderComponent creates a range slider with two knobs. You can use it to define and edit a numeric range, like a price filter. It consists of four layers: the slider itself, the fill, the minKnob and the maxKnob.

// Create a range slider
var range = new RangeSliderComponent({
    x: Align.center,
    y: Align.center
})

By default, the slider has a dark fill color, a light-gray backgroundColor and rounded corners with borderRadius. The radius of the fill automatically matches with that of the slider, so you only need to set it once.

// Customize the appearance
range.backgroundColor = "#ddd"
range.borderRadius = 4

rangeSlider.min <number>

The mininum range of the slider. Set to 0 by default.

// Create a range slider
range = new RangeSliderComponent({
    x: Align.center,
    y: Align.center,
    min: 0,
    max: 10
})

rangeSlider.max <number>

The maximum range of the slider. Set to 1 by default.

// Create a range slider
range = new RangeSliderComponent({
    x: Align.center,
    y: Align.center,
    min: 0,
    max: 10
})

rangeSlider.minValue <number>

The minimum value of the slider. Set to 0 by default.

// Create a range slider
range = new RangeSliderComponent({
    x: Align.center,
    y: Align.center,
    minValue: 0
})

You can exclusively listen to minimum value changes.

range.onMinValueChange(() => print(range.minValue))

You can also listen to any value changes using the Value Change event.

range.onValueChange(() => print(range.minValue, range.maxValue))

rangeSlider.maxValue <number>

The maximum value of the slider. Set to 0.5 by default.

// Create a range slider
range = new RangeSliderComponent({
    x: Align.center,
    y: Align.center,
    maxValue: 0.5
})

You can exclusively listen to maximum value changes.

range.onMaxValueChange(() => print(range.maxValue))

You can also listen to any value changes using the Value Change event.

range.onValueChange(() => print(range.minValue, range.maxValue))

rangeSlider.knobSize <number>

The size of both knobs. This automatically sets the width and height of the minKnob and the maxKnob. The default value is 30.

// Create a range slider
range = new RangeSliderComponent({
    x: Align.center,
    y: Align.center
})

// Change the size of the knobs
range.knobSize = 40

rangeSlider.fill <layer>

The fill of the slider. The width and height are automatically updated, based on the size of the slider. By default, its backgroundColor is set to #333.

// Create a range slider
range = new RangeSliderComponent({
    x: Align.center,
    y: Align.center
})

// Set the fill color to blue
range.fill.backgroundColor = "#00AAFF"

rangeSlider.minKnob <layer>

The knob that influences the minimum value of the slider.

// Create a range slider
range = new RangeSliderComponent({
    x: Align.center,
    y: Align.center
})

The minKnob is a draggable layer, with momentum enabled.

// Disable momentum
range.minKnob.draggable.momentum = false

rangeSlider.maxKnob <layer>

The knob that influences the maximum value of the slider.

// Create a range slider
range = new RangeSliderComponent({
    x: Align.center,
    y: Align.center
})

The maxKnob is a draggable layer, with momentum enabled.

// Disable momentum
range.maxKnob.draggable.momentum = false

rangeSlider.animateToMinValue(minValue, animationOptions)

Automatically animate to a specific minimum value.

Arguments

  1. minValue — A number, representing the minimum value.
  2. animationOptions — An object with curve, time, delay and repeat properties. <span>(Optional)
// Create a range slider
range = new RangeSliderComponent({
    x: Align.center,
    y: Align.center
})

// Animate to 1
range.animateToMinValue(0.3)

// Animate with a custom curve
range.animateToMinValue(0.3, { curve: Spring })

rangeSlider.animateToMaxValue(maxValue, animationOptions)

Automatically animate to a specific maximum value.

Arguments

  1. maxValue — A number, representing the maximum value.
  2. animationOptions — An object with curve, time, delay and repeat properties. <span>(Optional)
// Create a range slider
range = new RangeSliderComponent({
    x: Align.center,
    y: Align.center
})

// Animate to 1
range.animateToMaxValue(1)

// Animate with a custom curve
range.animateToMaxValue(1, { curve: Spring })

Screen

The Screen object contains the size of the current device screen. The size changes when switching to a different device. You can also change the background color and the perspective of the device screen.

Screen.backgroundColor <string>

Sets the background color of the device screen.

// Change the device screen background color
Screen.backgroundColor = "#28affa"

Screen.width <number>

The width of the current device screen in pixels. (Read-only)

print(Screen.width)
// Output: 640

Screen.height <number>

The height of the current device screen in pixels. (Read-only)

print(Screen.height)
// Output: 1080

Screen.size <object>

The width and height of the current device screen in pixels. (Read-only)

print(Screen.size)
// Output: { width:640, height: 1080 }

Screen.frame <object>

The x, y, width and height of the current device screen in pixels. (Read-only)

print(Screen.frame)
// Output: { x:0, y:0, width:640, height: 1080 }

Screen.perspective <number>

The perspective of the current device screen. Set to 1200 by default.

// Rotate layer in 3D
layerA = new Layer({
    rotationX: 30
})

// Adjust perspective
Screen.perspective = 1000

Screen.perspectiveOriginX <number>

Sets the x origin for 3D transformations. The origin is defined as a number, where 0 is the left edge of the screen and 1 the right edge. The default value is 0.5, the center of the screen.

// Rotate layer in 3D
layerA = new Layer({
    rotationX: 30
})

// Set horizontal perspective origin
Screen.perspectiveOriginX = 1

Screen.perspectiveOriginY <number>

Sets the y origin for 3D transformations. The origin is defined as a number, where 0 is the top edge of the screen and 1 the bottom edge. The default value is 0.5, the center of the screen.

// Rotate layer in 3D
layerA = new Layer({
    rotationX: 30
})

// Set vertical perspective origin
Screen.perspectiveOriginY = 1

Screen.convertPointToCanvas(point)

Converts a point from the Screen to the Canvas.

point = {
    x: 20,
    y: 40
}

pointInCanvas = Screen.convertPointToCanvas(point)

Screen.convertPointToLayer(point, layer)

Converts a point from the Screen to a layer.

point = {
    x: 20,
    y: 40
}

layer = new Layer

pointInLayer = Screen.convertPointToLayer(point, layer)

ScrollComponent

A ScrollComponent is used to scroll content. It implements momentum and spring physics, allows for customization, and emits different events.

The ScrollComponent is built with two layers. The ScrollComponent itself is a layer that masks its content. It has a content layer that has draggable enabled and constraints configured. It automatically manages the size of the content layer based on the total size of the sub layers of the content layer.

// Create a new ScrollComponent
scroll = new ScrollComponent({
    width: 100,
    height: 100
})

// Include a Layer
layerA = new Layer({
    parent: scroll.content
})

You can also wrap an existing layer within a ScrollComponent, using ScrollComponent.wrap(). The ScrollComponent will insert itself in-between the content and its super layer. You can learn more about wrapping in the learn section.

layerA = new Layer({
    width: 300,
    height: 300
})

scroll = ScrollComponent.wrap(layerA)

scroll.content <layer>

The layer to add content to. To add content, create a new Layer and set its parent to the scroll.content layer. When the content doesn't fit the ScrollComponent it will be clipped.

scroll = new ScrollComponent({
    width: 100,
    height: 100
})

layerA = new Layer({
    parent: scroll.content,
    image: "images/bg.png",
    width: 100,
    height: 200
})

scroll.contentInset <object>

Inset for the content. This will give your content extra padding between the constraints and the actual content layers.

scroll = new ScrollComponent({
    width: 100,
    height: 100
})

layerA = new Layer({
    parent: scroll.content,
    image: "images/bg.png",
    width: 100,
    height: 200
})

scroll.contentInset = {
    top: 20,
    right: 0,
    bottom: 20,
    left: 0
}

scroll.speedX <number>

Horizontal scrolling speed, number between 0 and 1. Default value is 1.

scroll = new ScrollComponent

layerA = new Layer({
    parent: scroll.content
})

scroll.speedX = 0.5

scroll.speedY <number>

Vertical scrolling speed, number between 0 and 1. Default value is 1.

scroll = new ScrollComponent

layerA = new Layer({
    parent: scroll.content
})

scroll.speedY = 0.5

scroll.scroll <boolean>

Enable or disable scrolling. Enabled by default. If you set this to false, it will set both scrollVertical and scrollHorizontal to false.

scroll = new ScrollComponent

layerA = new Layer({
    parent: scroll.content
})

scroll.scroll = false

scroll.scrollHorizontal <boolean>

Enable or disable horizontal scrolling.

scroll = new ScrollComponent

layerA = new Layer({
    parent: scroll.content
})

scroll.scrollHorizontal = false

scroll.scrollVertical <boolean>

Enable or disable vertical scrolling.

scroll = new ScrollComponent

layerA = new Layer({
    parent: scroll.content
})

scroll.scrollVertical = false

scroll.scrollX <number>

Horizontal scroll location.

scroll = new ScrollComponent

layerA = new Layer({
    parent: scroll.content
})

scroll.scrollX = 250

scroll.scrollY <number>

Vertical scroll location.

scroll = new ScrollComponent

layerA = new Layer({
    parent: scroll.content
})

scroll.scrollY = 250

scroll.scrollPoint <object>

Define the scroll location with x and y properties.

scroll = new ScrollComponent

layerA = new Layer({
    parent: scroll.content
})

scroll.scrollPoint = {
    x: 0,
    y: 50
}

scroll.scrollFrame <object>

Visible scroll frame.

scroll = new ScrollComponent

layerA = new Layer({
    parent: scroll.content
})

scroll.scrollFrame = {
    x: 0,
    y: 250,
    width: 250,
    height: 250
}

scroll.velocity <number>

Current scroll speed and direction in pixels per second at this current time.

scroll = new ScrollComponent

// On scroll, print the velocity
scroll.on(Events.Scroll, () => print(scroll.velocity))

scroll.direction <string>

Current scrolling direction. Returns "up", "down", "left", or "right". The scrolling direction is the inverse of the direction of the drag action: when dragging downwards, you're effectively scrolling upwards. (Read-only)

scroll = new ScrollComponent

// On scroll, print the direction
scroll.on(Events.Scroll, () => print(scroll.direction))

scroll.directionLock <boolean>

Snap to horizontal/vertical direction after a certain threshold.

scroll = new ScrollComponent

// Allow dragging only in one direction at a time
scroll.directionLock = true

scroll.directionLockThreshold <object>

The thresholds for lock directions. The x and y values represent the distance you can drag in a certain direction before it starts locking.

scroll = new ScrollComponent

// Snap horizontally after dragging 50px
// Snap vertically instantly
scroll.directionLock = true

scroll.directionLockThreshold = {
    x: 50,
    y: 0
}

scroll.angle <number>

Current scrolling angle (in degrees). The scrolling angle is the inverse of the direction of the drag action: when dragging downwards, you're effectively scrolling upwards. (Read-only)

scroll = new ScrollComponent

// On scroll, print the angle
scroll.on(Events.Scroll, () => print(scroll.angle))

scroll.isDragging <boolean>

Whether the layer is currently being dragged (returns false when animating). (Read-only)

scroll = new ScrollComponent

// Check if the layer is being dragged
scroll.onMove(() => print(scroll.isDragging))

scroll.isMoving <boolean>

Whether the content is currently moving, either by dragging or by a momentum/bounce animation. (Read-only)

scroll = new ScrollComponent

// Check if the layer is moving
scroll.onMove(() => print(scroll.isMoving))

scroll.closestContentLayer(originX, originY)

Get the layer closest to the ScrollComponent, depending on the defined origin. The origin is defined as numbers between 0 and 1, where (0,0) is the top-left corner, (0.5, 0.5) the center, and (1,1) the bottom-right corner.

The default values are (0,0). This means that it calculates the distance from the top-left of the ScrollComponent to the top-left of the content layers.

scroll = new ScrollComponent

// Create content layers
layerA = new Layer({
    parent: scroll.content,
    name: "layerA",
    x: 0,
    y: 0
})

layerB = new Layer({
    parent: scroll.content,
    name: "layerB",
    x: 50,
    y: 50
})

// Get the Layer of which the center point is closest
// to the center point of the ScrollComponent
print(scroll.closestContentLayer(0.5, 0.5))

scroll.closestContentLayerForScrollPoint(originX, originY)

Get the content layer closest to a specific point.

scroll = new ScrollComponent

// Create content layers
layerA = new Layer({
    parent: scroll.content,
    name: "layerA",
    x: 0,
    y: 0
})

layerB = new Layer({
    parent: scroll.content,
    name: "layerB",
    x: 50,
    y: 50
})

// Get the layer of which the top-left
// corner is closest to x: 50, y: 25
print(scroll.closestContentLayerForScrollPoint({
    x: 50,
    y: 25
})
)

// Returns layerB

You can adjust the origin values to define how the distance is calculated. The default values are (0,0). This means that it calculates the distance from the top-left of the ScrollComponent to the top-left of the content layers.

scroll = new ScrollComponent

// Create content layers
layerA = new Layer({
    parent: scroll.content,
    name: "layerA",
    x: 0,
    y: 0
})

layerB = new Layer({
    parent: scroll.content,
    name: "layerB",
    x: 50,
    y: 50
})

// With the origins set to the center,
// layerA becomes the closest
print(scroll.closestContentLayerForScrollPoint({ x: 50, y: 25 }, 0.5, 0.5))

// Returns layerA

scroll.scrollToPoint(point, animate, animationOptions)

Scroll to a specific point, optionally animating.

Arguments

  1. point — An object with x and y properties.
  2. animate — A boolean, set to true by default. <span>(Optional)
  3. animationOptions — An object with curve, time, delay and repeat properties. <span>(Optional)
scroll = new ScrollComponent

// Scroll content to x: 200, y: 100
scroll.scrollToPoint(
    {x: 200, y: 100},
    true,
    {curve: Bezier.ease}
)

// Scroll very slowly
scroll.scrollToPoint(
    {x: 200, y: 100},
    true,
    {curve: Bezier.ease, time: 10}
)

scroll.scrollToLayer(layer, originX, originY, animate, animationOptions)

Scroll to a specific layer. You can only scroll to layers that are children of the scroll.content layer.

Arguments

  1. layer — A layer object.
  2. originX — A number between 0 and 1. <span>(Optional)
  3. originY — A number between 0 and 1. <span>(Optional)
  4. animate — A boolean, set to true by default. <span>(Optional)
  5. animationOptions — An object with curve, time, delay and repeat properties. <span>(Optional)
// Create ScrollComponent
scroll = new ScrollComponent({
    width: 500,
    height: 500
})

// Define Background
layerA = new Layer({
    x: 500,
    y: 1000,
    image: "bg.png",
    parent: scroll.content
})

// Scroll to this layer
const scrollerA = new Layer({
    parent: scroll.content
})

scroll.scrollToLayer(scrollerA)

The originX and originY arguments define the point within the layer that will be scrolled to. The default values are 0,0 - which is the top-left corner.

scroll.scrollToLayer(
    layerA,
    0.5, 0,
    true,
    {time: 2}
)

scroll.scrollToClosestLayer(originX, originY)

Scroll to the closest content layer, using the given origin. The default values are (0,0) which is the top-left corner, (0.5, 0.5) the center, and (1,1) the bottom-right corner.

Arguments

  1. originX — A number between 0 and 1.
  2. originY — A number between 0 and 1.
scroll = new ScrollComponent

layerA = new Layer({
    parent: scroll.content,
    x: 75,
    y: 75
})

// Scroll to the center of layerA
scroll.scrollToClosestLayer(0.5, 0.5)

scroll.mouseWheelEnabled <boolean>

Enable or disable scrolling with mousewheel. Disabled by default. When set to true, layers can be scrolled both by dragging and with the mouse.

scroll = new ScrollComponent({
    width: 100,
    height: 100
})

// Allow scrolling with mouse
scroll.mouseWheelEnabled = true

layerA = new Layer({
    parent: scroll.content,
    image: "images/bg.png",
    width: 100,
    height: 200
})

scroll.wrap(layer)

Wraps a layer within a new ScrollComponent.

// Wrap the "content" layer group
scroll = ScrollComponent.wrap(layer.content)

Now, scroll is the variable name of the ScrollComponent. This also automatically wraps your layer within a ScrollContent layer, which you can select to adjust certain properties like momentum, overdrag or bounce.

// Wrap the "content" layer group
scroll = ScrollComponent.wrap(layer.content)

// Change scroll properties
scroll.scrollHorizontal = false
scroll.speedY = 0.5

// Change scroll.content properties
scroll.content.draggable.momentum = true
scroll.content.draggable.overdrag = false
scroll.content.draggable.bounce = false

scroll.updateContent()

Re-calculates and updates the size of the content and the dragging constraints. It also accounts for the contentInset.

If you're looking to change the size of your content layers, you can call it to update the size of your ScrollComponent accordingly.

scroll = new ScrollComponent

// Update the contents of the ScrollComponent
scroll.updateContent()

scroll.copy()

Copies a ScrollComponent, including its content and properties.

scroll = new ScrollComponent

layerA = new Layer({
    parent: scroll.content
})

// Copy the ScrollComponent
const scrollB = scroll.copy()

scroll.propagateEvents <boolean>

Set the propagateEvents property of the draggable content layer. Set to true by default. This is useful when working with nested ScrollComponents or PageComponents.

Let's say you'd like to have a draggable layer within the scroll.content layer. By default, moving the layer will also move the scroll.content. This is because both layers will listen to the dragging events.

To prevent any draggable children from passing events to its parent, set propagateEvents to false. This applies to all nested draggable layers.

scroll = new ScrollComponent({
    width: Screen.width,
    height: Screen.height
})

scroll.content.backgroundColor = "#28affa"

layerA = new Layer({
    parent: scroll.content,
    backgroundColor: "#fff"
})

layerA.draggable.enabled = true

// Setting propagateEvents to false allows you to drag layerA
// without also scrolling within the ScrollComponent
layerA.draggable.propagateEvents = false

SliderComponent

The SliderComponent creates a fully customisable slider for you. With it, you can adjust any numeric value or layer property. It consists of three layers: the slider itself, the fill and the knob.

// Create a SliderComponent
slider = new SliderComponent
slider.center()

By default, the slider has a dark fill color, a light-gray backgroundColor and rounded corners with borderRadius. The radius of the fill automatically matches with that of the slider, so you only need to set it once.

// Customize the appearance
slider.backgroundColor = "#ddd"
slider.borderRadius = 4

slider.knob <layer>

The knob of the slider. By default, it's made circular using borderRadius and has a little bit of a drop shadow applied to it.

// Create a SliderComponent
slider = new SliderComponent
slider.center()

// Customize the appearance
slider.knob.shadowY = 2
slider.knob.shadowBlur = 4
slider.knob.borderRadius = 6

The knob is a draggable layer, with momentum enabled.

// Disable momentum
slider.knob.draggable.momentum = false

slider.knobSize <number>

The size of the knob. This automatically sets the width and height of the knob. The default value is 30.

// Create a SliderComponent
slider = new SliderComponent
slider.center()

// Change the size of the knob
slider.knobSize = 40

slider.fill <layer>

The fill of the slider. The width and height are automatically updated, based on the size of the slider. By default, its backgroundColor is set to #333.

// Create a SliderComponent
slider = new SliderComponent
slider.center()

// Set the fill color to blue
slider.fill.backgroundColor = "#28affa"

slider.min <number>

The mininum value of the slider. Set to 0 by default.

// Create a SliderComponent
slider = new SliderComponent
slider.center()

// Set the minimum value
slider.min = -1

slider.max <number>

The maximum value of the slider. Set to 1 by default.

// Create a SliderComponent
slider = new SliderComponent
slider.center()

// Set the maximum value
slider.max = 2

slider.value <number>

The value of the slider. Set to 0.5 by default.

// Create a SliderComponent
slider = new SliderComponent
slider.center()

// Print the current value
print(slider.value)

You can listen to any value changes with the "change:value" event. This is useful for retreiving the value or mapping it to another layer property, like changing the opacity of a layer with the slider.

slider.on("change:value", function() {
    return print(this.value)
})

slider.pointForValue(value)

Takes a value and returns the corresponding point (x) within the slider. With a slider ranging from 0 to 1, the pointForValue(0.5) will be the center of the slider. With a width of 200, this will return 100.

// Create a SliderComponent
slider = new SliderComponent({
    width: 200
})

slider.center()

// Print the point for a value of 0.5
print(slider.pointForValue(0.5))
// Returns 100

slider.valueForPoint(value)

Takes a point and returns the corresponding value of the slider. With a width of 200, the valueForPoint(100) will be the center of the slider. With a slider ranging from 0 to 1, this will return 0.5.

// Create a SliderComponent
slider = new SliderComponent({
    width: 200
})

slider.center()

// Print the value for the point 100
print(slider.valueForPoint(100))
// Returns 0.5

slider.animateToValue(value, animationOptions)

Automatically animate to a specific value.

Arguments

  1. value — A number, ranging from the min to the max value.
  2. animationOptions — An object with curve, time, delay and repeat properties. <span>(Optional)
// Create a SliderComponent
slider = new SliderComponent
slider.center()

// Animate to 1
slider.animateToValue(1)

// Animate with a custom curve
slider.animateToValue(1, { curve: Spring })

SVGLayer

The SVGLayer allows you to define and reference SVG elements made in Design and Code. Set the fill, stroke, strokeWidth and more.

svg.svg <string | svg>

The svg property can be used to pass along entire SVG elements.

let shape = new SVGLayer({
    svg: "<svg><rect width='200' height='200' fill='#0AF' />"
})

This also allows you to access the svg element.

print(shape.svg)
// <SVGElement {}>

svg.fill <string>

Sets the background color.

shape = new SVGLayer({
    svg: "<svg><path d='M0 0 H 200 V 200 H 0 L 0 0' />",
    fill: "#0AF"
})

svg.stroke <string>

Sets the stroke color.

shape = new SVGLayer({
    svg: "<svg><rect width='200' height='200' />",
    stroke: "#0AF"
})

svg.strokeWidth <number>

The strokeWidth property can be used to define the stroke width.

shape = new SVGLayer({
    svg: "<svg><rect width='200' height='200' />",
    stroke: "#0AF",
    strokeWidth: 10
})

svg.gradient <object>

Sets the gradient of this layer. By default, gradients made in Code have a start color of #FFF, an end color of #000 and an angle set to 0. Gradients can be used alongside the backgroundColor property, too.

shape = new SVGLayer({
    svg: "<svg><path d='M0 0 H 200 V 200 H 0 L 0 0' />"
})

// Set a gradient
shape.gradient = {
    start: "#05F",
    end: "#0DF",
    angle: 0
}

svg.elements <object>

Contains all the SVGPath and SVGGroup elements in the SVG that have both the name and the id property set.

let svg = new SVGLayer({
    svg: `\
<svg>
    <g id='group' name='Container'>
        <path id='shape' name='Rectangle' d='M0 0 H 200 V 200 H 0 L 0 0' />
    </g>
</svg>\
`
})

print(svg.elements)
// {shape:<SVGPath id:3 name:Rectangle (0, 0) 200x200>,
//  group:<SVGGroup id:2 name:Container (0, 0) 200x200>}

svg.copy()

This will copy the SVGLayer just like layer.copy().

shape = new SVGLayer({
    svg: "<svg><path id='path' d='M0 0 H 200 V 200 H 0 L 0 0' />"
})

shape.copy()

If the SVG contains id’s these id’s will be made unique in the copied SVG.

print(shape.html)
// "<svg><path id="path1" d="M0 0 H 200 V 200 H 0 L 0 0"></path></svg>"

SVGPath

Use SVGPath to modify and animate SVG paths targeted from Design. Set fill, strokeStart, strokeEnd and more.

An SVGPath should not be created in code. The only way to get an SVGPath is through the elements property of SVGLayer

svg = new SVGLayer({
    svg: "<svg><path id='shape' name='Rectangle' d='M0 0 H 150 V 75 H 0 L 0 0' />",
    fill: "#0AF"
})

const path = svg.elements.shape

Layers can also be animated along a path, in combination with the point and rotation property, for example.

layer = new Layer({
    size: 100
})

layer.midPoint = path.start
layer.animate({
    point: path,
    rotation: path
})

// Shorthand for doing all of the above steps
layer.animate({
    path
})

path.length <number>

The length of the path. (Read-only)

print(path.length)
// Output: 450

path.width <number>

The width of the path. (Read-only)

print(path.width)
// Output: 150

path.height <number>

The height of the path. (Read-only)

print(path.height)
// Output: 75

path.start(relativeToLayer)

Returns the location and rotation of the start of the path. Pass a layer as final argument to get the coordinates for that layer. If no layer is passed, the coordinates will be for the current context.

print(path.start())
// {x:0, y:0, rotation:90}

// Shorthand to set the location of a layer to the start of the path
layer.point = path.start

path.end(relativeToLayer)

Returns the location and rotation of the end of the path. Pass a layer as final argument to get the coordinates in that layer. If no layer is passed, the coordinates will be for the current context.

print(path.end())
// {x:0, y:0, rotation:0}

// Shorthand to set the location of a layer to the end of the path
layer.point = path.end

path.pointAtFraction(fraction)

Get the location of a point along a fraction (value from 0 to 1) of the path, relative to the position of the path.

point = path.pointAtFraction(0.5)
print(point.x, point.y)
// Output: 150, 75

path.rotationAtFraction(fraction, delta)

Get the angle of the line at a fraction (value from 0 to 1) of the path. The optional second argument is the offset used to calculate the angle.

print(path.rotationAtFraction(0.5))
// Output: -90

path.fill <string>

Sets the fill color of the path.

path.fill = "#FFF"

path.stroke <string>

Sets the stroke color of the path.

path.stroke = "#0AF"

path.strokeWidth <number>

Sets the stroke width of the path.

path.strokeWidth = 10

path.strokeStart <number>

Set the start position of where to draw the stroke on the path.

// Only stroke the last half of the path
path.strokeStart = path.length / 2

path.strokeEnd <number>

Set the end position of where to stop drawing the stroke on the path.

// Only stroke the first half of the path
path.strokeEnd = path.length / 2

path.strokeLength <number>

Set the length of the stroke of the path.

path.strokeLength = 200

path.strokeFraction <number>

Set the stroke length to a fraction of the total length of the path. Shorthand for strokeLength.

// Set the stroke length to half of the total length
// Same as path.strokeLength = path.length / 2
path.strokeFraction = 0.5

path.strokeLinecap <string>

Set the line-cap of the stroke.

You can choose between butt, round and square.

// Multiple types of line caps
shape.strokeLinecap = "butt"
shape.strokeLinecap = "round"
shape.strokeLinecap = "square"

path.strokeLinejoin <string>

Set the line-join of the stroke.

You can choose between miter, round and bevel.

// Multiple types of line joins
shape.strokeLinejoin = "miter"
shape.strokeLinejoin = "round"
shape.strokeLinejoin = "bevel"

path.strokeMiterlimit <number>

Set the miter limit of the stroke. Only works when strokeLinejoin is set to miter.

star.strokeMiterlimit = 1

path.strokeOpacity <number>

Sets the stroke opacity. Opacity is defined with a number between 0 and 1, where 0 is invisible and 1 fully opaque.

path.opacity = 0.5

path.strokeDasharray <array>

Sets the stroke to have a certain pattern. See MDN’s examples for more details.

path.strokeDasharray = [5, 5, 10, 10]

path.strokeDashoffset <number>

The offset of the dash-pattern set by strokeDasharray. Useful for animating a dashed pattern.

path.stroke = "#000"
path.strokeDasharray = [10, 10]
path.animate({
    strokeDashoffset: path.length
})

SVGGroup

The SVGGroup allows you to modify SVG groups targeted form Design. Set fill, stroke, strokeWidth.

An SVGGroup should not be created in code. The only way to get an SVGGroup is through the elements property of SVGLayer

svg = new SVGLayer({
    svg: `\
<svg>
  <g id='group' name='Container'>
    <path id='shape' name='Rectangle' d='M0 0 H 150 V 75 H 0 L 0 0' />
  </g>
</svg>\
`
})

const {
    group
} = svg.elements

All properties set on an SVGGroup will be set on the containing paths. When using a property from a group, it will return the value of the underlying SVGPath properties, or null if the underlying SVGPaths have different values for that property.

group.fill <string>

Sets the fill color of all the paths contained in the group.

group.fill = "#FFF"

group.stroke <string>

Sets the stroke color of all the paths contained in the group.

group.stroke = "#0AF"

group.strokeWidth <number>

Sets the stroke width of all the paths contained in the group.

group.strokeWidth = 10

States

Layer states manage and organize different combinations of layer properties. Animations can use them as a target. Switch lets you jump to another state instantly and cycle allows you to sequentially move from state to state.

You can add any layer property to a state, like x and y. Non-animatable layer properties like html will be set at the end of the state animation.

States can have an animation options property. Which will be used whenever layers get animated to the defined state.

There are three pre-defined states that can't be overridden because they are already assigned to serve a purpose. You can get the state names for current and previous using their name property.

  1. default — The initially active state.
  2. current — The currently active state.
  3. previous — The previously active state.

Example: Create and delete a state

// Create a state
layerA.states.stateA =
    {x: 100}

// Delete a state
delete layerA.states.stateA

Example: A state with animation options

// Create a state with animationOptions
layerA.states.stateA = {
    x: 100,
    animationOptions: {
        curve: Spring({damping: 0.5}),
        time: 0.5
    }
}

Example: Animate to a state

// Create a state
layerA.states.stateA =
    {x: 100}

// Animate to the state
layerA.animate("stateA")

Example: Switch to a state

// Create a state
layerA.states.stateA =
    {x: 100}

// Switch to the state without an animation
layerA.stateSwitch("stateA")

Example: Cycle through states

// Set multiple states at once
layerA.states = {
    stateA: {
        x: 100
    },
    stateB: {
        x: 200
    }
}

// On a click, go back and forth between states.
layerA.onTap(() => layerA.stateCycle("stateA", "stateB"))

layer.states.current <object>

Returns an object of the currently active state.

Properties

  1. name — A read-only property that returns the name of the state object.
layerA = new Layer

layerA.states.stateA = {
    x: 500,
    opacity: 0.5
}

layerA.stateSwitch("stateA")

print(layerA.states.current)
// Output: <Object State>

print(layerA.states.current.name)
// Output: stateA

layer.states.previous <object>

Returns an object of the previously active state.

Properties

  1. name — A read-only property that returns the name of the state object.
layerA = new Layer

layerA.states.stateA = {
    x: 500,
    opacity: 0.5
}

layerA.stateSwitch("stateA")

print(layerA.states.previous)
// Output: <Object State>

TextLayer

A TextLayer allows you to work with type in Prototyper. Define text within a string, and use its unique properties to style it. Almost all property names match the CSS text styles. You can change the typeface, change the style, adjust the line height, add padding, shadows and much more.

text.text <string>

The text content. By default, the color is set to #888.

// Create a TextLayer
let title = new TextLayer({
    text: "Title"
})

text.template <object>

Set values for template tags in text. Template tags are wrapped in {}.

// Create text layer with template tag.
layerA = new TextLayer({
    text: "{speed}KM/h"
})

// Set speed template tag value.
layerA.template =
    {speed: 50}

// Shorthand to set value for first template tag.
layerA.template = 50
// Both result in "50KM/h".

text.templateFormatter <object>

Format template values to inject into template tags.

// Create text layer with template tags.
layerA = new TextLayer({
    text: "{speed}{unit}/h"
})

// Format template value to only have 2 decimals.
layerA.templateFormatter = {
    speed(value) {
        return Utils.round(value, 2)
    }
}

// Animate template value from 0 to 100.
layerA.animate({
    template: {
        speed: 100,
        unit: "KM"
    }
})

Here’s a shorthand way to format the first template tag only.

// Format template value to only have 2 decimals.
layerA.templateFormatter = value => Utils.round(value, 2)

text.textReplace(from, to)

Finds and replaces a piece of text.

// Replace 0:00 with 45:00
layerA = new TextLayer({
    text: "Total time: 0:00"
})

layerA.textReplace("0:00", "45:00")

text.fontSize <number>

The size of the text. By default, it's set to 40.

// Set fontSize to 64px
title = new TextLayer({
    fontSize: 64
})

text.fontFamily <string>

The current typeface of the text. By default, it's set to use the system typeface of the device you're currently previewing on.

  • Apple Device: SF UI.
  • Google Device: Roboto.
  • Microsoft Device: Segoe UI.
// Create a TextLayer
title = new TextLayer({
    fontFamily: "-apple-system"
})

text.fontWeight <number>

The weight of the text. By default, it's set to 400.

// Create a TextLayer
title = new TextLayer({
    fontWeight: 400
})

text.fontStyle <string>

The style of the text.

// Set font style to italic
title = new TextLayer({
    fontStyle: "italic"
})

You can choose between italic, bold and oblique.

// Set font style to bold
title = new TextLayer({
    fontStyle: "bold"
})

text.font <string>

A shorthand to define all font styles using a single line. These properties can be set (in order): "fontStyle fontWeight fontSize/lineHeight fontFamily".

// Set font styles in one line
title = new TextLayer({
    font: "300 64px/1 -apple-system, Helvetica Neue"
})

Note that the fontSize and fontFamily properties are required.

// Set font size and font family
title = new TextLayer({
    font: "64px -apple-system"
})

text.padding <object>

The padding of the text. By default, it's set to 0.

// Set padding
title = new TextLayer({
    padding: 40
})

You can also define padding of each side individually.

// Set padding of each side
title = new TextLayer({
    padding: {
        top: 40,
        left: 20,
        bottom: 40,
        right: 20
    }
})

Left and right padding can be defined by using the horizontal shorthand. Top and bottom padding can also be defined using the vertical shorthand.

// Set horizontal and vertical padding
title = new TextLayer({
    padding: {
        horizontal: 40,
        vertical: 80
    }
})

text.lineHeight <number>

The line height of the text. By default, it's set to 1.25. This means that if you've set the fontSize to 40, the line-height will effectively be 50px.

// Set line-height
title = new TextLayer({
    lineHeight: 1.5
})

text.letterSpacing <number>

The letter spacing of the text in pixels. Set to 0 by default.

// Set letter spacing
title = new TextLayer({
    letterSpacing: 2})

text.wordSpacing <number>

The letter spacing of the words in pixels. Set to 0 by default.

// Set word spacing
title = new TextLayer({
    wordSpacing: 10
})

text.textAlign <string>

The alignment of the text.

// Center-align the text
title = new TextLayer({
    textAlign: "center"
})

You can choose between left, right and center.

// Multiple ways to align text
title.textAlign = "left"
title.textAlign = "right"
title.textAlign = "center"

Alternatively, you can also use the Align class.

// Center-align the text
title = new TextLayer({
    textAlign: Align.center
})

text.textTransform <string>

The capitalization of the text.

// Uppercase all characters
title = new TextLayer({
    textTransform: "uppercase"
})

You can choose between uppercase, lowercase and capitalize.

// Multiple ways to capitalize text
title.textTransform = "uppercase"
title.textTransform = "lowercase"
title.textTransform = "capitalize"

text.textDecoration <string>

The decoration of the text.

// Add an underline to the text
title = new TextLayer({
    textDecoration: "underline"
})

You can choose between underline, overline and line-through.

// Add an overline to the text
title = new TextLayer({
    textDecoration: "overline"
})

text.textIndent <number>

The indentation of the first paragraph of text in pixels.

// Indent the text by 20 pixels
title = new TextLayer({
    textIndent: 20
})

text.textOverflow <string>

Add an ellipsis to overflowing text content.

// Single line clipping
let paragraph = new TextLayer({
    textOverflow: "ellipsis",
    text:
        `\
Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\
`
})

If you set the height, you’ll be able to add an ellipsis to multiple lines.

// Multi line clipping
paragraph = new TextLayer({
    textOverflow: "ellipsis",
    height: 100,
    text:
        `\
Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\
`
})

text.direction <string>

The direction of the text. The direction of the text. Set to left-to-right by default.

// Set the text direction
title = new TextLayer({
    direction: "right-to-left"
})

You can choose between right-to-left (rtl) and left-to-right (ltr).

// Set the text direction
title = new TextLayer({
    direction: "rtl"
})

text.truncate <boolean>

A shorthand of setting textOverflow to "ellipsis".

// Single line clipping
paragraph = new TextLayer({
    truncate: true,
    text:
        `\
Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\
`
})

If you set the height, you’ll be able to add an ellipsis to multiple lines.

// Multi line clipping
paragraph = new TextLayer({
    truncate: true,
    height: 100,
    text:
        `\
Lorem ipsum dolor sit amet, consectetur adipiscing elit,
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.\
`
})

text.shadowX <number>

Defines the shadow direction on the x-axis. A positive value will produce a shadow from the right edge of a layer, whereas a negative value will produce a shadow from the left edge.

// Set horizontal text shadow
title = new TextLayer({
    shadowX: 10
})

text.shadowY <number>

Defines the shadow direction on the y-axis. A positive value will produce a shadow from the bottom edge of a layer, whereas a negative value will produce a shadow from the top edge.

// Set vertical text shadow
title = new TextLayer({
    shadowY: 10
})

text.shadowBlur <number>

Adds a gaussian blur to the shadowX or shadowY property. shadowBlur is defined with a number. The default value is 0.

// Set text shadow
title = new TextLayer({
    shadowY: 1,
    shadowBlur: 4
})

text.shadowColor <string>

Sets the color of a layers shadow. The color is expressed as a string in the CSS color format.

// Set text shadow and color
title = new TextLayer({
    shadowY: 10,
    shadowColor: "rgba(0,0,0,0.2)"
})

Utilities

Utilities are custom functions in Prototyper, designed to make things easier to do. For example, they allow you to map values, set delays and intervals, detect devices and more. See below for a complete overview.

Utils.modulate(value, [a, a], [b, b], limit)

Translates a number between two ranges. When you enable limit, it will never return a value outside of the b range. The default value for limit is false.

Arguments

  1. value — A variable, representing the input.
  2. [a, a] — The first range of two numbers.
  3. [b, b] — The second range of two numbers.
  4. limit — A boolean, set to false by default. <span>(Optional)
print(Utils.modulate(0.5, [0, 1], [0, 100]))
// Output: 50

print(Utils.modulate(1, [0, 1], [0, 100]))
// Output: 100

You can think of modulate as a way to convert numbers between different scales. Like going from Celcius to Farenheit, or Kilometers to Miles.

// Convert to Celsius/Farenheit
Utils.modulate(celcius, [0, 100], [32, 212])

It's also useful for creating parallax effects on scroll. For example, you can move a layer from 0-10, when scrolling from 0-100.

scroll = new ScrollComponent({
    scrollHorizontal: false
})

layerA = new Layer({
    x: 100
})

// Modulate the scrolling distance
scroll.on(Events.Move, function() {
    const y = Utils.modulate(scroll.scrollY, [0,100], [0,10])
    return layerA.y = y
})

Utils.cycle(values)

Creates a function that returns the next value of an array every time it's called.

Arguments

  1. values — An array of values.
const cycler = Utils.cycle(["a", "b", "c"])

print(cycler()) // Output: "a"
print(cycler()) // Output: "b"
print(cycler()) // Output: "c"
print(cycler()) // Output: "a", returns to start

Utils.loadWebFont(fontFamily, fontWeight)

Load and set a typeface from Google Web Fonts.

Arguments

  1. fontFamily — A string with the name of the typeface.
  2. fontWeight — A number defining the font weight.
// Load Raleway from Google Web Fonts
let raleway = Utils.loadWebFont("Raleway")

// Set fontFamily
title = new TextLayer({
    fontFamily: raleway
})

You can optionally pass along a number as a second argument, which represents a specific fontWeight of the typeface to load.

// Load a bold weight of Raleway
raleway = Utils.loadWebFont("Raleway", 600)

// Set font
title = new TextLayer({
    font: raleway
})

Utils.labelLayer(layer, text)

Quickly add a label to a layer. By default, the text will be set in Menlo, and positioned in the center of the layer.

Arguments

  1. layer — A layer object.
  2. text — A string.
layerA = new Layer

// Add a label to layerA
Utils.labelLayer(layerA, "Hello")

Utils.round(value, decimals, increments, min, max)

Rounds a number.

Arguments

  1. value — A floating point number.
  2. decimals — The amount to appear after the decimal point. <span>(Optional)
  3. increments — The increment to round to. <span>(Optional)
  4. min — The minimum value to return. <span>(Optional)
  5. max — The maximum value to return. <span>(Optional)
print(Utils.round(100.12345, 0)) // Output 100
print(Utils.round(100.12345, 2)) // Output 100.12
print(Utils.round(100.12345, 4)) // Output 100.1234

Utils.randomChoice(values)

Select a random item in an array of values.

Arguments

  1. values — An array of values.
print(Utils.randomChoice(["a", "b", "c"])) // Output: "c"
print(Utils.randomChoice(["a", "b", "c"])) // Output: "b"
print(Utils.randomChoice(["a", "b", "c"])) // Output: "b"
print(Utils.randomChoice(["a", "b", "c"])) // Output: "b"
print(Utils.randomChoice(["a", "b", "c"])) // Output: "a"

Utils.randomColor(opacity)

Creates a random color with a given opacity. The opacity is optional.

Arguments

  1. opacity — A number between 0 and 1. <span>(Optional)
layerA = new Layer
layerA.backgroundColor = Utils.randomColor(0.5)

print(layerA.backgroundColor)
// Output: "rgba(124, 12, 33, 0.5)"

Utils.randomImage(layer or size)

Generate a random unsplash image url. If you optionally pass a layer or size, it will keep using the same image for that layer and optimize for the size.

Arguments

  1. layer — Layer
layer = new Layer
layer.image = Utils.randomImage() // Unoptimized
layer.image = Utils.randomImage(layer) // Preferred

Utils.randomNumber(a, b)

Generate a random number between a and b.

Arguments

  1. a — A number, the first value of the range.
  2. b — A number, the final value of the range.
print(Utils.randomNumber(0, 1)) // Output: 0.2
print(Utils.randomNumber(0, 100)) // Output: 22

Utils.delay(delay, handler)

Calls a function after a delay. Delay is defined in seconds.

Arguments

  1. delay — A number, representing seconds.
  2. handler — A function.
Utils.delay(0.5, () => print("hello"))

// Output: "hello", after 0.5 seconds

Utils.frameInset(frame, inset)

Arguments

  1. frame — An object with x, y, width, height.
  2. inset — A number or object with top, right, bottom, left

Inset a frame by a certain amount of pixels.

print(Utils.frameInset({x:0, y:0, width:100, height:100}, 10))
// Output {x:10, y:10, width:80, height:80}

print(Utils.frameInset({x:0, y:0, width:100, height:100}, {top: 20}))
// Output {x:0, y:20, width:100, height:80}

Utils.interval(interval , handler)

Calls a function every x seconds.

Utils.interval(2, () => print("hello"))

// Output: "hello"
// Output: "hello"
// Output: "hello"
// Output: "hello" etc...

Utils.debounce(interval, handler)

Creates a function that will delay the calling of handler until after x seconds have elapsed since the last time it was invoked. Alias to _.debounce.

Arguments

  1. interval — A number, representing seconds.
  2. handler — A function.
let handler = Utils.debounce(0.1, () => print("hello"))

for (i = 1 i <= 100 i++) {
    handler()
}

// Output: "hello" only once

Utils.insertCSS(css)

Add css to a layer by wrapping it in a string and passing it as a parameter.

layerA = new Layer
layerA.classList.add("testClass")

const css = `\
.testClass {
    border: 1px solid #000
}\
`

print(Utils.insertCSS(css))

Utils.throttle(interval, handler)

Creates a function that will call the wrapped function at most once per x seconds. Alias to _.throttle.

Arguments

  1. interval — A number, representing seconds.
  2. handler — A function.
handler = Utils.throttle(0.1, () => print("hello"))

for (i = 1 i <= 100 i++) {
    handler()
}

// Output: "hello" only once

Utils.isWebKit()

Returns whether this is a WebKit browser.

print(Utils.isWebKit()) // Output true

Utils.isChrome()

Returns whether this is a Chrome browser.

print(Utils.isChrome()) // Output true

Utils.isSafari()

Returns whether this is a Safari browser.

print(Utils.isSafari()) // Output true

Utils.isTouch()

Returns whether this is a touch enabled browser.

print(Utils.isTouch()) // Output true

Utils.isDesktop()

Returns whether this is a desktop browser.

print(Utils.isDesktop()) // Output true

Utils.isPhone()

Returns whether this is a phone device.

print(Utils.isPhone()) // Output true

Utils.isTablet()

Returns whether this is a tablet device.

print(Utils.isTablet()) // Output true

Utils.isMobile()

Returns whether this is a mobile device (phones and tables).

print(Utils.isMobile()) // Output true

VideoLayer

A videoLayer loads a video. VideoLayers have a layer.player object to control the video. The browser supports many different types of video, including the Animation codec that supports alpha channels.

videoLayer.video <string>

Sets the video URL for the video layer.

// Set on creation
layerA = new VideoLayer({
    video: "hello.mp4"
})

// Change afterwards
layerA.video = "bye.mp4"

videoLayer.player <object>

Player object for the video layer. Allows you to control the video and listen for playback events. See this overview of all video methods and properties.

// Set on creation
layerA = new VideoLayer({
    video: "hello.mp4"
})

// Enable auto play
layerA.player.autoplay = true

// Play the video
layerA.player.play()

// Jump to 5 seconds
layerA.player.fastSeek(5)

// Listen to paused playback
Events.wrap(layerA.player).on("pause", () => print("Video paused"))