Effect

An entrance that combines fade, blur, slide and zoom on load or when elements scroll into view.

<script setup lang="ts">
import { RepeatIcon } from '@hugeicons/core-free-icons'
import { HugeiconsIcon } from '@hugeicons/vue'
import { Effects } from '@animate-ui/vue/primitives/effects/effect'
import { ref } from 'vue'
import { Button } from '@/components/ui/button'

withDefaults(
  defineProps<{
    delay?: number | string,
    blur?: boolean | string,
    slide?: boolean | string,
    fade?: boolean | string,
    zoom?: boolean | string
  }>(),
  { delay: 0, blur: true, slide: true, fade: true, zoom: true },
)

const ITEMS = ['Design', 'Build', 'Ship']
const run = ref(0)
</script>

<template>
  <div class="flex flex-col items-center gap-6">
    <div :key="`${run}-${delay}-${blur}-${slide}-${fade}-${zoom}`" class="flex gap-3">
      <Effects
        :hold-delay="100"
          :delay="Number(delay)"
          :blur="blur === true || blur === 'true'"
          :slide="slide === true || slide === 'true'"
          :fade="fade === true || fade === 'true'"
          :zoom="zoom === true || zoom === 'true'"
      >
        <div
          v-for="item in ITEMS"
          :key="item"
          class="flex h-20 w-24 items-center justify-center rounded-xl bg-accent text-sm font-medium"
        >
          {{ item }}
        </div>
      </Effects>
    </div>
    <Button variant="outline" size="sm" @click="run++">
      <HugeiconsIcon :icon="RepeatIcon" :stroke-width="2" />
      Replay
    </Button>
  </div>
</template>

Installation

npm install @animate-ui/vue motion-v
pnpm add @animate-ui/vue motion-v
yarn add @animate-ui/vue motion-v
bun add @animate-ui/vue motion-v

Usage

<script setup lang="ts">
import { Effect, Effects } from '@animate-ui/vue/primitives/effects/effect';
import Card from './Card.vue';
</script>

<template>
  <Effect fade blur slide zoom>
    <h1>Animated primitives for Vue</h1>
  </Effect>
  <!-- Staggered: each child starts 100ms after the previous one. -->
  <Effects :hold-delay="100" fade blur slide zoom>
    <Card />
    <Card />
    <Card />
  </Effects>
</template>

With as-child, the animation is applied to your element instead of a wrapping div.

Animation

  • Pick any combination of fade, blur, slide and zoom. true uses each effect's defaults; an object customizes it.
  • Everything animates together on one spring (stiffness 200, damping 20). Slide (x / y) and zoom (scale) are hardware-accelerated transforms.
  • Under reduced motion, there is no travel or scale: the fade and the blur still play.
  • in-view waits for the element to scroll into view, once by default.
  • <AnimateUIProvider :tempo> paces the default spring.

API Reference

Effect

PropTypeDefault
as-child?
booleanfalse
fade?
boolean | { initialOpacity?: number; opacity?: number }false
blur?
boolean | { initialBlur?: number; blur?: number }false
slide?
boolean | { direction?: 'up' | 'down' | 'left' | 'right'; offset?: number }false
zoom?
boolean | { initialScale?: number; scale?: number }false
delay?
number0
transition?
Transition{ type: 'spring', stiffness: 200, damping: 20 }
in-view?
booleanfalse
in-view-once?
booleantrue
in-view-margin?
string'0px'
...props?
HTMLMotionProps<'div'>-

Effects

Wraps each child in an Effect, delaying each one a little more than the previous.

PropTypeDefault
#default
slot-
hold-delay?
number0
...props?
EffectProps-

Built by Skyleen. The source code is available on GitHub.

Last updated: 10/23/2026