Edit Page

#Utilities

Utilities provide simple helper methods and properties for advanced prototyping needs.

#Transform

#transform(inputValue, inputRange, outputRange, options): T

Transforms numbers into other values by mapping them from an input range to an output range. Returns the type of the input provided.

Given an input range of [0, 200] and an output range of [0, 1], this function will return a value between 0 and 1. The input range must be a linear series of numbers. The output range can be any supported value type, such as numbers, colors, shadows, arrays, objects and more. Every value in the output range must be of the same type and in the same format.

import * as React from "react"
import { Frame, transform } from "framer"

export function MyComponent() {
   const inputRange = [0, 200]
   const outputRange = [0, 1]
   const output = transform(100, inputRange, outputRange)

   // Returns 0.5
   return <Frame>{output}</Frame>
}
inputValue: number

A number to transform between the input and output ranges.

inputRange: number[]

A linear series of numbers (either all increasing or decreasing).

outputRange: T[]

A series of numbers, colors, strings, or arrays/objects of those. Must be the same length as inputRange.

options: TransformOptions<T>

Clamp: Clamp values to within the given range. Defaults to true.

returns: T

#Ranges

The transform method also supports ranges of more than 2 numbers. Given an input range of [-200, -100, 100, 200] and an output range of [0, 1, 1, 0], this function will:

  • If input is between -200 and -100, return a value between 0 and 1
  • If input is between -100 and 100, return 1
  • If input is between 100 and 200, return a value between 1 and 0
import * as React from "react"
import { Frame, transform } from "framer"

export function MyComponent() {
  const inputRange = [-200, -100, 100, 200]
  const outputRange = [0, 1, 1, 0]
  const output = transform(150, inputRange, outputRange)
  // output equals 0.5
  return <Frame>{output}</Frame>
}

#transform(inputRange, outputRange, options): (inputValue: number) => T

For improved performance, transform can pre-calculate the function that will transform a value between two ranges. Returns a function.

import * as React from "react"
import { Frame, transform } from "framer"

export function MyComponent() {
    const inputRange = [-200, -100, 100, 200]
    const outputRange = [0, 1, 1, 0]
    const convertRange = transform(inputRange, outputRange)
    const output = convertRange(-150)

    // Returns 0.5
    return <Frame>{output}</Frame>
}

inputRange: number[]

A linear series of numbers (either all increasing or decreasing).

outputRange: T[]

A series of numbers, colors or strings. Must be the same length as inputRange.

options: TransformOptions<T>

Clamp: clamp values to within the given range. Defaults to true.

returns: (inputValue: number) => T

#useTransform

#useTransform(value, transform): MotionValue

Create a MotionValue that transforms the output of another MotionValue through a function. In this example, y will always be double x.

import * as React from "react"
import { Frame, useMotionValue, useTransform } from "framer"

export function MyComponent() {
  const x = useMotionValue(10)
  const y = useTransform(x, value => value * 2)

  return <Frame x={x} y={y} />
}
value: MotionValue

The MotionValue to transform the output of.

transform: Transformer

Function that accepts the output of value and returns a new value.

returns: MotionValue

MotionValue


#Transforming Ranges

You can also use this hook to convert ranges of numeric values based on user input. In this example, we create a Frame that is horizontally draggable.

The x value starts at 0, and we’re converting the horizontal movement of the Frame from 0 - 200 into 1 - 0.5, a range that is acceptable for scale. Both the x and the scale values then get set on the Frame, too.

import * as React from "react"
import { Frame, useMotionValue, useTransform } from "framer"

export function MyComponent() {
  const x = useMotionValue(0)
  const scale = useTransform(x, [0, 200], [1, 0.5])

  return <Frame drag={"x"} x={x} scale={scale} />
}

#useAnimation

#useAnimation(): AnimationControls

Creates AnimationControls, which can be used to manually start, stop and sequence animations on one or more components.

The returned AnimationControls should be passed to the animate property of the components you want to animate.

These components can then be animated with the start method.

import * as React from 'react'
import { Frame, useAnimation } from 'framer'

export function MyComponent(props) {
   const controls = useAnimation()

   controls.start({
       x: 100,
       transition: { duration: 0.5 },
   })

   return <Frame animate={controls} />
}
returns: AnimationControls

Animation controller with start and stop methods


#Sequence

Animations can be sequenced using async functions, allowing you to chain animations with different sets of properties. The start method returns a Promise.

In this example, we’re moving a Frame four times in a row on every single tap, passing in unique properties after every previous animation has been completed.

import * as React from "react"
import { Frame, useAnimation } from "framer"

export function MyComponent(props) {
  const controls = useAnimation()

  async function sequence() {
    await controls.start({ left: 100 })
    await controls.start({ top: 100 })
    await controls.start({ left: 0 })
    await controls.start({ top: 0 })
  }

  return <Frame animate={controls} onTap={sequence} />
}

#Dynamic Start

The controls.start() method accepts a function that can return a different set of animation settings for each animating component. Each of these components will provide the function anything passed to its custom prop.

In this example, we’re passing along the index parameter to each component’s custom prop.

In the function, we use this index value to create unique delays for each Frame, which will be 0.5 for the first component, and 1 for the second. This effectively creates a controlled staggered animation.

Finally, we’re adding some default visual properties like opacity, size and background that allow us to visualize the effect.

import * as React from "react"
import { Frame, useAnimation } from "framer"

export function MyComponent(props) {
  const controls = useAnimation()

  controls.start(index => ({
    opacity: 1,
    transition: { delay: index * 0.5 },
  }))

  return (
    <Frame background="#09F">
      <Frame
        custom={0}
        opacity={0}
        animate={controls}
        size={50}
        background={"rgba(255,255,255,0.5)"}
      />
      <Frame
        custom={1}
        opacity={0}
        animate={controls}
        size={50}
        background={"rgba(255,255,255,0.25)"}
      />
    </Frame>
  )
}

The controls.start() function can optionally accept variant names.

const controls = useAnimation()
const variants = {
  visible: { opacity: 1 },
  hidden: { opacity: 0 },
}

controls.start("visible")

return <Frame variants={variants} animate={controls} />

#Stopping Animations

All currently active animations can be stopped with animation.stop().

controls.stop()

#useCycle

#useCycle(c1, c2, ...): [currentState, cycleState]

Cycles through a series of visual properties. Can be used to toggle between or cycle through animations. It works similar to useState in React. It is provided an initial array of possible states, and returns an array of two arguments.

import * as React from "react"
import { Frame, useCycle } from "framer"

export function MyComponent() {
  const [x, cycleX] = useCycle(0, 50, 100)

  return (
    <Frame
      animate={{ x: x }}
      onTap={() => cycleX()}
     />
   )
}
items: T[]

items to cycle through

returns: CycleState<T>

[currentState, cycleState]


#Cycling between Variants

The useCycle is often used to animate between a Frame’s variants or visual states.

In this example, we’ve created an object with three variants, set up a cycle containing each variant's name, and then pointed our Frame’s animate prop to the cycle's current value.

Tapping on the Frame will trigger a cycle, causing the Frame to animate to the variant name provided by the cycle’s new current value.

import * as React from "react"
import { Frame, useCycle } from "framer"

export function MyComponent() {
  const variants = {
    green: { background: "#1ea463" },
    yellow: { background: "#fecd45" },
    red: { background: "#de5347" },
  }

  const [current, cycle] = useCycle(
    "green",
    "yellow",
    "red"
  )

  return (
    <Frame
      variants={variants}
      animate={current}
      onTap={() => cycle()}
    />
  )
}

#Cycling to a Specific Value

You can jump to a specific value in a cycle by calling useCycle’s returned function with the index of the desired value.

As in the last example, tapping on the Frame will cycle between three values. However in this example, mousing out from the Frame will reset the cycle to its first value, "green".

import * as React from "react"
import { Frame, useCycle } from "framer"

export function MyComponent() {
  const variants = {
    green: { background: "#1ea463" },
    yellow: { background: "#fecd45" },
    red: { background: "#de5347" },
  }

  const [current, cycle] = useCycle(
    "green",
    "yellow",
    "red"
  )

  return (
    <Frame
      variants={variants}
      animate={current}
      onTap={() => cycle()}
      onMouseLeave={() => cycle(0)}
    />
  )
}

#useMotionValue

#useMotionValue(initial): MotionValue<T>

Creates a MotionValue to track the state and velocity of a value.

Usually, these are created automatically. For advanced use-cases, like use with useTransform, you can create MotionValues externally and pass them into the animated component via the style prop.

export function MyComponent() {
  const scale = useMotionValue(1)

  return <Frame scale={scale} />
}
initial: T

The initial state.

returns: MotionValue<T>

#useViewportScroll

#useViewportScroll(): ScrollMotionValues

Provides MotionValues that update when the viewport scrolls:

  • scrollX — Horizontal scroll distance in pixels.
  • scrollY — Vertical scroll distance in pixels.
  • scrollXProgress — Horizontal scroll progress between 0 and 1.
  • scrollYProgress — Vertical scroll progress between 0 and 1.
import * as React from "react"
import {
  Frame,
  useViewportScroll,
  useTransform
} from "framer"

export function MyComponent() {
  const { scrollYProgress } = useViewportScroll()
  return <Frame scaleX={scrollYProgress} />
}
returns: ScrollMotionValues