Framer X » Archive » Animations (pre X22) » Delaying an animation

Delaying an animation

Warning: These pages are from before the launch of Framer X22 and are about the older animation API. These animations will still work in the current version of Framer X but are officially deprecated. Learn about the new animation API here.

Say we want the use this same ‘move down, then back up’ animation as in Chaining animations, but with a slight pause between the two movements.

There are two ways to do this, you use JavaScript’s setTimeout() function, or you insert a fake, dummy animation between the two real animations.

Using setTimeout()

The more official way would be to use JavaScript’s setTimeout() method.

You give setTimeout() a function, with inside it everything that should happen after the delay, plus a duration for that delay.

So it actually only takes two parameters:

setTimeout(«a_function», «a_delay_in_milliseconds»);

Below I give if an arrow function. The function doesn’t need to have a name, so it looks like this:

() => {
  animate(data.yPositionLeftBlock, startPosition);
}

… and then the delay: 1500.

export const DelayedAnimation_1: Override = props => {
  data.yPositionLeftBlock.set(props.top);
  const startPosition = props.top;
  return {
    top: data.yPositionLeftBlock,
    onTap() {
      animate(data.yPositionLeftBlock, 645).finished;
      setTimeout(() => {
        animate(data.yPositionLeftBlock, startPosition);
      }, 1500);
    }
  };
};
download this project

The animations didn’t get any specified duration, so they’ll have the default length of 1 second: 1000 milliseconds. So with this delay of 1500 milliseconds, the second animation will start half a second after the first one.

Using a dummy animation

This is a neat trick.

You just create an extra Animatable that is not connected to any property (here: dummy), and you animate it, with the duration that you want the delay to be (here: 0.5).

export const DelayedAnimation_2: Override = props => {
  data.yPositionRightBlock.set(props.top);
  const startPosition = props.top;
  return {
    top: data.yPositionRightBlock,
    async onTap() {
      await animate(data.yPositionRightBlock, 645).finished;
      const dummy = Animatable(0);
      await animate.ease(dummy, 1, { duration: 0.5 }).finished;
      animate(data.yPositionRightBlock, startPosition);
    }
  };
};

By using async / await / finished (like we did in Chaining animations), you then let the animations wait for each other.

(By the way, here I’m animating from 0 to 1, but you can use any values, and the name also doesn’t have to be dummy.)

This can be a bit shorter. You actually don’t need to create a variable (dummy) for the Animatable. You can just write Animatable inline because you don’t need to refer to it anywhere else.

export const DelayedAnimation_2: Override = props => {
  data.yPositionRightBlock.set(props.top);
  const startPosition = props.top;
  return {
    top: data.yPositionRightBlock,
    async onTap() {
      await animate(data.yPositionRightBlock, 645).finished;
      await animate.ease(Animatable(0), 1, { duration: 0.5 }).finished;
      animate(data.yPositionRightBlock, startPosition);
    }
  };
};
download this project

Leave a Reply