Gesture Animations

With the whileHover, whileTap, and whileDrag gesture animations, you can quickly make layers interactive. With just one line of code, you add an automatic animation between two states.

📘 The Framer Code Guide – 💫 Gesture Animations

 

While Hover

Here’s an override example: You give whileHover an object with the properties you want to animate, just like we did earlier with animate.

export function WhileHover(Component): ComponentType {
    return (props) => {
        return <Component {...props} whileHover={{ scale: 0.8 }} />
    }
}
C01 – WhileHover

The frame shrinks to 80 percent of its size when you hover over it, and it grows again when the hover ends.

With one line of code, you’ve added two animations:

  • one that happens when the pointer is over the frame;
  • and a reverse animation that runs when the pointer leaves the frame.

Animation helpers, whileHover

While Tap

The second one, whileTap, works the same, but for tap gestures.

export function WhileTap(Component): ComponentType {
    return (props) => {
        return (
            <Component
                {...props}
                whileTap={{ scale: 0.8 }}
                transition={{ duration: 0.5 }}
            />
        )
    }
}
C02 – WhileTap

And just like with animate, you can tweak these animations by adding transition settings. For example, here, the frame will take its sweet little time of half a second to shrink when you press down. And the same thing happens when you release; the grow animation also has a duration of 0.5.

Animation helpers, whileTap

While Drag

Framer Motion 3 added a whileDrag interaction. It works as you would expect.

Naturally, you can combine these gesture animations. Here we have a draggable frame with whileHover, whileTap, and whileDrag:

export function WhileDrag(Component): ComponentType {
    return (props) => {
        return (
            <Component
                {...props}
                drag
                whileHover={{ opacity: 1 }}
                whileTap={{
                    opacity: 1,
                    scale: 1.05,
                    boxShadow: "0px 5px 8px #037",
                }}
                whileDrag={{ scale: 1.1, boxShadow: "0px 10px 16px #037" }}
                transition={{ duration: 0.6 }}
            />
        )
    }
}
C03 – WhileDrag

  • whileHover — I gave the frame an opacity of 70% on the canvas, which changes to 100% when you hover over it.
  • whileTap — Tapping the frame makes it grow slightly (scale of 105%) and gives it a shadow.
  • whileDrag — Once you start dragging, it seems to float a bit higher above the surface because of its scale of 110% and a larger boxShadow.

(The whileTap also changes the opacity to 1. This is for touch devices, on which a whileHover is not triggered.)

All three animations have a duration of 0.6 seconds, a bit longer than the default 0.3.

whileDrag

While Focus

Framer Motion 3.1 added whileFocus. Only HTML input elements can have a focus state, so you have to use a <motion.input>.

I tried to make something that’s impossible with CSS’s :focus pseudo-class and arrived at this crazy background animation that cycles through keyframes of different gradients.

export function C04WhileFocusFM() {
  return (
    <motion.input
      style={{
        // width, background, etc.
      }}
      whileFocus={{
        background: [
          "linear-gradient(to right, #f0f -200%, #0ff -100%, #f0f 0%, #0ff 100%)",
          "linear-gradient(to right, #f0f -100%, #0ff 0%, #f0f 100%, #0ff 200%)",
          "linear-gradient(to right, #f0f 0%, #0ff 100%, #f0f 200%, #0ff 300%)",
        ],
      }}
      transition={{
        background: {
          duration: 2,
          repeat: Infinity,
          ease: "linear",
          from:
            "linear-gradient(to right, #fff -200%, #fff -100%, #fff 0%, #fff 100%)",
        },
      }}
    />
  )
}
C04 – WhileFocus

(Apparently, adding the from value keeps it from continuing to animate (in Framer) when the input field has already lost focus.)

whileFocus, from
:focus

whileFocus with validation example

In the tweet announcing whileFocus, Matt Perry added this example that gives a visual indication of the field’s validation status:

Leave a space in the text to see the error state — Open in new tab

  • Blue: Neutral
  • Green: Valid value entered
  • Red: Invalid value entered (no spaces allowed!)

It has an onBlur() event (called when the element loses focus) that changes a validity state, which, in turn, defines which color is used for the boxShadow around the field.

onblur




Leave a Reply