Get Started

Get started with Framer by exploring the basics.

1. Layers

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

More on Layers

2. Animation

Animate layer properties like scale and color with various easing or spring curves, a set time, repeat and delay options and more.

More on Animation

3. States

States are sets of layer properties with values. You can add, remove or switch between states, with or without an animation.

More on States

4. Events

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

More 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 
layerA = new Layer
    x: Align.center
    y: Align.center
 
# Create a state in the bottom right corner 
layerA.states.add
    a:
        x: Align.right
        y: Align.bottom
    b:
        x: Align.left
        y: Align.top
 
layerA.onTap -> layerA.states.next()

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 flexible more 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
 
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 that target a layer and properties. An animation will tween between a start and end value, with a curve. The start value is determined when the animation starts, and the end value is defined by properties. If the start values equal to end values, they won't animate.

Properties
  1. layer — A layer object, the targeted layer.
  2. properties — An object with target values for the animated properties.
  3. curve — A string, set to ease by default. (Optional)
  4. curveOptions — An object with the options of the set curve. (Optional)
  5. time — A number, the duration in seconds. (Optional)
  6. delay — A number, the delay of the animation. (Optional)
  7. repeat — A number, the amount of times it repeats. (Optional)
  8. colorModel — A string, the model to animate colors in. (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 a ease curve.

layerA = new Layer
 
# Animate the layer to the right 
animationA = new Animation
    layer: layerA
    properties:
        x: 100
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 
animationB = new Animation
    layer: layerA
    properties:
        x: 100
        opacity: 0.5
    time: 5
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.

# Repeat an animation 5 times, delay for 2 seconds 
animationD = new Animation
    layer: layerA
    properties:
        x: 100
    repeat: 5
    delay: 2
Example: ease-in-out

Included easing curves are ease-in, ease-out and ease-in-out.

# Animate with an ease-in-out curve 
animationE = new Animation
    layer: layerA
    properties:
        x: 100
    curve: "ease-in-out"

Animation Curves

  1. linear — Constant speed.
  2. bezier-curve — Bezier curve
  3. spring-rk4 — Runge-Kutta spring.
  4. spring-dho — Damping Harmonic Oscillator spring.
  5. spring — An alias for "spring-rk4"
Example: bezier curve
layerA = new Layer
 
# Animate with a bezier curve 
animationA = new Animation
    layer: layerA
    properties:
        x: 100
        opacity: 0.5
    curve: "bezier-curve(0.25, 0.1, 0.25, 1)"
Example: spring-rk4

The included spring curve values are:

  1. tension — Strength of the spring.
  2. friction — Weight of the spring.
  3. velocity — Velocity at the start.
  4. tolerance — Minimal threshold before the animation ends. (Optional)
layerA = new Layer
 
# Animate with the spring-rk4 curve 
animationA = new Animation
    layer: layerA
    properties:
        x: 100
    curve: "spring(250, 25, 0)"
Example: spring-dho

The included spring curve values are:

  1. stiffness — Strength of the spring.
  2. damping — How quickly the spring should reduce motion/force.
  3. mass — Weight of the object.
  4. tolerance — Minimal threshold before the animation ends. (Optional)
layerA = new Layer
 
# Animate with the spring-dho curve 
animationA = new Animation
    layer: layerA
    properties:
        x: 100
    curve: "spring-dho(800, 200, 10, 0.01)"
 
animationA.start()

Animatable Properties

Only numeric layer properties can be animated:

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 second one will fail.

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:

animation.start()

Start the animation.

layerA = new Layer
 
animationA = new Animation
    layer: layerA
    properties:
        x: 100
 
# Nothing will move until we start 
animationA.start()

animation.stop()

Stop the animation.

layerA = new Layer
 
animationA = new Animation
    layer: layerA
    properties:
        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
    layer: layerA
    properties:
        x: 100
 
animationB = animationA.reverse()
 
# Alternate between the two animations 
animationA.on(Events.AnimationEndanimationB.start)
animationB.on(Events.AnimationEndanimationA.start)
 
animationA.start()

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 local path, or a link. The image will always fit to cover the canvas, and will never be stretched.

# Local images 
Canvas.image = "images/background.png"
 
# Hosted images 
Canvas.image = "http://framerjs.com/background.png"

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.

point =
    x: 20
    y: 40
pointInScreen = Canvas.convertPointToScreen(point)

Canvas.convertPointToLayer(point, layer)

Converts a point from the Canvas to a layer.

point =
    x: 20
    y: 40
 
layer = new Layer
 
pointInLayer = Canvas.convertPointToLayer(pointlayer)

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.

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: 
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: 255g: 255b: 255)
 
# Define a color with an HSL object 
layerB = new Layer
    backgroundColor: new Color(h: 360s: 1l: 1a: 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
    properties:
        backgroundColor: "red"
    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 
yellow = new Color("yellow")
 
# Convert it to gray 
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. (Optional)
layer = new Layer
layer.backgroundColor = Color.gray(0.5)

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. (Optional)
  4. limit — A boolean, set to false by default. (Optional)
  5. model — A string, the color model used to mix. (Optional)
# Mix red with yellow 
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(offset) ->
 
    # Map the dragging distance to a number between 0 and 1 
    fraction = Utils.modulate(offset.x[0Screen.width][0,1]true)
 
    # Mix the colors, enable the limit, transition in HUSL 
    layerA.backgroundColor =
        Color.mix("red""yellow"fractiontrue"husl")

Color.random()

Returns a Color instance with a random color value set.

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

Compatibility

Framer.js
Browsers Webkit (Chrome, Safari)
Platforms Mac OS X, Windows, Linux
Mobile Platforms iOS, Android, Windows Phone
Generator.app
Imports from Photoshop CC, Sketch 3.4.4
Platforms Mac OS X, Windows (coming soon)
Framer Studio.app
Imports from Photoshop CC, Sketch 3.4.4
Platforms Mac OS X 10.10+

Defaults

The Framer.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 
Framer.Defaults.Layer.backgroundColor = "red"
 
# Override the default corner radius for layers 
Framer.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 that layer with layer.states.animationOptions.

# Override the default animation options for all Animations 
Framer.Defaults.Animation =
    curve: "spring(100,10,0)"
 
# Override the default corner radius for layers 
Framer.Defaults.Layer.borderRadius = 10
 
layerA = new Layer
 
layerA.animate
    properties:
        x: 100
 
# The animation will now use the "spring(100,10,0)" curve 

Device

The DeviceComponent emulates a device like an iPhone, iPad or Android. It allows you to scale the device, scale the content and adjust the orientation. After the device is set up, everything will render within its screen. Device previews match mirrored previews, meaning that if you're previewing on iPhone and then view it on an iPhone it will appear in fullscreen.

Scaling and orientation properties are also prefixed with Framer.Device:

Framer.Device.contentScale = 0.5
Framer.Device.orientation = 90

Underneath, the Device is just a collection of layers. That makes it easy to customize or add behaviour. You can find the entire source on Github. Here are some common examples:

# Set a blurred background image 
Framer.Device.background.image = "photo.jpg"
Framer.Device.background.blur = 10
 
# Get the screen dimensions for the current device 
print Framer.Device.screen.width  # Output: 640 
print Framer.Device.screen.height # Output: 480 

Please note that the scale-to-fit view can render your content off-pixel to retain your screen ratio. Your content will always snap-to-pixel when viewed at 50%, 100% etc. If your browser supports it, device images are compressed with JPEG2000 to reduce image size.

To change the device position simply change the x and y values for the screen and device like you would for a normal Layer.

# Set the Device position 
Framer.Device.screen.x = 50
Framer.Device.x = 50
 
# Change from the current Device position 
Framer.Device.screen.x += 50
Framer.Device.x += 50

Device.customize(deviceType, screenWidth, screenHeight, deviceImage, deviceImageWidth, deviceImageHeight)

Customize the device with a custom device image and sizes. If the device is a phone or tablet you can specify its type which will make sure the device image isn't visible when previewing on the device itself.

# Define and set custom device 
Framer.Device.customize
    deviceType: Framer.Device.Type.Tablet
    screenWidth: 720
    screenHeight: 1024
    deviceImage: "http://f.cl.ly/items/001L0v3c1f120t0p2z24/custom.png"
    deviceImageWidth: 800
    deviceImageHeight: 1214

Device.deviceType <string>

The type of device to render. Below is an overview of all available options.

Fullscreen

Renders in fullscreen.

Framer.Device.deviceType = "fullscreen"
Apple Watch 38mm

All available Apple Watch 38mm colors.

Framer.Device.deviceType = "apple-watch-38mm-black-steel-black-closed"
Framer.Device.deviceType = "apple-watch-38mm-gold-midnight-blue-closed"
Framer.Device.deviceType = "apple-watch-38mm-rose-gold-lavender-closed"
 
Framer.Device.deviceType = "apple-watch-38mm-sport-aluminum-blue-closed"
Framer.Device.deviceType = "apple-watch-38mm-sport-aluminum-fog-closed"
Framer.Device.deviceType = "apple-watch-38mm-sport-aluminum-green-closed"
Framer.Device.deviceType = "apple-watch-38mm-sport-aluminum-red-closed"
Framer.Device.deviceType = "apple-watch-38mm-sport-aluminum-walnut-closed"
Framer.Device.deviceType = "apple-watch-38mm-sport-aluminum-white-closed"
Framer.Device.deviceType = "apple-watch-38mm-sport-space-gray-black-closed"
Apple Watch 42mm

All available Apple Watch 42mm colors.

Framer.Device.deviceType = "apple-watch-42mm-black-steel-black-closed"
Framer.Device.deviceType = "apple-watch-42mm-gold-midnight-blue-closed"
Framer.Device.deviceType = "apple-watch-42mm-rose-gold-lavender-closed"
 
Framer.Device.deviceType = "apple-watch-42mm-sport-aluminum-blue-closed"
Framer.Device.deviceType = "apple-watch-42mm-sport-aluminum-fog-closed"
Framer.Device.deviceType = "apple-watch-42mm-sport-aluminum-green-closed"
Framer.Device.deviceType = "apple-watch-42mm-sport-aluminum-red-closed"
Framer.Device.deviceType = "apple-watch-42mm-sport-aluminum-walnut-closed"
Framer.Device.deviceType = "apple-watch-42mm-sport-aluminum-white-closed"
Framer.Device.deviceType = "apple-watch-42mm-sport-space-gray-black-closed"
iPhone 6s

All available iPhone 6s colors.

Framer.Device.deviceType = "apple-iphone-6s-gold"
Framer.Device.deviceType = "apple-iphone-6s-rose-gold"
Framer.Device.deviceType = "apple-iphone-6s-silver"
Framer.Device.deviceType = "apple-iphone-6s-space-gray"
iPhone 6+

All available iPhone 6+ colors.

Framer.Device.deviceType = "apple-iphone-6s-plus-gold"
Framer.Device.deviceType = "apple-iphone-6s-plus-rose-gold"
Framer.Device.deviceType = "apple-iphone-6s-plus-silver"
Framer.Device.deviceType = "apple-iphone-6s-plus-space-gray"
iPhone 5s

All available iPhone 5s colors.

Framer.Device.deviceType = "apple-iphone-5s-gold"
Framer.Device.deviceType = "apple-iphone-5s-silver"
Framer.Device.deviceType = "apple-iphone-5s-space-gray"
iPhone 5c

All available iPhone 5c colors.

Framer.Device.deviceType = "apple-iphone-5c-blue"
Framer.Device.deviceType = "apple-iphone-5c-green"
Framer.Device.deviceType = "apple-iphone-5c-red"
Framer.Device.deviceType = "apple-iphone-5c-white"
Framer.Device.deviceType = "apple-iphone-5c-yellow"
Nexus

All Google Nexus devices.

Framer.Device.deviceType = "google-nexus-4"
Framer.Device.deviceType = "google-nexus-5x"
Framer.Device.deviceType = "google-nexus-6p"
Framer.Device.deviceType = "google-nexus-9"
HTC One A9

All Google Nexus devices.

Framer.Device.deviceType = "htc-one-a9-black"
Framer.Device.deviceType = "htc-one-a9-white"
HTC One M8

All HTC One M8 devices.

Framer.Device.deviceType = "htc-one-m8-black"
Framer.Device.deviceType = "htc-one-m8-gold"
Framer.Device.deviceType = "htc-one-m8-silver"
Microsoft Lumia 950

All Microsoft Lumia 950 devices.

Framer.Device.deviceType = "microsoft-lumia-950-black"
Framer.Device.deviceType = "microsoft-lumia-950-white"
Samsung Note 5

All Samsung Note 5 devices.

Framer.Device.deviceType = "samsung-galaxy-note-5-black"
Framer.Device.deviceType = "samsung-galaxy-note-5-gold"
Framer.Device.deviceType = "samsung-galaxy-note-5-pink"
Framer.Device.deviceType = "samsung-galaxy-note-5-silver-titanium"
Framer.Device.deviceType = "samsung-galaxy-note-5-white"
iPad Mini

All available iPad Mini colors.

Framer.Device.deviceType = "apple-ipad-mini-4-silver"
Framer.Device.deviceType = "apple-ipad-mini-4-gold"
Framer.Device.deviceType = "apple-ipad-mini-4-space-gray"
iPad Air

All available iPad Air colors.

Framer.Device.deviceType = "apple-ipad-air-2-silver"
Framer.Device.deviceType = "apple-ipad-air-2-gold"
Framer.Device.deviceType = "apple-ipad-air-2-space-gray"
iPad Pro

All available iPad Pro colors.

Framer.Device.deviceType = "apple-ipad-pro-silver"
Framer.Device.deviceType = "apple-ipad-pro-gold"
Framer.Device.deviceType = "apple-ipad-pro-space-gray"
Apple iMac

The iMac desktop device.

Framer.Device.deviceType = "apple-imac"
Apple MacBook

All available Apple MacBook laptop devices.

Framer.Device.deviceType = "apple-macbook"
Framer.Device.deviceType = "apple-macbook-air"
Framer.Device.deviceType = "apple-macbook-pro"
Dell XPS

The Dell XPS laptop device.

Framer.Device.deviceType = "dell-xps"
Sony TV

The Sony W850C TV device.

Framer.Device.deviceType = "sony-w85Oc"

Device.fullScreen <boolean>

Set the device to render fullscreen, independent of the deviceType. Set to true or false.

# Render the device in fullscreen 
Framer.Device.fullScreen = true

Device.deviceScale <number / string>

The scale of the device. Supported scale values range from 0.5 to 1.

Framer.Device.deviceScale = 0.5

Device.setDeviceScale(scale, animate)

The scale of the device and an optional animation (true or false). Supported scale values range from 0.5 to 1.

# Set device scale and animate 
Framer.Device.setDeviceScale(0.5true)

Device.contentScale <number>

The scale of the content, including the custom device. Supported scale values range from 0.5 to 1.

# Set content scale 
Framer.Device.contentScale = 0.5

Device.setContentScale(scale, animate)

Sets the scale of the content, and an optional animation (true or false). Supported scale values range from 0.5 to 1.

# Set content scale and animate 
Framer.Device.setContentScale(0.5true)

Device.orientation <number>

The orientation of the device. Supported orientation values are 0 and 90 (portrait and landscape orientations).

Framer.Device.orientation = 90

Device.setOrientation(orientation, animate)

Sets the orientation of the device, and an optional animation (true or false). Supported orientation values are 0 and 90 (portrait and landscape orientations).

# Set orientation and animate 
Framer.Device.setOrientation(90true)

Device.orientationName <string>

Set the device orientation by name. Valid options are "portrait" and "landscape". The portrait and landscape values are the same setting the device orientation to 0 and 90 respectively.

# Set orientation to either landscape or portrait 
Framer.Device.orientationName = "landscape"
Framer.Device.orientationName = "portrait"

Device.rotateLeft()

Rotates the device to the left (clockwise).

Framer.Device.rotateLeft()

Device.rotateRight()

Rotates the device to the right (clockwise).

Framer.Device.rotateRight()

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 
round = (number, nearest) ->
    Math.round(number / nearest) * nearest
 
# Drag in increments of 20px 
layerA.draggable.updatePosition = (point) ->
    point.x = round(point.x20)
    point.y = round(point.y20)
    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.

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 Framer, 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"
 
clickHandler = (event, layer) ->
    print "Clicked"layer.name
 
layerA.on(Events.ClickclickHandler)
layerA.off(Events.ClickclickHandler)

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"
  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.scalelayerA.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 eventlayer
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 eventlayer
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 eventlayer
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 — Start animation.
  2. Events.AnimationStop — Stop animation.
  3. Events.AnimationEnd — End of animation.
layerA = new Layer
 
layerA.animate
    properties:
        x: 100
 
# Returns the animation and the layer 
layerA.on Events.AnimationEnd(animation, layer) ->
    print animationlayer
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.StateWillSwitch — About to switch to a new state.
  2. Events.StateDidSwitch — Just switched to new state.
layerA = new Layer
 
layerA.states.add
    rotate:
        rotation: 90
 
layerA.states.switch("rotate")
 
# Returns the old state, new state and layer.states 
layerA.on Events.StateDidSwitch(from, to, states) ->
    print fromtostates
State Event Shortcuts
# For Events.StateWillSwitch 
layerA.onStateWillSwitch ->
    print "Will switch state"
 
# For Events.StateDidSwitch 
layerA.onStateDidSwitch ->
    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), layer.draggable and the layer 
layerA.on Events.Move(offset, draggable, layer) ->
    print offsetdraggablelayer
layerA = new Layer
layerA.draggable.enabled = true
 
# Returns the event, layer.draggable and the layer 
layerA.on Events.DragStart(event, draggable, layer) ->
    print eventdraggablelayer
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, layer.draggable and the layer 
scroll.on Events.ScrollStart(event, draggable, layer) ->
    print eventdraggablelayer
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"
  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"

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
    properties:
        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
    properties:
        rotation: 180
 
# When the rotation value from layerA changes 
layerA.on "change:rotation"->
 
    # Use the values to move layerB from 100 to 300 
    = Utils.modulate(layerA.rotation[0180][100300]true)
    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(event, layer) ->
    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 Framer 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 Framer for Mac 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:

Framer.Extras.Hints.disable()

Or enable them like this:

Framer.Extras.Hints.enable()

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

Framer.Extras.Hints.enable()
Framer.Extras.Hints.showHints()
Some notes:
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 = (hintFrame) ->
 
    # Create a hint layer, this will automatically be   
    # placed in the hints context on top of everything. 
    hint = new Layer
        frame: hintFrame
        backgroundColor: "red"
        opacity: 0.5
 
    # Add a cool animation 
    hint.animate
        properties:
            scale: 1.3
            opacity: 0
        time: 0.5
 
    # Remove the layer when done 
    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 Framer, such as when you share a project online or via mirroring.

You can force enable the preloader like this:

Framer.Extras.Preloader.enable()

Or disable it like this:

Framer.Extras.Preloader.disable()
Customization

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

Framer.Extras.Preloader.enable()
Framer.Extras.Preloader.setLogo("https://twitter.com/framerjs/profile_image?size=bigger")
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 Framer.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.

Framer.Extras.Preloader.enable()
Framer.Extras.Preloader.addImage("https://twitter.com/framerjs/profile_image?size=bigger")
 
layerA = new Layer point: Align.center
 
layerA.onTap ->
    layerB = new Layer
        image: "https://twitter.com/framerjs/profile_image?size=bigger"
Some notes:

Info

The info variable is used to store general information about your prototype, such as project title or author. This information is used as part of the sharing flow, and the information will appear when you share a project online or via Facebook and Twitter.

Adding this information to your project is a great way to leave instructions for your user, add identity to your project and link to your Twitter profile or website.

Here's how you can customize your Sharing Info:

Framer.Info =
    author: "Koen Bok"
    twitter: "@koenbok"
    title: "My Pretty Project"
    description: "Just some sample."

If you would like to see a sharing preview in Framer:

Framer.Extras.ShareInfo.enable()

The supported attributes are (all optional):

  1. author — The author name (eg: you).
  2. twitter — The author Twitter handle.
  3. title — The project title (will default to the file name).
  4. description — A short project description, supports inline links.
  5. date — Publish date (will default to upload date).
  6. image.facebook — Open graph image url for Facebook card.
  7. image.twitter — Twitter card image url.

Layer

Layers are the basic containers of Framer, 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. Layers aren't named by default. Imported layers will inherit the name you've defined within Sketch or Photoshop.

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.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.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.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.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.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.point <object>

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

layerA = new Layer
 
print layerA.point
# Output: { x: 100, y: 100 } 
 
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.xlayerB.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.xlayerB.y
# Output: 200, 0 
 
layerB.centerX(20)
print layerB.xlayerB.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.xlayerB.y
# Output: 0, 200 
 
layerB.centerY(20)
print layerB.xlayerB.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.xlayerA.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
 
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.image <string>

Sets the background-image url or path for this layer. You can set it as a local path or 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.

# Local images 
layerA = new Layer
    image: "images/logo.png"
 
# Hosted images 
layerA.image = "http://framerjs.com/logo.png"

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
    image: "images/logo.png"
 
# Listen to the loading event 
layerA.on Events.ImageLoaded->
    print "The image loaded"
 
layerA.on Events.ImageLoadError->
    print "The image couldn't be loaded"

layer.visible <boolean>

Sets whether the layer should be visible or not.

layerA = new Layer
layerA.visible = false

layer.opacity <string>

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. Framer 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(context)

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.

Arguments
  1. context — A boolean that specifies if the context should be included, set to false by default. (Optional)
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.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 Framer 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</span>"
 
# 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>"
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.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.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.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(options)

Start animating this layer. The animation options describe the properties it needs to animate to and how to animate. Running this method will create a new Animation Object with the animationOptions, which you can use to stop or reverse the animation. Here, the duration of the animation is 5 seconds.

layerA = new Layer
 
# Animate scale and rotation 
layerA.animate
    properties:
        scale: 0.5
        rotation: 90
    time: 5

In the example below, there is a 2 second delay between every repeat.

# Repeat and delay the animation 
layerA.animate
    properties:
        x: 100
    repeat: 5
    delay: 2

layer.animateStop()

Stop all running animations on this layer immediately.

layerA = new Layer
 
# Stop an animation immediately 
layerA.animate
    properties:
        x: 100
 
layerA.animateStop()

layer.animations()

Returns all the current running animations for this layer.

layerA = new Layer
 
layerA.animate
    properties:
        x: 100
 
layerA.animate
    properties:
        y: 100
 
print layerA.animations()
# Output: [<Object Animation>, <Object Animation>] 

layer.isAnimating <boolean>

See if a layer is animating. This property is readonly.

layerA = new Layer
 
layerA.animate
    properties:
        x: 100
 
print layerA.isAnimating
# Result: True 

layer.convertPointToCanvas(point)

Converts a point from a layer to the Canvas.

point =
    x: 20
    y: 40
 
layer = new Layer
 
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.convertPointToCanvas(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
 
pointInLayerB = layerA.convertPointToLayer(pointlayerB)

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.ClickclickHandler)
layerA.off(Events.ClickclickHandler)

MIDIComponent

A MIDI controller sends signals to your computer, similar to a keyboard or a mouse. Most commonly MIDI controllers have buttons, sliders and knobs that you can hook up to software. There is a wide variety of hardware MIDI controllers available on the market, many of them connect over USB. There are also MIDI controller apps, that connect over Bluetooth.

The MIDIComponent gives you the ability to work with MIDI controllers directly in Framer and in browsers that support the Web MIDI API.

Get Started
midi = new MIDIComponent
 
midi.onValueChange (value, info) ->
    print valueinfo

Now, when you change a button on the MIDI device you will see the values being printed, for example if you move a control from the start to end position:

» 0, {source:"111955983", channel:1, control:2}
» 1, {source:"111955983", channel:1, control:2}
» 2, {source:"111955983", channel:1, control:2}
» 125, {source:"111955983", channel:1, control:2}
» 126, {source:"111955983", channel:1, control:2}
» 127, {source:"111955983", channel:1, control:2}

By default, MIDIComponent will listen to MIDI signals from all controls and note buttons on all devices coming over any channel. You can use the properties you see printed above to filter the signal events. That way you can hook up control number 2 to a slider, for example:

midi = new MIDIComponent
    control: 2
 
slider = new SliderComponent
    point: Align.center
    max: 127
 
midi.onValueChange (value) ->
    slider.value = value

The output values from MIDI are always between 0 and 127, but if you want to use the value to set a property that has a different range, you can use min and max to modulate the value for you. For example, the RGB components in a color range from 0 to 255, so you can use:

midi = new MIDIComponent
    min: 0
    max: 255
 
midi.onValueChange (value) ->
    Screen.backgroundColor = new Color
        r: valueg: 0b: 0

MIDIComponent.min <number>

The value that will be send as the minimum value to the onValueChange handler. The default value is 0.

MIDIComponent.max <number>

The value that will be send as the maximum value to the onValueChange handler. The default value is 127.

MIDIComponent.control <number>

The number of the control, between 0 and 127. Filters out events not coming from this control.

To find the correct control number, you can use the extra information send to the handler of onValueChange.

MIDIComponent.channel <number>

A number between 1 and 16 representing the channel. Filters out all events not coming from this channel.

To find the current channel of a control, you can use the extra information send to the handler of onValueChange.

MIDIComponent.source <string>

The source to listen to. Filters out all events not coming from this source.

Each MIDI device has a unique source ID that is managed by the system. In general, the source ID should be stable, so that if you reconnect a device to the same computer, you should get the same ID. Note that the source ID will not be the same between different browsers and Framer.

To find the source ID, you can use the extra information send to the handler of onValueChange.

MIDIComponent.onValueChange(handler)

Handle MIDI signal events.

The handler gets two parameters, first the value of the signal and second an object with more information about the origin.

midi = new MIDIComponent
 
# Print the identifier of the control sending the change 
midi.onValueChange (value, info) ->
  print info.control

See the Get Started section for more examples.

Properties

The info parameter is an object with the following properties:

  1. control — the identifier of the control (knob, slider, etc.) sending the signal.
  2. channel — the channel the signal is send over.
  3. source — the identifier of the device sending the signal.
  4. type (optional) — "note" if the signal is coming from a note, the value represents the velocity, 0 means the note is off.

Modules

Modules allow you to separate and organize parts of your prototype across different files. They're JavaScript or CoffeeScript files, which you can include (require) within your prototype. They help you organize your code, and choose what parts to focus on.

You can find them in the /modules folder of your prototype. Modules are based on JavaScript and Node.js standards. Everything that you've prefixed with exports in your module will be available in your prototype. The require keyword imports your module.

If you want to add modules to an older project, we advice to create a new project in the latest Framer Studio, and copy over your files.

Get Started
# To include myModule.coffee in our prototype 
module = require "myModule"

Make sure to save your file and refresh your prototype to see changes. Modules can contain anything. For example, you can create Layers within your modules, or define specific interactions within functions.

# Store variables 
exports.myVar = "myVariable"
 
# Create functions 
exports.myFunction = ->
    print "I'm running!"
 
# Create Arrays 
exports.myArray = [123]
 
# Create Layers 
exports.mylayerA = new Layer
    backgroundColor: "#fff"

In the example above, a new layer is automatically created and included within our prototype. To also run the function, you can write:

# To include myModule.coffee 
module = require "myModule"
 
# Run the function, printing "I'm running!" 
module.myFunction()

Example: Interactions

Let's create a simple draggable interaction within a module. In our myModule.coffee file, we include the following function. It takes a layer, makes it draggable, and snaps it back to its original position on DragEnd.

# A draggable function without our module 
exports.makeDraggable = (layer) ->
    layer.draggable.enabled = true
 
    # Store current x and y position 
    startX = layer.x
    startY = layer.y
 
    # Animate back on DragEnd 
    layer.on Events.DragEnd->
        this.animate
            properties:
                x: startX
                y: startY
            curve: "spring(300,20,0)"

Now, within our prototype, we can call the makeDraggable function from our module to include the dragging interaction.

# Include module 
module = require "myModule"
 
# Set background 
bg = new BackgroundLayer
    backgroundColor: "#28AFFA"
 
# Create a new layer 
layerA = new Layer
    backgroundColor: "#fff"
    borderRadius: 4
 
layerA.center()
 
# Add the dragging interaction to layerA 
module.makeDraggable(layerA)

Example: npm

Framer modules work with npm, a package manager where thousands of JavaScript packages are published. Let’s import the Moment.js library. Make sure you already have npm installed.

# In your terminal 
cd ~/my-project.framer
npm install moment

Create a new module in /modules, and name it npm.coffee. Beware that if you name the file the same as the npm module (like moment.coffee), you could run into a recursive import problem.

# File: modules/npm.coffee 
exports.moment = require "moment"

After a refresh, you can import moment into your project.

# Import the moment module from your npm index 
moment = require("npm").moment
 
# Or use this nice shortcut, which is the exact same 
{moment} = require "npm"

And now you can use it in your project:

dayStarted = new Layer
    html: moment().startOf("day").fromNow()

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. 
page = new PageComponent
    width: Screen.width
    height: Screen.height
    scrollVertical: false
 
# Define the first page 
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 
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 number in [0...5]
    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: "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
    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.snapToPage( pageTwo)

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 = curve: "ease"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(pageTwofalse)
 
# 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 
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(pageTwofalse)

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
 
pageA = new Layer
    size: page.size
 
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 Framer Studio, 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
 
# Scale 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.xprint layerA.y
# Output: 10, 20 

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

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. This is useful when you've imported designs from Sketch or Photoshop and want to make a layer scrollable. 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.50.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: 50y: 25 }0.50.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. (Optional)
  3. animationOptions — An object with curve, time, delay and repeat properties. (Optional)
scroll = new ScrollComponent
 
# Scroll content to x: 200, y: 100 
scroll.scrollToPoint(
    x: 200y: 100
    true
    curve: "ease"
)
 
# Scroll very slowly 
scroll.scrollToPoint(
    x: 200y: 100
    true
    curve: "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. (Optional)
  3. originY — A number between 0 and 1. (Optional)
  4. animate — A boolean, set to true by default. (Optional)
  5. animationOptions — An object with curve, time, delay and repeat properties. (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 
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.50
    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.50.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. This is useful to create scrollable layers out of imported layers.

# Import files from Sketch 
sketch = Framer.Importer.load "imported/Scrollable"
 
# Wrap the "content" layer group 
scroll = ScrollComponent.wrap(sketch.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.

# Import files from Sketch 
sketch = Framer.Importer.load "imported/Scrollable"
 
# Wrap the "content" layer group 
scroll = ScrollComponent.wrap(sketch.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 
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"->
    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. (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(400,40,0)"})

States

States are sets of layer properties and values. You can add, remove or switch between states. State switching can be done with or without an animation, and you can define different animation options for individual states too.

layer.states.add(name, states)

Adds a layer state. Each layer state is a collection of layer properties and values. You can add them one by one with a name and property object or all at once with an object containing the layer names and properties.

There is always a "default" state, containing the property values that the layer was created with.

Arguments
  1. name — A string that is the title of the state.
  2. states — A collection of objects with layer properties and values.
layerA = new Layer
 
# Add a single state 
layerA.states.add
    stateA:
        x: 500
        opacity: 0.5
 
# Add a multiple states 
layerA.states.add
    stateA:
        x: 500
        opacity: 0.5
 
    stateB:
        x: 200
        opacity: 1

layer.states.remove(name)

Remove a layer state by name.

Arguments
  1. name — A string, the title of the state.
layerA = new Layer
 
layerA.states.add
    stateA:
        x: 500
        opacity: 0.5
 
layerA.states.remove("stateA")

layer.states.switch(name)

Switch to a new state. This will animate the layer to the new state. By default, it will use the layer.states.animationOptions.

Arguments
  1. name — A string, the title of the state.
layerA = new Layer
 
layerA.states.add
    stateA:
        x: 500
        opacity: 0.5
 
layerA.states.switch("stateA")

layer.states.switchInstant(name)

Switch to a new state without animating.

Arguments
  1. name — A string, the title of the state.
layerA = new Layer
 
layerA.states.add
    stateA:
        x: 500
        opacity: 0.5
 
layerA.states.switchInstant("stateA"