# Hyprland Animation System Explained: How AnimatedVariable Powers Smooth Transitions

> Discover Hyprland's animation system and its AnimatedVariable class. Learn how it creates smooth transitions and repaints windows efficiently.

- Repository: [Hypr Development/Hyprland](https://github.com/hyprwm/Hyprland)
- Tags: deep-dive
- Published: 2026-07-23

---

**Hyprland's animation system uses the `AnimatedVariable` template class to interpolate values over time according to easing curves, triggering damage callbacks that repaint specific window regions on each global tick.**

The Hyprland compositor delivers its signature smooth visual effects—window movements, scaling transformations, opacity fades, and border-glow transitions—through a lightweight animation framework defined in the `hyprutils` library. Within the Hyprland source code, this framework is wrapped by compositor-specific types that attach context about which window, workspace, or layer surface requires repainting when values change.

## Core Components of the Animation Framework

The Hyprland animation system is built on a layered architecture that separates the generic interpolation engine from the compositor-specific damage tracking.

### CGenericAnimatedVariable (hyprutils)

The foundation is `CGenericAnimatedVariable<VarType>`, defined in [[`hyprutils/animation/AnimatedVariable.hpp`](https://github.com/hyprwm/Hyprland/blob/main/hyprutils/animation/AnimatedVariable.hpp)](https://github.com/hyprutils/hyprutils/blob/main/include/hyprutils/animation/AnimatedVariable.hpp). This template class stores a value of any type (`float`, `Vector2D`, etc.) and interpolates it over time according to an `SAnimationPropertyConfig`. It emits a **tick callback** whenever the interpolated value changes, allowing the compositor to schedule repaints.

### CAnimatedVariable (Hyprland Wrapper)

Hyprland defines a specialized alias in [[`src/helpers/AnimatedVariable.hpp`](https://github.com/hyprwm/Hyprland/blob/main/src/helpers/AnimatedVariable.hpp)](https://github.com/hyprwm/Hyprland/blob/main/src/helpers/AnimatedVariable.hpp):

```cpp
using CAnimatedVariable = Hyprutils::Animation::CGenericAnimatedVariable<VarType, SAnimationContext>;

```

This alias enriches the generic variable with an **`SAnimationContext`** that identifies *where* the change occurred (window, workspace, or layer surface) and specifies how to damage the scene through the `eAVarDamagePolicy` enum.

### CHyprAnimationManager

The [[`src/animation/AnimationManager.hpp`](https://github.com/hyprwm/Hyprland/blob/main/src/animation/AnimationManager.hpp)](https://github.com/hyprwm/Hyprland/blob/main/src/animation/AnimationManager.hpp) file houses `CHyprAnimationManager`, which owns a `hyprutils::Animation::CAnimationManager`. This central manager schedules ticks, updates global time, and provides the `createAnimation` helper that constructs `CAnimatedVariable` instances and attaches the proper damage policy to each.

### ViewAnimationController

For higher-level coordination, [[`src/animation/controller/ViewAnimationController.hpp`](https://github.com/hyprwm/Hyprland/blob/main/src/animation/controller/ViewAnimationController.hpp)](https://github.com/hyprwm/Hyprland/blob/main/src/animation/controller/ViewAnimationController.hpp) groups multiple `CAnimatedVariable`s into a **`SAnimatedMovement`** struct. This controller manages related properties (position, size, alpha) simultaneously for a given view, ensuring synchronized animation updates.

### Animated View Mix-ins

Concrete view classes inherit animation capabilities through mix-ins like `GeometricAnimated`, found in [[`src/desktop/view/types/GeometricAnimated.hpp`](https://github.com/hyprwm/Hyprland/blob/main/src/desktop/view/types/GeometricAnimated.hpp)](https://github.com/hyprwm/Hyprland/blob/main/src/desktop/view/types/GeometricAnimated.hpp). These classes expose animated properties as part of the view hierarchy, allowing `CWindow` and `CLayerSurface` objects to store and update animated state directly.

## How AnimatedVariable Creates Animations

Creating an animation in Hyprland follows a strict four-step flow that connects the generic interpolation engine to the compositor's damage system.

1. **Select a damage policy** – The `eAVarDamagePolicy` enumeration determines what region must be redrawn when the variable changes. Options include `AVARDAMAGE_ENTIRE` (full window), `AVARDAMAGE_NONE` (no additional damage), or specialized modes for borders and shadows.

2. **Call `CHyprAnimationManager::createAnimation`** – This template method accepts the target value, a smart pointer to hold the resulting `CAnimatedVariable`, an `SAnimationPropertyConfig` (duration, easing curve), and an optional context reference (`PHLWINDOW`, `PHLWORKSPACE`, `PHLLS`).

3. **Variable registration** – The manager constructs a `CAnimatedVariable` and registers it with the underlying `CAnimationManager`, which begins tracking the interpolation timeline.

4. **Global tick advancement** – On each call to `CHyprAnimationManager::tick`, the manager advances all active variables, triggers their callbacks, and marks the affected regions for repaint based on the selected damage policy.

## Practical Implementation Examples

### Window Opacity Fade

To animate a window fading to transparent over 300ms:

```cpp
PHLWINDOW pWin = /* window pointer */;
float finalOpacity = 0.0f;

auto pConfig = std::make_shared<Hyprutils::Animation::SAnimationPropertyConfig>();
pConfig->duration = 300;  // milliseconds
pConfig->easing = Hyprutils::Animation::EASE_LINEAR;

PHLANIMVAR<float> pOpacityVar;

Animation::mgr()->createAnimation(
    finalOpacity,
    pOpacityVar,
    pConfig,
    pWin,                 // context for damage tracking
    AVARDAMAGE_ENTIRE);   // repaint entire window each tick

```

As the animation runs, `pOpacityVar` interpolates from the current opacity to `0.0f`, triggering window repaints until completion.

### Position Animation with Bounce Easing

To move a window with a bounce effect:

```cpp
PHLWINDOW pWin = /* window pointer */;
Vector2D targetPos = {1920.f, 1080.f};

auto pConfig = std::make_shared<Hyprutils::Animation::SAnimationPropertyConfig>();
pConfig->duration = 500;
pConfig->easing = Hyprutils::Animation::EASE_OUT_BOUNCE;

PHLANIMVAR<Vector2D> pPosVar;

Animation::mgr()->createAnimation(
    targetPos,
    pPosVar,
    pConfig,
    pWin,
    AVARDAMAGE_NONE);    // position changes handled by existing damage logic

```

The `Vector2D` specialization smoothly moves the window while the bounce curve adds an overshoot effect.

### View Controller Integration

Inside a view class, animated properties are typically pre-declared and updated through the controller:

```cpp
void CWindow::animateScale(const Vector2D& newScale) {
    auto pConfig = std::make_shared<Hyprutils::Animation::SAnimationPropertyConfig>();
    pConfig->duration = 200;
    pConfig->easing = Hyprutils::Animation::EASE_IN_OUT_QUAD;

    // m_sScale is a CAnimatedVariable<Vector2D> owned by ViewAnimationController
    Animation::mgr()->createAnimation(
        newScale,
        m_sScale,
        pConfig,
        this,               // view context
        AVARDAMAGE_ENTIRE);
}

```

The controller automatically updates the window's transformation matrix each tick, abstracting the interpolation details from the view logic.

## Key Source Files

Understanding the complete animation flow requires examining these specific files in the Hyprland repository:

- **[`src/helpers/AnimatedVariable.hpp`](https://github.com/hyprwm/Hyprland/blob/main/src/helpers/AnimatedVariable.hpp)** – Defines `eAVarDamagePolicy`, `SAnimationContext`, and the `CAnimatedVariable` alias used throughout the compositor.
- **[`src/animation/AnimationManager.hpp`](https://github.com/hyprwm/Hyprland/blob/main/src/animation/AnimationManager.hpp)** – Contains `CHyprAnimationManager`, which bridges the generic animation library with Hyprland's damage system.
- **[`src/animation/controller/ViewAnimationController.hpp`](https://github.com/hyprwm/Hyprland/blob/main/src/animation/controller/ViewAnimationController.hpp)** – Groups per-view animated variables into the `SAnimatedMovement` struct for coordinated updates.
- **[`src/desktop/view/types/GeometricAnimated.hpp`](https://github.com/hyprwm/Hyprland/blob/main/src/desktop/view/types/GeometricAnimated.hpp)** – Demonstrates the mix-in pattern for adding animated geometry to view classes.
- **[`src/desktop/view/Window.hpp`](https://github.com/hyprwm/Hyprland/blob/main/src/desktop/view/Window.hpp)** – Real-world usage showing `CAnimatedVariable` instances for border angles, shadow opacity, and window alpha.

## Summary

- **Hyprland's animation system** relies on `hyprutils` for generic value interpolation, wrapped by `CAnimatedVariable` to add compositor context.
- **`SAnimationContext`** and **`eAVarDamagePolicy`** connect animated values to the damage system, ensuring efficient repaints of only affected regions.
- **`CHyprAnimationManager`** orchestrates the global tick, advancing all active interpolations and triggering callbacks.
- **ViewAnimationController** provides high-level grouping of related animations (position, size, alpha) for window management.
- The template-based design allows animating any value type (`float`, `Vector2D`, `CColor`) with configurable duration and easing curves.

## Frequently Asked Questions

### What is the difference between CGenericAnimatedVariable and CAnimatedVariable?

`CGenericAnimatedVariable` is the base template class from the `hyprutils` library that handles value interpolation and stores animation configuration. `CAnimatedVariable` is a Hyprland-specific alias that specializes the template with `SAnimationContext`, adding a pointer to the window, workspace, or layer surface that owns the animation, plus the damage policy for repaint scheduling.

### How does Hyprland know which part of the screen to repaint during an animation?

Each `CAnimatedVariable` carries an **`eAVarDamagePolicy`** set during creation via `createAnimation()`. When the variable ticks and updates its value, the animation manager checks this policy—options include `AVARDAMAGE_ENTIRE` for full window redraws, `AVARDAMAGE_BORDER` for border-only updates, or `AVARDAMAGE_NONE` when the change doesn't require explicit damage.

### Can AnimatedVariable handle complex types like colors or vectors?

Yes. `CAnimatedVariable` is a template that supports any type implementing the necessary arithmetic operators. The Hyprland codebase uses specializations for `float` (opacity), `Vector2D` (position, size), and `CColor` (border colors). The interpolation logic automatically applies to each component of the complex type.

### Where are animation durations and easing curves configured?

Animation properties are defined in **`SAnimationPropertyConfig`** objects passed to `createAnimation()`. These configurations specify the duration in milliseconds and the easing function (such as `EASE_LINEAR`, `EASE_OUT_BOUNCE`, or `EASE_IN_OUT_QUAD`). Hyprland typically loads these values from user configuration files and applies them when creating animations for window events.