zui docs v0.0.5
GitHub ↗
Zui guide · 05

Animation and effects

Add native transitions, sequenced motion, shaders, particles, shadows, and GPU-backed treatments.

Updated for Zui 0.0.5·2 minutes read

Animate a reactive patch

Attach an animation to a binding when a state change should transition a native property instead of replacing it immediately.

require "zui"

Zui.app do
  state :panel_visible, true

  app :main, title: "Animated binding", width: 640, height: 420 do
    column spacing: 16 do
      panel = card padding: 24 do
        label "Native transition"
      end

      bind(
        panel,
        :opacity,
        animation: animation(duration: 280, easing: :out_cubic)
      ) do
        state.panel_visible ? 1.0 : 0.0
      end

      button "Toggle panel" do
        state.panel_visible = !state.panel_visible
      end
    end
  end
end

Sequence deliberate motion

animate_sequence converts ordered steps into native animation tracks. Trigger the sequence from an event when the application is already running.

require "zui"

Zui.app do
  app :main, title: "Motion sequence", width: 640, height: 420 do
    column spacing: 16 do
      hero = card padding: 24, opacity: 0.0, scale: 0.9 do
        label "Deployment ready", size: 24, bold: true
      end

      button "Reveal" do
        animate_sequence hero, [
          { to: { opacity: 1.0, scale: 1.0 }, duration: 260 },
          { to: { rotation: 2 }, duration: 90, pause: 40 },
          { to: { rotation: 0 }, duration: 140 }
        ]
      end
    end
  end
end

Use the native GPU pipeline

Effects are containers, so their child becomes the source texture. Shader effects accept precompiled QSB shaders and bounded runtime uniforms.

require "zui"

Zui.app do
  app :main, title: "GPU effects", width: 760, height: 520 do
    column spacing: 20 do
      glow color: "#b7ff5a", blur: 0.7, opacity: 0.8 do
        card padding: 24, color: "#111114" do
          label "Signal locked"
        end
      end

      shader_effect "assets/shaders/plasma.frag.qsb",
        width: 640,
        height: 300,
        running: true,
        intensity: 0.85
    end
  end
end