### 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 states or layer properties like scale and color with various easing or spring curves, repeat and delay options and more.

More on Animation

#### 3. States

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

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 =    stateA:        x: Align.right        y: Align.bottom    stateB:        x: Align.left        y: Align.top layerA.onTap -> layerA.stateCycle()

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

You can also optionally use offsets:

    layerA = new Layer    x: Align.center(-100) # 100 pixels left from the center     y: Align.top(100) # 100 pixels from the top

Please note that left and right only work for the x property, and top and bottom only for the y property. Center works for both. Align is a 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 targeted on a layer. This is what is created by the layer’s animate function. The only difference is that animation objects don’t start immediately, you have to explicitly execute `start()`.

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

##### Properties

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

###### Example: Layer and properties

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

    layerA = new Layer # Animate the layer to the right animationA = new Animation layerA,    x: 100 animationA.start()

###### Example: Layer and states

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

    layerA = new Layer layerA.states.stateA =    x: 100 # Animate the layer to the right animationB = new Animation layerA,    layerA.states.stateA animationB.start()

###### Example: Multiple properties and time

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

    layerA = new Layer # Animate multiple properties for 5 seconds animationC = new Animation layerA,    x: 100    opacity: 0.5    options:        time: 5 animationC.start()

###### Example: Repeat and delay

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

    layerA = new Layer # Repeat an animation 5 times, delay for 2 seconds animationD = new Animation layerA,    x: 100    options:        repeat: 5        delay: 2 animationD.start()

#### 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 layerA,    x: 100    opacity: 0.5    options:        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 layerA,    x: 100    options:        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 layerA,    x: 100    options:        curve: "spring-dho(800, 200, 10, 0.01)" animationA.start()

#### Animatable Properties

Only numeric layer properties and color can be animated:

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

###### Multiple Properties

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

###### Performance

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

- width
- height
- scrollX
- scrollY
- borderRadius
- borderWidth

#### animation.start()

Start the animation.

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

#### animation.stop()

Stop the animation.

    layerA = new Layer animationA = new Animation layerA,    x: 100 animationA.start() # Stop the animation animationA.stop()

#### animation.reverse()

Create a new animation with all reverse values.

    layerA = new Layer animationA = new Animation layerA,    x: 100 animationB = animationA.reverse() # Alternate between the two animations animationA.on Events.AnimationEnd, animationB.startanimationB.on Events.AnimationEnd, animationA.start animationA.start()

#### animation.reset()

Reset the layer to its default state.

    layerA = new Layer animationA = new Animation layerA,    x: 100 animationA.start() # On animation end reset the animation animationA.on Events.AnimationEnd, ->    animationA.reset()

#### animation.restart()

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

    layerA = new Layer animationA = new Animation layerA,    x: 100 animationA.start() # On animation end restart the animation animationA.on Events.AnimationEnd, ->    animationA.restart()

#### animation.finish()

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

    layerA = new Layer animationA = new Animation layerA,    x: 100,    time: 3 animationA.start() # Finish the animation after a 1 second delay Utils.delay 1, ->    animationA.finish()

### BackgroundLayer

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

    layerA = new BackgroundLayer    backgroundColor: "white"

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

    # Hex value for white layerA = new BackgroundLayer    backgroundColor: "#ffffff" # RGB value for white layerA = new BackgroundLayer    backgroundColor: "rgb(255,255,255)" # RGBA value for white layerA = new BackgroundLayer    backgroundColor: "rgba(255,255,255,1)"

### Canvas

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

#### Canvas.backgroundColor <string>

Sets the background color of the canvas.

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

#### Canvas.image <string>

Sets the background image of the canvas. You can set it as a 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: 40pointInScreen = 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(point, layer)

### Color

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

    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: 255, g: 255, b: 255) # Define a color with an HSL object layerB = new Layer    backgroundColor: new Color(h: 360, s: 1, l: 1, a: 1)

#### Color Models

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

    bg = new BackgroundLayer    backgroundColor: "blue" # Animate in RGB bg.animate    backgroundColor: "red"    options:        colorModel: "rgb"

#### color.lighten(amount)

Add white and return a lightened color.

###### Arguments

1. `amount` — A number, from 0 to 100. Set to 10 by default.

    # Create a new color, lighten it blue = new Color("#28affa").lighten(20) layerA = new Layer    backgroundColor: blue

#### color.darken(amount)

Add black and return a darkened color.

###### Arguments

1. `amount` — A number, from 0 to 100. Set to 10 by default.

    # Create a new color, darken it blue = new Color("#28affa").darken(20) layerA = new Layer    backgroundColor: blue

#### color.saturate(amount)

Increase the saturation of a color.

###### Arguments

1. `amount` — A number, from 0 to 100. Set to 10 by default.

    # Create a new Color, saturate it blue = new Color("#877DD7").saturate(100) layerA = new Layer    backgroundColor: blue

#### color.desaturate(amount)

Decrease the saturation of a color.

###### Arguments

1. `amount` — A number, from 0 to 100. Set to 10 by default.

    # Create a new Color, desaturate it blue = new Color("#28affa").desaturate(25) layerA = new Layer    backgroundColor: blue

#### color.grayscale()

Return a fully desaturated color.

    # Create a new Color 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 Layerlayer.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, [0, Screen.width], [0,1], true)     # Mix the colors, enable the limit, transition in HUSL     layerA.backgroundColor =        Color.mix("red", "yellow", fraction, true, "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    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.5Framer.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 = 50Framer.Device.x = 50 # Change from the current Device position Framer.Device.screen.x += 50Framer.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.5, true)

#### 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.5, true)

#### 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(90, true)

#### 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 LayerlayerA.draggable.enabled = true

#### layer.draggable.horizontal <boolean>

Enable or disable horizontal movement.

    layerA = new LayerlayerA.draggable.enabled = true # Disable horizontal dragging layerA.draggable.horizontal = false

#### layer.draggable.vertical <boolean>

Enable or disable vertical movement.

    layerA = new LayerlayerA.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 LayerlayerA.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 LayerlayerA.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 LayerlayerA.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 LayerlayerA.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 LayerlayerA.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 LayerlayerA.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 LayerlayerA.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 LayerlayerA.draggable.enabled = true # Disable momentum layerA.draggable.momentum = false

#### layer.draggable.momentumOptions <object>

Options for momentum simulation on DragEnd.

    layerA = new LayerlayerA.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 LayerlayerA.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 LayerlayerA.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 LayerlayerA.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 LayerlayerA.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 LayerlayerA.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 LayerlayerA.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.x, 20)    point.y = round(point.y, 20)    return point

#### layer.draggable.directionLock <boolean>

Snap to horizontal/vertical direction after a certain threshold.

    layerA = new LayerlayerA.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 LayerlayerA.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 LayerlayerA.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 LayerlayerA.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 LayerlayerA.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 LayerlayerA.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 LayerlayerA.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 LayerlayerA.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 LayerlayerA.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 LayerlayerA.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 LayerlayerA.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 LayerlayerA.name = "Layer A" clickHandler = (event, layer) ->    print "Clicked", layer.name layerA.on(Events.Click, clickHandler)layerA.off(Events.Click, clickHandler)

#### Tap Events

Tap events receive the gesture event properties.

1. `Events.Tap` — Tap a layer.
2. `Events.SingleTap` — Same as Tap.
3. `Events.DoubleTap` — Quickly tap a layer twice.

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

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

###### Tap Event Shortcuts

    # For Events.Tap layerA.onTap ->    print "Tap" # For Events.SingleTap layerA.onSingleTap ->    print "Single tap" # For Events.DoubleTap layerA.onDoubleTap ->    print "Double tap"

#### ForceTap Events

ForceTap events receive the gesture event properties.

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

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

###### ForceTap Event Shortcuts

    # For Events.ForceTap layerA.onForceTap ->    print "Force tap" # For Events.ForceTapChange layerA.onForceTapChange ->    print "Change of force tap pressure" # For Events.ForceTapStart layerA.onForceTapStart ->    print "Start force tap" # For Events.ForceTapEnd layerA.onForceTapEnd ->    print "End force tap"

#### LongPress Events

LongPress events receive the gesture event properties.

1. `Events.LongPress` — A long press.
2. `Events.LongPressStart` — Start of long press.
3. `Events.LongPressEnd` — End of long press.

    # Detect a long press layer.on Events.LongPress, (event) ->    print "Long press"

###### LongPress Event Shortcuts

    # For Events.LongPress layerA.onLongPress ->    print "Long press" # For Events.LongPressStart layerA.onLongPressStart ->    print "Start long press" # For Events.LongPressEnd layerA.onLongPressEnd ->    print "End long press"

#### Swipe Events

Swipe events receive the gesture event properties.

###### Basic

1. `Events.Swipe` — Swipe a layer.
2. `Events.SwipeStart` — Start swiping a layer.
3. `Events.SwipeEnd` — End swiping a layer.

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

###### Swipe Event Shortcuts

    # For Events.Swipe layerA.onSwipe ->    print "Currently swiping" # For Events.SwipeStart layerA.onSwipeStart ->    print "Start swiping" # For Events.SwipeEnd layerA.onSwipeEnd ->    print "End swiping"

###### Up

1. `Events.SwipeUp` — Upwards swiping.
2. `Events.SwipeUpStart` — Start swiping up.
3. `Events.SwipeUpEnd` — End swiping up.

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

###### SwipeUp Event Shortcuts

    # For Events.SwipeUp layerA.onSwipeUp ->    print "Currently swiping up" # For Events.SwipeUpStart layerA.onSwipeUpStart ->    print "Start swiping up" # For Events.SwipeUpEnd layerA.onSwipeUpEnd ->    print "End swiping up"

###### Right

1. `Events.SwipeRight` — Right swiping.
2. `Events.SwipeRightStart` — Start swiping right.
3. `Events.SwipeRightEnd` — End swiping right.

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

###### SwipeRight Event Shortcuts

    # For Events.SwipeRight layerA.onSwipeRight ->    print "Currently swiping right" # For Events.SwipeRightStart layerA.onSwipeRightStart ->    print "Start swiping right" # For Events.SwipeRightEnd layerA.onSwipeRightEnd ->    print "End swiping right"

###### Down

1. `Events.SwipeDown` — Downwards swiping.
2. `Events.SwipeDownStart` — Start swiping down.
3. `Events.SwipeDownend` — End swiping down.

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

###### SwipeDown Event Shortcuts

    # For Events.SwipeDown layerA.onSwipeDown ->    print "Currently swiping down" # For Events.SwipeDownStart layerA.onSwipeDownStart ->    print "Start swiping down" # For Events.SwipeDownEnd layerA.onSwipeDownEnd ->    print "End swiping down"

###### Left

1. `Events.SwipeLeft` — Left swiping.
2. `Events.SwipeLeftStart` — Start swiping left.
3. `Events.SwipeLeftEnd` — End swiping left.

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

###### SwipeLeft Event Shortcuts

    # For Events.SwipeLeft layerA.onSwipeLeft ->    print "Currently swiping left" # For Events.SwipeLeftStart layerA.onSwipeLeftStart ->    print "Start swiping left" # For Events.SwipeLeftEnd layerA.onSwipeLeftEnd ->    print "End swiping left"

#### Pan Events

Pan events receive the gesture event properties.

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

    layerA = new Layer # Detect a panning gesture layerA.on Events.Pan, (event) ->    print event.distance

###### Pan Event Shortcuts

    # For Events.Pan layerA.onPan ->    print "Currently panning" # For Events.PanStart layerA.onPanStart ->    print "Start panning" # For Events.PanMove layerA.onPanMove ->    print "Currently panning" # For Events.PanEnd layerA.onPanEnd ->    print "End panning" # For Events.PanLeft layerA.onPanLeft ->    print "Panning left" # For Events.PanRight layerA.onPanRight ->    print "Panning right" # For Events.PanUp layerA.onPanUp ->    print "Panning up" # For Events.PanDown layerA.onPanDown ->    print "Panning down"

#### Pinch Events

Pinch events receive the gesture event properties.

1. `Events.Pinch` — Two pointers moving inwards or outwards.
2. `Events.PinchStart` — Start pinching.
3. `Events.PinchEnd` — End of pinching.

    layerA = new LayerlayerA.pinchable.enabled = true layerA.on Events.Pinch, ->    print layerA.scale, layerA.rotation

###### Pinch Event Shortcuts

    # For Events.Pinch layerA.onPinch ->    print "Currently pinching" # For Events.PinchStart layerA.onPinchStart ->    print "Start pinching" # For Events.PinchEnd layerA.onPinchEnd ->    print "End pinching"

#### Scale Events

Scale events receive the gesture event properties.

1. `Events.Scale` — Scale a layer with two pointers.
2. `Events.ScaleStart` — Start scaling.
3. `Events.ScaleEnd` — End scaling.

    layerA = new LayerlayerA.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 LayerlayerA.pinchable.enabled = true layerA.on Events.Rotate, ->    print layerA.rotation

###### Rotate Event Shortcuts

    # For Events.Rotate layerA.onRotate ->    print "Currently rotating" # For Events.RotateStart layerA.onRotateStart ->    print "Start rotating" # For Events.RotateEnd layerA.onRotateEnd ->    print "End rotating"

#### Touch Events

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

    layerA = new Layer # Returns the event and the layer layerA.on Events.TouchStart, (event, layer) ->    print event, layer

###### Touch Event Shortcuts

    # For Events.TouchStart layerA.onTouchStart ->    print "Start touch" # For Events.TouchMove     layerA.onTouchMove ->    print "Touch move" # For Events.TouchEnd layerA.onTouchEnd ->    print "End touch"

#### Click Events

1. `Events.Click` — Click or touch (no delay on mobile).

    layerA = new Layer # Returns the event and the layer layerA.on Events.Click, (event, layer) ->    print event, layer

###### Click Event Shortcuts

    # For Events.Click layerA.onClick ->    print "Click"

#### Mouse Events

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

    layerA = new Layer # Returns the event and the layer layerA.on Events.MouseOver, (event, layer) ->    print event, layer

###### Mouse Event Shortcuts

    # For Events.mouseup layerA.onMouseUp ->    print "mouseup" # For Events.MouseDown layerA.onMouseDown ->    print "mousedown" # For Events.MouseOver layerA.onMouseOver ->    print "mouseover" # For Events.MouseOut layerA.onMouseOut ->    print "mouseout" # For Events.MouseMove layerA.onMouseMove ->    print "mousemove" # For Events.MouseWheel layerA.onMouseWheel ->    print "mousewheel"

#### Animation Events

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

    layerA = new Layer layerA.animate    x: 100 # Returns the animation and the layer layerA.on Events.AnimationEnd, (animation, layer) ->    print animation, layer

###### Animation Event Shortcuts

    # For Events.AnimationStart layerA.onAnimationStart ->    print "Animation started" # For Events.AnimationStop layerA.onAnimationStop ->    print "Animation stopped" # For Events.AnimationEnd     layerA.onAnimationEnd ->    print "Animation ended"

#### State Events

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

(`StateSwitch` deprecated the `StateWillSwitch` and `StateDidSwitch` events)

    layerA = new Layer layerA.states.rotate =    rotation: 90 layerA.stateSwitch("rotate") # Returns the old and new state layerA.on Events.StateSwitchEnd, (from, to) ->    print from, to

###### State Event Shortcuts

    # For Events.StateSwitchStart layerA.onStateSwitchStart ->    print "Will switch state" # For Events.StateSwitchStop layerA.onStateSwitchStop ->    print "Did switch state" # For Events.StateSwitchEnd layerA.onStateSwitchEnd ->    print "Did switch state"

#### Drag Events

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

    layerA = new LayerlayerA.draggable.enabled = true # Returns the offset (x, y), layer.draggable and the layer layerA.on Events.Move, (offset, draggable, layer) ->    print offset, draggable, layer

    layerA = new LayerlayerA.draggable.enabled = true # Returns the event, layer.draggable and the layer layerA.on Events.DragStart, (event, draggable, layer) ->    print event, draggable, layer

###### Drag Event Shortcuts

    # For Events.Move layerA.onMove ->    print "Moving" # For Events.DragStart layerA.onDragStart ->    print "Start of drag" # For Events.Drag     layerA.onDrag ->    print "Dragging" # For Events.DragEnd     layerA.onDragEnd ->    print "End of drag" # For Events.DragAnimationStart     layerA.onDragAnimationStart ->    print "Start of drag animation" # For Events.DragAnimationEnd     layerA.onDragAnimationEnd ->    print "End of drag animation" # For Events.DirectionLockStart     layerA.onDirectionLockStart ->    print "Start of direction lock"

#### Scroll Events

1. `Events.Move` — The layer is moving.
2. `Events.ScrollStart` — Start scrolling.
3. `Events.Scroll` — While scrolling.
4. `Events.ScrollEnd` — End of scroll.
5. `Events.ScrollAnimationDidStart` — Did start momentum/bounce animation.
6. `Events.ScrollAnimationDidEnd` — Did end momentum/bounce animation.

    scroll = new ScrollComponentlayerA = new Layer    parent: scroll.content # Returns the event, layer.draggable and the layer scroll.on Events.ScrollStart, (event, draggable, layer) ->    print event, draggable, layer

###### Scroll Event Shortcuts

    # For Events.Move scroll.onMove ->    print "Moving" # For Events.ScrollStart scroll.onScrollStart ->    print "Start of scroll" # For Events.Scroll     scroll.onScroll ->    print "Scrolling" # For Events.ScrollEnd     scroll.onScrollEnd ->    print "End of scroll" # For Events.ScrollAnimationDidStart     scroll.onScrollAnimationDidStart ->    print "Start of scroll animation" # For Events.ScrollAnimationDidEnd     scroll.onScrollAnimationDidEnd ->    print "End of scroll animation"

#### EdgeSwipe Events

EdgeSwipe events receive the gesture event properties.

###### Basic

1. `Events.EdgeSwipe` — Swipe from any edge of the screen.
2. `Events.EdgeSwipeStart` — Start edge swipe.
3. `Events.EdgeSwipeEnd` — End edge swipe.

    # Swipe from any edge of the screen Screen.on Events.EdgeSwipe, (event) ->    print event.distance

###### EdgeSwipe Event Shortcuts

    # For Events.EdgeSwipe Screen.onEdgeSwipe ->    print "Swiping from edge" # For Events.EdgeSwipeStart Screen.onEdgeSwipeStart ->    print "Start swiping from edge" # For Events.EdgeSwipeEnd Screen.onEdgeSwipeEnd ->    print "End swiping from edge"

###### Top

1. `Events.EdgeSwipeTop` — Edge swipe from top.
2. `Events.EdgeSwipeTopStart` — Start edge swipe from top.
3. `Events.EdgeSwipeTopEnd` — End edge swipe from top.

    # Swipe from the top edge of the screen Screen.on Events.EdgeSwipeTop, (event) ->    print event.distance

###### EdgeSwipeTop Event Shortcuts

    # For Events.EdgeSwipeTop Screen.onEdgeSwipeTop ->    print "Swiping from top edge" # For Events.EdgeSwipeTopStart Screen.onEdgeSwipeTopStart ->    print "Start swiping from top edge" # For Events.EdgeSwipeTopEnd Screen.onEdgeSwipeTopEnd ->    print "End swiping from top edge"

###### Right

1. `Events.EdgeSwipeRight` — Edge swipe from right.
2. `Events.EdgeSwipeRightStart` — Start edge swipe from right.
3. `Events.EdgeSwipeRightEnd` — End edge swipe from right.

    # Swipe from the right edge of the screen Screen.on Events.EdgeSwipeRight, (event) ->    print event.distance

###### EdgeSwipeRight Event Shortcuts

    # For Events.EdgeSwipeRight Screen.onEdgeSwipeRight ->    print "Swiping from right edge" # For Events.EdgeSwipeRightStart Screen.onEdgeSwipeRightStart ->    print "Start swiping from right edge" # For Events.EdgeSwipeRightEnd Screen.onEdgeSwipeRightEnd ->    print "Start swiping from right edge"

###### Bottom

1. `Events.EdgeSwipeBottom` — Edge swipe from bottom.
2. `Events.EdgeSwipeBottomStart` — Start edge swipe from bottom.
3. `Events.EdgeSwipeBottomEnd` — End edge swipe from bottom.

    # Swipe from the bottom edge of the screen Screen.on Events.EdgeSwipeBottom, (event) ->    print event.distance

###### EdgeSwipeBottom Event Shortcuts

    # For Events.EdgeSwipeBottom Screen.onEdgeSwipeBottom ->    print "Swiping from bottom edge" # For Events.EdgeSwipeBottomStart Screen.onEdgeSwipeBottomStart ->    print "Start swiping from bottom edge" # For Events.EdgeSwipeBottomEnd Screen.onEdgeSwipeBottomEnd ->    print "End swiping from bottom edge"

###### Left

1. `Events.EdgeSwipeLeft` — Edge swipe from left.
2. `Events.EdgeSwipeLeftStart` — Start edge swipe from left.
3. `Events.EdgeSwipeLeftEnd` — End edge swipe from left.

    # Swipe from the left edge of the screen Screen.on Events.EdgeSwipeLeft, (event) ->    print event.distance

###### EdgeSwipeLeft Event Shortcuts

    # For Events.EdgeSwipeLeft Screen.onEdgeSwipeLeft ->    print "Swiping from left edge" # For Events.EdgeSwipeLeftStart Screen.onEdgeSwipeLeftStart ->    print "Start swiping from left edge" # For Events.EdgeSwipeLeftEnd Screen.onEdgeSwipeLeftEnd ->    print "End swiping from left edge"

#### Change Events

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

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

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

    layerA = new Layer layerA.animate    x: 100 layerA.on "change:x", ->    print layerA.x

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

    layerA = new LayerlayerB = new Layer    x: 100 # We rotate layerA from 0 to 180 degrees. layerA.animate    rotation: 180 # When the rotation value from layerA changes layerA.on "change:rotation", ->     # Use the values to move layerB from 100 to 300     x = Utils.modulate(layerA.rotation, [0, 180], [100, 300], 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 LayerlayerA.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 LayerlayerA.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:

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

###### Customization

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

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

    layerA = new LayerlayerA.onTap -> print "layerA" layerB = new Layer x: 220layerB.onTap -> print "layerB" # Set an empty function on showHint layerB.showHint = -> print "nope"

And you can customize the hint the same way:

    layerA = new LayerlayerA.onTap -> print "layerA" layerB = new Layer x: 220layerB.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        scale: 1.3        opacity: 0        options:            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:

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

### 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 Layerprint 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 LayerlayerA.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 LayerlayerA.x = 500

#### layer.y <number>

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

    layerA = new LayerlayerA.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 LayerlayerA.z = 500

#### layer.width <number>

The width of the layer in pixels.

    layerA = new LayerlayerA.width = 500

#### layer.height <number>

The height of the layer in pixels.

    layerA = new LayerlayerA.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 = 500print 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 = 500print 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 = 500print 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 = 500print 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.x, layerB.y# Output: 200, 200

#### layer.centerX(offset)

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

###### Arguments

1. `offset` — A number that offsets the position.

    layerA = new Layer    width: 500    height: 500 layerB = new Layer    parent: layerA    width: 100    height: 100 layerB.centerX()print layerB.x, layerB.y# Output: 200, 0  layerB.centerX(20)print layerB.x, layerB.y# Output: 220, 0

#### layer.centerY(offset)

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

###### Arguments

1. `offset` — A number that offsets the position.

    layerA = new Layer    width: 500    height: 500 layerB = new Layer    parent: layerA    width: 100    height: 100 layerB.centerY()print layerB.x, layerB.y# Output: 0, 200  layerB.centerY(20)print layerB.x, layerB.y# Output: 0, 220

#### layer.pixelAlign()

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

    layerA = new Layer    x: 100.18293    y: 10.12873 layerA.pixelAlign() print layerA.x, layerA.y# Output: 100, 10

#### layer.screenFrame <object>

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

    layerA = new Layer    x: 100 layerB = new Layer    parent: layerA    x: 100 print layerB.screenFrame# Output: { x: 200, y: 0, width: 100, height: 100 }  layerB.screenFrame =    x: 400    y: 0    width: 100    height: 100 print layerB.x# Output: 300

#### layer.contentFrame()

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

    layerA = new LayerlayerB = 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 LayerlayerA.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 LayerlayerA.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 LayerlayerA.rotation = 45layerA.originX = 0layerA.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 LayerlayerA.rotation = 45layerA.originY = 0layerA.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 LayerlayerA.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 LayerlayerA.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 LayerlayerA.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 LayerlayerA.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 LayerlayerA.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 LayerlayerA.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 LayerlayerA.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 LayerlayerA.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 LayerlayerB = 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 LayerlayerB = 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 LayerlayerB = 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 LayerlayerB = new Layer # Draw layerB on top layerA.index = 2layerB.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 LayerlayerB = 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 LayerlayerB = 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 LayerlayerB = new LayerlayerC = new Layer # Draw layerA on top layerA.bringToFront()

#### layer.sendToBack()

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

    layerA = new LayerlayerB = new LayerlayerC = 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 LayerlayerA.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 LayerlayerA.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 LayerlayerB = new Layer    parent: layerA layerC = layerA.copy()

#### layer.copySingle()

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

    layerA = new LayerlayerB = 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 LayerlayerA.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 LayerlayerA.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 LayerlayerA.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 LayerlayerA.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 LayerlayerA.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 LayerlayerA.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 LayerlayerA.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 LayerlayerA.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 LayerlayerA.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 LayerlayerA.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 LayerlayerA.shadowY = 1layerA.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 LayerlayerA.shadowY = 1layerA.shadowBlur = 4layerA.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 LayerlayerA.shadowY = 1layerA.shadowBlur = 4layerA.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 LayerlayerA.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 LayerlayerA.borderColor = "red"layerA.borderWidth = 2

#### layer.borderWidth <number>

Set the width of the layer border in pixels.

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

#### layer.animate(properties or state, options)

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

###### Arguments

1. `properties` or `state` — A layer properties object or the name of the state it should animate to.
2. `options` — An object with all the animation options like curve, time and more. (Optional)

###### Example: Animate with properties

    layerA = new Layer # Animate the x position layerA.animate    x: 200

###### Example: Animate with properties and options

    layerA = new Layer # Animate the x position with options layerA.animate    x: 200    options:        curve: "spring"

###### Example: Animate with states

    layerA = new Layer # Create a new state layerA.states.stateA =    x: 200 # State animation layerA.animate "stateA"

###### Example: Animate with states and options

    layerA = new Layer # Create a new state layerA.states.stateA =    x: 200 # State animation with options layerA.animate "stateA",    curve: "spring"

#### layer.animationOptions <object>

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

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

###### Properties

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

    layerA = new Layer layerA.animationOptions =    curve: "ease"    time: 0.25

#### layer.animations()

Returns all the current running animations for this layer.

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

#### layer.isAnimating <boolean>

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

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

#### layer.animateStop()

Immediately stop all animations running on this layer.

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

#### layer.stateSwitch(name)

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

###### Arguments

1. `name` — A string, the name of the state.

    layerA = new Layer layerA.states.stateA =    x: 100 layerA.stateSwitch("stateA")

#### layer.stateCycle(states, options)

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

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

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

###### Arguments

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

    layerA = new Layer layerA.states =    stateA:        x: 100    stateB:        x: 200 # Every time we call this we cycle to the next state layerA.stateCycle(["stateA", "stateB"])

#### layer.stateNames <Array>

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

    layerA = new Layer layerA.states =    stateA:        x: 100    stateB:        y: 100 print layerA.stateNames# Result: ["stateA", "stateB"]

#### layer.convertPointToCanvas(point)

Converts a point from a layer to the Canvas.

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

#### layer.on(eventName, handler)

Start listening to an event on this layer.

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

    layerA = new LayerlayerA.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 LayerlayerA.name = "layerA" clickHandler = (event, layer) ->    print "This layer was clicked", layer.name layerA.on(Events.Click, clickHandler)layerA.off(Events.Click, clickHandler)

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

- Connect a MIDI device
- Open Framer and paste the following code

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

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: value, g: 0, b: 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

- Create a new project in Framer Studio
- Navigate to the /modules folder and open the myModule.coffee file in a text-editor.
- To include the module within your project, add the following:

    # 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 = [1, 2, 3] # 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            x: startX            y: startY            options:                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.framernpm 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 PageComponentpage.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 PageComponentpage.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 PageComponentpage.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(pageTwo, false) # Scroll back to the page at its left, which is pageOne page.snapToNextPage("left", true)

#### page.snapToPreviousPage()

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

    page = new PageComponent # Snap to the previous page page.snapToPreviousPage()

#### page.addPage(direction)

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

    page = new PageComponent    width: Screen.width    height: Screen.height # The first page, placed directly within the page.content pageOne = new Layer    width: page.width    height: page.height    parent: page.content    backgroundColor: "#28affa" # Second page pageTwo = new Layer    width: page.width    height: page.height    backgroundColor: "#90D7FF" # Third page pageThree = new Layer    width: page.width    height: page.height    backgroundColor: "#CAECFF"  # Add the second and third page to the right page.addPage(pageTwo, "right")page.addPage(pageThree, "right")

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

    page = new PageComponent    width: Screen.width    height: Screen.height pageOne = new Layer    width: page.width    height: page.height    parent: page.content    backgroundColor: "#28affa" pageTwo = new Layer    width: page.width    height: page.height    backgroundColor: "#90D7FF" # Add a page to the right page.addPage(pageTwo, "right") # Start at the second page by default page.snapToPage(pageTwo, false)

#### page.horizontalPageIndex(page)

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

    page = new PageComponent    width: Screen.width    height: Screen.height 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 LayerlayerA.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 LayerlayerA.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 LayerlayerA.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 LayerlayerA.pinchable.enabled = true # Disable scale on pinch layerA.pinchable.scale = false

#### layer.pinchable.scaleIncrements <number>

Scale the pinchable layer incrementally.

    layerA = new LayerlayerA.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 LayerlayerA.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 LayerlayerA.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 LayerlayerA.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 LayerlayerA.pinchable.enabled = true # Disable scale on pinch layerA.pinchable.rotate = false

#### layer.pinchable.rotateIncrements <number>

Rotate the pinchable layer incrementally.

    layerA = new LayerlayerA.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 LayerlayerA.pinchable.enabled = true # Increase the rotation speed by 2 layerA.pinchable.rotateFactor = 2

### Print

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

    print "Hello"# Output: "Hello"

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

    layerA = new Layer    x: 10    y: 20 # A single property value print layerA.x# Output: 10  # Multiple values print layerA.x, print layerA.y# Output: 10, 20

### Screen

The Screen object contains the size of the current device screen. The size changes when switching to a different device. You can also change the background color and the perspective of the device screen.

#### Screen.backgroundColor <string>

Sets the background color of the device screen.

    # Change the device screen background color Screen.backgroundColor = "#28affa"

#### Screen.width <number>

The width of the current device screen in pixels. (Read-only)

    print Screen.width# Output: 640

#### Screen.height <number>

The height of the current device screen in pixels. (Read-only)

    print Screen.height# Output: 1080

#### Screen.size <object>

The width and height of the current device screen in pixels. (Read-only)

    print Screen.size# Output: { width:640, height: 1080 }

#### Screen.frame <object>

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

    print Screen.frame# Output: { x:0, y:0, width:640, height: 1080 }

#### Screen.perspective <number>

The perspective of the current device screen. Set to 1200 by default.

    # Rotate layer in 3D layerA = new Layer    rotationX = 30 # Adjust perspective Screen.perspective = 1000

#### Screen.perspectiveOriginX <number>

Sets the x origin for 3D transformations. The origin is defined as a number, where 0 is the left edge of the screen and 1 the right edge. The default value is 0.5, the center of the screen.

    # Rotate layer in 3D layerA = new Layer    rotationX = 30 # Set horizontal perspective origin Screen.perspectiveOriginX = 1

#### Screen.perspectiveOriginY <number>

Sets the y origin for 3D transformations. The origin is defined as a number, where 0 is the top edge of the screen and 1 the bottom edge. The default value is 0.5, the center of the screen.

    # Rotate layer in 3D layerA = new Layer    rotationX = 30 # Set vertical perspective origin Screen.perspectiveOriginY = 1

#### Screen.convertPointToCanvas(point)

Converts a point from the Screen to the Canvas.

    point =    x: 20    y: 40 pointInCanvas = Screen.convertPointToCanvas(point)

#### Screen.convertPointToLayer(point, layer)

Converts a point from the Screen to a layer.

    point =    x: 20    y: 40 layer = new Layer pointInLayer = Screen.convertPointToLayer(point, layer)

### ScrollComponent

A ScrollComponent is used to scroll content. It implements momentum and spring physics, allows for customization, and emits different events.

The ScrollComponent is built with two layers. The ScrollComponent itself is a layer that masks its content. It has a content layer that has draggable enabled and constraints configured. It automatically manages the size of the content layer based on the total size of the sub layers of the content layer.

    # Create a new ScrollComponent scroll = new ScrollComponent    width: 100    height: 100 # Include a Layer layerA = new Layer    parent: scroll.content

You can also wrap an existing layer within a ScrollComponent, using ScrollComponent.wrap(). The ScrollComponent will insert itself in-between the content and its super layer. 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.5, 0.5)

#### scroll.closestContentLayerForScrollPoint(originX, originY)

Get the content layer closest to a specific point.

    scroll = new ScrollComponent # Create content layers layerA = new Layer    parent: scroll.content    name: "layerA"    x: 0    y: 0 layerB = new Layer    parent: scroll.content    name: "layerB"    x: 50    y: 50 # Get the layer of which the top-left # corner is closest to x: 50, y: 25 print scroll.closestContentLayerForScrollPoint(    x: 50    y: 25) # Returns layerB

You can adjust the origin values to define how the distance is calculated. The default values are `(0,0)`. This means that it calculates the distance from the top-left of the ScrollComponent to the top-left of the content layers.

    scroll = new ScrollComponent # Create content layers layerA = new Layer    parent: scroll.content    name: "layerA"    x: 0    y: 0  layerB = new Layer    parent: scroll.content    name: "layerB"    x: 50    y: 50 # With the origins set to the center, # layerA becomes the closest print scroll.closestContentLayerForScrollPoint({ x: 50, y: 25 }, 0.5, 0.5) # Returns layerA

#### scroll.scrollToPoint(point, animate, animationOptions)

Scroll to a specific point, optionally animating.

###### Arguments

1. `point` — An object with x and y properties.
2. `animate` — A boolean, set to true by default. (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: 200, y: 100    true    curve: "ease") # Scroll very slowly scroll.scrollToPoint(    x: 200, y: 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.5, 0    true    time: 2)

#### scroll.scrollToClosestLayer(originX, originY)

Scroll to the closest content layer, using the given origin. The default values are `(0,0)` which is the top-left corner, `(0.5, 0.5)` the center, and `(1,1)` the bottom-right corner.

###### Arguments

1. `originX` — A number between 0 and 1.
2. `originY` — A number between 0 and 1.

    scroll = new ScrollComponent layerA = new Layer    parent: scroll.content    x: 75    y: 75 # Scroll to the center of layerA scroll.scrollToClosestLayer(0.5, 0.5)

#### scroll.mouseWheelEnabled <boolean>

Enable or disable scrolling with mousewheel. Disabled by default. When set to `true`, layers can be scrolled both by dragging and with the mouse.

    scroll = new ScrollComponent    width: 100    height: 100 # Allow scrolling with mouse scroll.mouseWheelEnabled = true layerA = new Layer    parent: scroll.content    image: "images/bg.png"    width: 100    height: 200

#### scroll.wrap(layer)

Wraps a layer within a new ScrollComponent. 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 = falsescroll.speedY = 0.5 # Change scroll.content properties scroll.content.draggable.momentum = truescroll.content.draggable.overdrag = falsescroll.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 SliderComponentslider.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 SliderComponentslider.center() # Customize the appearance slider.knob.shadowY = 2slider.knob.shadowBlur = 4slider.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 SliderComponentslider.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 SliderComponentslider.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 SliderComponentslider.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 SliderComponentslider.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 SliderComponentslider.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 SliderComponentslider.center() # Animate to 1 slider.animateToValue(1) # Animate with a custom curve slider.animateToValue(1, { curve: "spring(400,40,0)"})

### States

Layer states manage and organize different combinations of layer properties. Animations can use them as a target. Switch lets you jump to another state instantly and cycle allows you to sequentially move from state to state.

You can add any layer property to a state, like `x` and `y`. Non-animatable layer properties like `html` will be set at the end of the state animation.

States can have an animation options property. Which will be used whenever layers get animated to the defined state.

There are three pre-defined states that can't be overridden because they are already assigned to serve a purpose. You can get the state names for current and previous using their name property.

1. `default` — The initially active state.
2. `current` — The currently active state.
3. `previous` — The previously active state.

###### Example: Create and delete a state

    # Create a state layerA.states.stateA =    x: 100 # Delete a state delete layerA.states.stateA

###### Example: A state with animation options

    # Create a state with animationOptions layerA.states.stateA =    x: 100    animationOptions:        curve: "spring"

###### Example: Animate to a state

    # Create a state layerA.states.stateA =    x: 100 # Animate to the state layerA.animate("stateA")

###### Example: Switch to a state

    # Create a state layerA.states.stateA =    x: 100 # Switch to the state without an animation layerA.stateSwitch("stateA")

###### Example: Cycle through states

    # Set multiple states at once layerA.states =    stateA:        x: 100    stateB:        x: 200 # On a click, go back and forth between states. layerA.onTap ->    layerA.stateCycle("stateA", "stateB")

#### layer.states.current <object>

Returns an object of the currently active state.

###### Properties

1. `name` — A read-only property that returns the name of the state object.

    layerA = new Layer layerA.states.stateA =    x: 500    opacity: 0.5 layerA.stateSwitch("stateA") print layerA.states.current# Output: <Object State>  print layerA.states.current.name# Output: stateA

#### layer.states.previous <object>

Returns an object of the previously active state.

###### Properties

1. `name` — A read-only property that returns the name of the state object.

    layerA = new Layer layerA.states.stateA =    x: 500    opacity: 0.5 layerA.stateSwitch("stateA") print layerA.states.previous# Output: <Object State>

### Utilities

Utilities are custom functions in Framer, designed to make things easier to do. For example, they allow you to map values, set delays and intervals, detect devices and more. See below for a complete overview.

#### Utils.modulate(value, [a, a], [b, b], limit)

Translates a number between two ranges. When you enable limit, it will never return a value outside of the `b` range. The default value for limit is `false`.

###### Arguments

1. `value` — A variable, representing the input.
2. `[a, a]` — The first range of two numbers.
3. `[b, b]` — The second range of two numbers.
4. `limit` — A boolean, set to false by default. (Optional)

    print Utils.modulate(0.5, [0, 1], [0, 100])# Output: 50  print Utils.modulate(1, [0, 1], [0, 100])# Output: 100

You can think of modulate as a way to convert numbers between different scales. Like going from Celcius to Farenheit, or Kilometers to Miles.

    # Convert to Celsius/Farenheit Utils.modulate(celcius, [0, 100], [32, 212])

It's also useful for creating parallax effects on scroll. For example, you can move a layer from `0-10`, when scrolling from `0-100`.

    scroll = new ScrollComponent    scrollHorizontal: false layerA = new Layer    x: 100 # Modulate the scrolling distance scroll.on Events.Move, ->    y = Utils.modulate(scroll.scrollY, [0,100], [0,10])    layerA.y = y

#### Utils.cycle(values)

Creates a function that returns the next value of an array every time it's called.

###### Arguments

1. `values` — An array of values.

    cycler = Utils.cycle(["a", "b", "c"]) print cycler() # Output: "a" print cycler() # Output: "b" print cycler() # Output: "c" print cycler() # Output: "a", returns to start

#### Utils.labelLayer(layer, text)

Quickly add a label to a layer. By default, the text will be set in Menlo, and positioned in the center of the layer.

###### Arguments

1. `layer` — A layer object.
2. `text` — A string.

    layerA = new Layer # Add a label to layerA  Utils.labelLayer(layerA, "Hello")

#### Utils.round(value, decimals, increments, min, max)

Rounds a number.

###### Arguments

1. `value` — A floating point number.
2. `decimals` — The amount to appear after the decimal point. (Optional)
3. `increments` — The increment to round to. (Optional)
4. `min` — The minimum value to return. (Optional)
5. `max` — The maximum value to return. (Optional)

    print Utils.round(100.12345, 0) # Output 100 print Utils.round(100.12345, 2) # Output 100.12 print Utils.round(100.12345, 4) # Output 100.1234

#### Utils.randomChoice(values)

Select a random item in an array of values.

###### Arguments

1. `values` — An array of values.

    print Utils.randomChoice(["a", "b", "c"]) # Output: "c" print Utils.randomChoice(["a", "b", "c"]) # Output: "b" print Utils.randomChoice(["a", "b", "c"]) # Output: "b" print Utils.randomChoice(["a", "b", "c"]) # Output: "b" print Utils.randomChoice(["a", "b", "c"]) # Output: "a"

#### Utils.randomColor(opacity)

Creates a random color with a given opacity. The opacity is optional.

###### Arguments

1. `opacity` — A number between 0 and 1. (Optional)

    layerA = new LayerlayerA.backgroundColor = Utils.randomColor(0.5) print layerA.backgroundColor# Output: "rgba(124, 12, 33, 0.5)"

#### Utils.randomImage(layer or size)

Generate a random unsplash image url. If you optionally pass a layer or size, it will keep using the same image for that layer and optimize for the size.

###### Arguments

1. `layer` — Layer

    layer = new Layerlayer.image = Utils.randomImage() # Unoptimized layer.image = Utils.randomImage(layer) # Preferred

#### Utils.randomNumber(a, b)

Generate a random number between a and b.

###### Arguments

1. `a` — A number, the first value of the range.
2. `b` — A number, the final value of the range.

    print Utils.randomNumber(0, 1) # Output: 0.2 print Utils.randomNumber(0, 100) # Output: 22

#### Utils.delay(delay, handler)

Calls a funtion after a delay. Delay is defined in seconds.

###### Arguments

1. `delay` — A number, representing seconds.
2. `handler` — A function.

    Utils.delay 0.5, ->    print "hello" # Output: "hello", after 0.5 seconds

#### Utils.frameInset(frame, inset)

###### Arguments

1. `frame` — An object with x, y, width, height.
2. `inset` — A number or object with top, right, bottom, left

Inset a frame by a certain amount of pixels.

    print Utils.frameInset({x:0, y:0, width:100, height:100}, 10) # Output {x:10, y:10, width:80, height:80}  print Utils.frameInset({x:0, y:0, width:100, height:100}, {top: 20}) # Output {x:0, y:20, width:100, height:80}

#### Utils.interval(interval , handler)

Calls a function every x seconds.

    Utils.interval 2, ->    print "hello" # Output: "hello" # Output: "hello" # Output: "hello" # Output: "hello" etc...

#### Utils.debounce(interval, handler)

Creates a function that will delay the calling of handler until after x seconds have elapsed since the last time it was invoked. Alias to _.debounce.

###### Arguments

1. `interval` — A number, representing seconds.
2. `handler` — A function.

    handler = Utils.debounce 0.1, ->    print "hello" for i in [1..100]    handler() # Output: "hello" only once

#### Utils.insertCSS(css)

Add css to a layer by wrapping it in a string and passing it as a parameter.

    layerA = new LayerlayerA.classList.add("testClass") css = """.testClass {    border: 1px solid #000;}""" print Utils.insertCSS(css)

#### Utils.throttle(interval, handler)

Creates a function that will call the wrapped function at most once per x seconds. Alias to _.throttle.

###### Arguments

1. `interval` — A number, representing seconds.
2. `handler` — A function.

    handler = Utils.throttle 0.1, ->    print "hello" for i in [1..100]    handler() # Output: "hello" only once

#### Utils.isWebKit()

Returns whether this is a WebKit browser.

    print Utils.isWebKit() # Output true

#### Utils.isChrome()

Returns whether this is a Chrome browser.

    print Utils.isChrome() # Output true

#### Utils.isSafari()

Returns whether this is a Safari browser.

    print Utils.isSafari() # Output true

#### Utils.isTouch()

Returns whether this is a touch enabled browser.

    print Utils.isTouch() # Output true

#### Utils.isDesktop()

Returns whether this is a desktop browser.

    print Utils.isDesktop() # Output true

#### Utils.isPhone()

Returns whether this is a phone device.

    print Utils.isPhone() # Output true

#### Utils.isTablet()

Returns whether this is a tablet device.

    print Utils.isTablet() # Output true

#### Utils.isMobile()

Returns whether this is a mobile device (phones and tables).

    print Utils.isMobile() # Output true

### VideoLayer

A videoLayer loads a video. VideoLayers have a `layer.player` object to control the video. The browser supports many different types of video, including the Animation codec that supports alpha channels.

#### videoLayer.video <string>

Sets the video URL for the video layer.

    # Set on creation layerA = new VideoLayer    video: "hello.mp4" # Change afterwards layerA.video = "bye.mp4"

#### videoLayer.player <object>

Player object for the video layer. Allows you to control the video and listen for playback events. See this overview of all video methods and properties.

    # Set on creation layerA = new VideoLayer    video: "hello.mp4" # Enable auto play layerA.player.autoplay = true # Play the video layerA.player.play() # Jump to 5 seconds layerA.player.fastSeek(5) # Listen to paused playback Events.wrap(layerA.player).on "pause", ->    print "Video paused"