A button that flips over on hover to reveal its back face.
Installation
Usage
<script setup lang="ts">
import FlipButton from '@/components/animate-ui/buttons/flip/FlipButton.vue';
import FlipButtonBack from '@/components/animate-ui/buttons/flip/FlipButtonBack.vue';
import FlipButtonFront from '@/components/animate-ui/buttons/flip/FlipButtonFront.vue';
</script>
<template>
<FlipButton from="top">
<FlipButtonFront>Subscribe</FlipButtonFront>
<FlipButtonBack>It's free</FlipButtonBack>
</FlipButton>
</template>Animation
- On hover, the front face rotates away (90°, sliding half its height or width) and fades out while the back face rotates in from
from, on a bouncy spring (stiffness: 280, damping: 20) that swings past the end before settling. Leaving flips it back. - The faces are stacked in the same grid cell: the button takes the size of the larger one.
- Pressing scales the button to
tap-scaleon Motion's spring for scale (stiffness: 550, damping: 30). <AnimateUIProvider :tempo>paces the default springs.- Under reduced motion, the faces crossfade without rotating or sliding, and the button doesn't scale.
API Reference
FlipButton
| Prop | Type | Default |
|---|---|---|
from? | 'top' | 'bottom' | 'left' | 'right' | 'top' |
tap-scale? | number | 0.97 |
transition? | Transition | { type: 'spring', stiffness: 550, damping: 30, restSpeed: 10 } |
as-child? | boolean | false |
...props? | HTMLMotionProps<'button'> | - |
FlipButtonFront
| Prop | Type | Default |
|---|---|---|
transition? | Transition | { type: 'spring', stiffness: 280, damping: 20 } |
as-child? | boolean | false |
...props? | HTMLMotionProps<'span'> | - |
FlipButtonBack
| Prop | Type | Default |
|---|---|---|
transition? | Transition | { type: 'spring', stiffness: 280, damping: 20 } |
as-child? | boolean | false |
...props? | HTMLMotionProps<'span'> | - |
useFlipButton
Returns { from, isVertical, rotateAxis } inside a FlipButton.