ShaderAnimatedControl 12.0.0

dotnet add package ShaderAnimatedControl --version 12.0.0
                    
NuGet\Install-Package ShaderAnimatedControl -Version 12.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="ShaderAnimatedControl" Version="12.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="ShaderAnimatedControl" Version="12.0.0" />
                    
Directory.Packages.props
<PackageReference Include="ShaderAnimatedControl" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add ShaderAnimatedControl --version 12.0.0
                    
#r "nuget: ShaderAnimatedControl, 12.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package ShaderAnimatedControl@12.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=ShaderAnimatedControl&version=12.0.0
                    
Install as a Cake Addin
#tool nuget:?package=ShaderAnimatedControl&version=12.0.0
                    
Install as a Cake Tool

Lottie

CI Docs

A collection of animation controls for Avalonia including Lottie animation player and reusable base controls for custom animations.

Packages

Package NuGet Downloads Description
Lottie NuGet NuGet downloads An lottie animation player control for Avalonia.
AnimationControl NuGet NuGet downloads Reusable animation control base class for Avalonia applications.
CompositionAnimatedControl NuGet NuGet downloads Reusable composition-backed Skia control for static and animated rendering in Avalonia.
ShaderAnimatedControl NuGet NuGet downloads Reusable Skia shader-based animated control for Avalonia.

Documentation

Project documentation is published with Lunet at wieslawsoltes.github.io/Lottie.

To build the site locally:

./build-docs.sh

To preview the site with Lunet watch mode:

./serve-docs.sh

Controls

Lottie Control

A lottie animation player control for Avalonia.

Installation:

dotnet add package Lottie

Basic Usage:

<Lottie Path="/Assets/LottieLogo1.json" />

AnimationControl

A reusable base class for creating custom animation controls in Avalonia. This control provides a simple animation frame loop that you can override to create custom animations.

Installation:

dotnet add package AnimationControl

Basic Usage:

public class MyAnimationControl : AnimationControl
{
    protected override void OnAnimationFrame(TimeSpan now, TimeSpan last)
    {
        // Your animation logic here
        // The control will automatically invalidate and request the next frame
        var deltaTime = now - last;
        // Update your animation state based on deltaTime
    }

    public override void Render(DrawingContext context)
    {
        base.Render(context);
        // Your custom rendering logic here
    }
}

Key Features:

  • Automatic animation frame loop when attached to visual tree
  • Override OnAnimationFrame(TimeSpan now, TimeSpan last) for animation logic
  • Automatic visual invalidation after each frame
  • Lightweight base for simple custom animations

CompositionAnimatedControl

A reusable base control for Skia rendering with optional animation using Avalonia's composition layer. It is override-first: subclass it and override a small set of virtual methods.

Installation:

dotnet add package CompositionAnimatedControl

Mode 1: Animated rendering (time-based or per-frame update)

You can animate by normalizing elapsed time into a loop, or by updating your state every frame and rendering using that state.

Example 1: simple time-based animation (used in demo tabs)

public sealed class SimpleTimelineControl : CompositionAnimatedControl
{
    protected override Size OnGetSourceSize() => new Size(300, 200);
    protected override NormalizeResult OnNormalizeElapsed(TimeSpan elapsed)
    {
        var loop = TimeSpan.FromSeconds(2);
        if (loop <= TimeSpan.Zero) return new NormalizeResult(elapsed, false);
        var remainder = TimeSpan.FromTicks(elapsed.Ticks % loop.Ticks);
        var looped = elapsed >= loop;
        return new NormalizeResult(remainder, looped);
    }
    protected override void OnRender(SKCanvas canvas, Rect rect, TimeSpan t, bool running)
    {
        canvas.Clear(SKColors.White);
        var progress = (float)(t.TotalSeconds / 2.0);
        var x = (float)(rect.X + rect.Width * progress);
        using var paint = new SKPaint { Color = SKColors.CornflowerBlue, IsAntialias = true };
        canvas.DrawCircle(x, (float)rect.Center.Y, 20, paint);
    }
}

Example 2: bouncing ball with per-frame update and stretch-respecting drawing.

public sealed class BouncingBallControl : CompositionAnimatedControl
{
    private const float LogicalWidth = 300f;
    private const float LogicalHeight = 200f;
    private const float Radius = 18f;
    private SKPoint _position = new(40, 40);
    private SKPoint _velocity = new(120f, 90f);

    protected override Size OnGetSourceSize() => new Size(LogicalWidth, LogicalHeight);
    protected override NormalizeResult OnNormalizeElapsed(TimeSpan ts) => new NormalizeResult(ts, false);
    protected override void OnUpdate(TimeSpan delta)
    {
        var dt = (float)delta.TotalSeconds;
        _position.X += _velocity.X * dt;
        _position.Y += _velocity.Y * dt;
        if (_position.X - Radius < 0) { _position.X = Radius; _velocity.X = Math.Abs(_velocity.X); }
        else if (_position.X + Radius > LogicalWidth) { _position.X = LogicalWidth - Radius; _velocity.X = -Math.Abs(_velocity.X); }
        if (_position.Y - Radius < 0) { _position.Y = Radius; _velocity.Y = Math.Abs(_velocity.Y); }
        else if (_position.Y + Radius > LogicalHeight) { _position.Y = LogicalHeight - Radius; _velocity.Y = -Math.Abs(_velocity.Y); }
    }
    protected override void OnRender(SKCanvas canvas, Rect rect, TimeSpan _, bool __)
    {
        canvas.Clear(SKColors.White);
        var scaleX = (float)(rect.Width / LogicalWidth);
        var scaleY = (float)(rect.Height / LogicalHeight);
        var cx = (float)rect.X + _position.X * scaleX;
        var cy = (float)rect.Y + _position.Y * scaleY;
        var r = Radius * Math.Min(scaleX, scaleY);
        using var ball = new SKPaint { Color = SKColors.CornflowerBlue, IsAntialias = true };
        canvas.DrawCircle(cx, cy, r, ball);
    }
}

// Start/Stop animation from code-behind or view-model command
// myControl.Start();
// myControl.Stop();

Key virtuals:

  • OnGetSourceSize: logical content size used for layout and stretch.
  • OnNormalizeElapsed: returns a NormalizeResult which maps elapsed time to a single loop and indicates loop completion (enables repeat counting).
  • OnRender: draw into the provided SKCanvas within rect.
  • OnUpdate: per-frame updates driven by the composition scheduler.
  • Start()/Stop() control the animation loop; RepeatCount sets the number of loops (use CompositionAnimatedControl.Infinity for endless).

Events:

  • Started, Stopped, Disposed
  • Update(TimeSpan delta)

Mode 2: Static rendering with invalidation

For static content, omit Start() and call Redraw() when you need to refresh after state changes.

public sealed class StaticRedrawControl : CompositionAnimatedControl
{
    private SKColor _color = SKColors.DarkSlateGray;
    protected override Size OnGetSourceSize() => new Size(200, 100);
    protected override NormalizeResult OnNormalizeElapsed(TimeSpan ts) => new NormalizeResult(TimeSpan.Zero, false);
    protected override void OnRender(SKCanvas canvas, Rect rect, TimeSpan _, bool __)
    {
        canvas.Clear(SKColors.White);
        using var paint = new SKPaint { Color = _color, IsAntialias = true };
        canvas.DrawRect((float)rect.X + 20, (float)rect.Y + 20, (float)rect.Width - 40, (float)rect.Height - 40, paint);
    }
    public void Toggle()
    {
        _color = _color == SKColors.DarkSlateGray ? SKColors.OrangeRed : SKColors.DarkSlateGray;
        Redraw();
    }
}

Notes:

  • Redraw() issues a single render pass without starting the animation scheduler.
  • Stretch and StretchDirection are supported in both modes.

ShaderAnimatedControl

A reusable control for rendering animated Skia shaders in Avalonia. This control loads and executes SKSL (Skia Shading Language) shaders with animation support.

Installation:

dotnet add package ShaderAnimatedControl

Basic Usage:

<ShaderAnimatedControl 
    ShaderUri="/Assets/MyShader.sksl"
    ShaderWidth="512"
    ShaderHeight="512"
    IsShaderFillCanvas="False" />
// Handle the Draw event for custom shader parameter binding
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        myShaderControl.Draw += OnShaderDraw;
    }

    private void OnShaderDraw(object? sender, DrawEventArgs e)
    {
        if (e.Effect == null || e.ErrorText != null)
            return;

        // Create shader with custom parameters
        var time = (float)e.EffectiveElapsed.TotalSeconds;
        var resolution = new SKPoint((float)e.ShaderWidth, (float)e.ShaderHeight);
        
        using var shader = e.Effect.ToShader(
            new SKRuntimeEffectUniforms(e.Effect)
            {
                ["iTime"] = time,
                ["iResolution"] = resolution
            });
        
        using var paint = new SKPaint { Shader = shader };
        e.Canvas.DrawRect(e.DestRect, paint);
    }
}

Key Features:

  • Load SKSL shaders from assets or URIs
  • Automatic animation loop with time-based parameters
  • Configurable shader dimensions
  • Fill canvas or maintain aspect ratio modes
  • Draw event for custom shader parameter binding
  • Built on top of CompositionAnimatedControl

Properties:

  • ShaderUri: URI to the SKSL shader file
  • ShaderWidth/ShaderHeight: Logical shader dimensions
  • IsShaderFillCanvas: Whether to fill the entire canvas or maintain aspect ratio

License

Lottie is licensed under the MIT license.

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 is compatible.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
12.0.0 0 4/12/2026
12.0.0-rc2 43 4/2/2026
11.3.0.2 137 8/16/2025