Topography Background

Living contour lines, like a map of a terrain that slowly breathes. A hill rises under the cursor and a click sends a wave across.

<script setup lang="ts">
import TopographyBackground from '@/components/animate-ui/backgrounds/topography/TopographyBackground.vue'

withDefaults(
  defineProps<{
    lineColor?: string
    levels?: number | string
    speed?: number | string
    scale?: number | string
    peak?: number | string
    interactive?: boolean | string
  }>(),
  { lineColor: '', levels: 16, speed: 1, scale: 1, peak: 1, interactive: true },
)
</script>

<template>
  <TopographyBackground
    class="absolute inset-0 bg-[radial-gradient(ellipse_at_center,#fafafa_0%,#f0f0f0_100%)] text-neutral-500 dark:bg-[radial-gradient(ellipse_at_center,#171717_0%,#000_100%)] dark:text-neutral-400"
    :line-color="lineColor || undefined"
    :levels="Number(levels)"
    :speed="Number(speed)"
    :scale="Number(scale)"
    :peak="Number(peak)"
    :interactive="interactive === true || interactive === 'true'"
  />
</template>

Installation

npx shadcn-vue@latest add https://animate-ui.com/r/vue/backgrounds-topography.json
pnpm dlx shadcn-vue@latest add https://animate-ui.com/r/vue/backgrounds-topography.json
yarn dlx shadcn-vue@latest add https://animate-ui.com/r/vue/backgrounds-topography.json
bun x shadcn-vue@latest add https://animate-ui.com/r/vue/backgrounds-topography.json

Usage

<script setup lang="ts">
import TopographyBackground from '@/components/animate-ui/backgrounds/topography/TopographyBackground.vue';
</script>

<template>
  <section class="relative h-[480px] overflow-hidden">
    <TopographyBackground class="absolute inset-0 text-neutral-500" />
  </section>
</template>

Animation

  • The terrain is a field of gradient noise drawn as contour lines, like a topographic map: every fifth line is an index contour, thicker and brighter. The noise drifts slowly through time (speed), so the relief keeps reshaping itself.
  • On mount, the relief rises from flat ground in 1.8s on an ease-out: the lines bloom out from the middle level.
  • Under the cursor, a peak rises on a spring and follows it (transition), its rings tightening towards the summit (peak). Leaving the container lets it sink back.
  • A click (or a tap) drops a wave: a crest and a trough travel out from the point in 2.6s, bunching the lines as they pass, and fade away.
  • The lines take the container's text color, or line-color. They're drawn with WebGL, pixel by pixel on the GPU (at most twice the device pixel ratio): no grid, so they glide without stepping and redraw on every frame, even at 120Hz and more. Where WebGL is missing, a canvas draws them as smooth curves instead.
  • The loop pauses off screen and while the tab is hidden.
  • Under reduced motion, the terrain is a still map: no drift, no peak, no wave.

API Reference

TopographyBackground

PropTypeDefault
line-color?
string-
levels?
number16
speed?
number1
scale?
number1
peak?
number1
interactive?
booleantrue
transition?
SpringOptions{ stiffness: 120, damping: 20 }
...attrs?
HTMLAttributes-

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

Last updated: 10/23/2026