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 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 rangeA = [0, 200]
   const rangeB = [0, 1]
   const output = transform(100, rangeA, rangeB)

   // 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 or strings. 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 rangeA = [-200, -100, 100, 200]
    const rangeB = [0, 1, 1, 0]
    const convertRange = transform(rangeA, rangeB)
    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. Here, the y value will always be twice the x value.

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 style={{ x, 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 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

The useAnimation hook returns AnimationControls, which can be used to manually start, stop and sequence animations on one or more Frames.

The returned AnimationControls should be passed as the animate property of the Frame. It can be passed to any number of Frames. These Frames can be animated with the start method. It accepts the same properties as the animate property.


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

A function can be passed to start to return a different set of animation settings for every animating component. Each component will provide the function with its properties.

In this example, we’re passing along the i parameter, which we set on the components manually. It’s used 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(({ i }) => ({
    opacity: 1,
    transition: { delay: i * 0.5 },
  }))

  return (
    <Frame background="#09F">
      <Frame
        i={0}
        opacity={0}
        animate={controls}
        size={50}
        background={"rgba(255,255,255,0.5)"}
      />
      <Frame
        i={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")

#Stopping Animations

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

controls.stop()

#useCycle

#useCycle(items): CycleState<T>

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]


#Cycle with Animate

Cycle can also be used with the animate property. Here we’re passing along objects with multiple properties, instead of single property. Then, instead of referencing a specific property on animate, we’re just referencing the object, and cycling between the states with cycleAnimate.

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

export function MyComponent() {
  const [animate, cycle] = useCycle([
    { rotate: 90, scale: 0.5 },
    { rotate: 0, scale: 1 },
  ])

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

#Change Initial State

By default, the initial state is the first item in the provided array. By passing a different index as the second argument, useCycle can start on a different item in the array. Please note that the index value of an array starts at 0.

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

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

  return <Frame animate={{ x }} onClick={() => cycleX()} />
}

#Cycle to a Specific State

The returned cycleState function, by default, cycles to the next item in the provided array. Optionally, it accepts an index that will cycle to a specific item in the array. In this example, we’ve used variants and passed along the names of each variant, instead of directly including the properties.

Here, it will always cycle to the off state, because we’ve passed along the index of 0 to the cycleToggle function. If we were to remove it, it would cycle between off and on again.

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

export function MyComponent() {
  const variants = {
    off: { opacity: 0.5 },
    on: { opacity: 1.0 },
  }

  const [toggle, cycleToggle] = useCycle(["off", "on"], 1)

  return (
    <Frame
      variants={variants}
      animate={toggle}
      onClick={() => cycleVariant(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 style={{ scale: scale }} />
}
initial: T

The initial state.

returns: MotionValue<T>

#useViewportScroll

#useViewportScroll(): ScrollMotionValues

Provides a MotionValue that updates when the viewport scrolls. Returns the following four values.

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

export function MyComponent() {
  const { scrollYProgress } = useViewportScroll()
  const scaleX = useTransform(scrollYProgress, [0, 1], [0, 1])

  return <Frame style={{ scaleX }} />
}
returns: ScrollMotionValues