creating-wpf-animations — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited creating-wpf-animations (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
WPF animations create visual effects by changing property values over time.
Storyboard (container)
├── Timeline (time control)
│ ├── Animation (value change)
│ │ ├── DoubleAnimation
│ │ ├── ColorAnimation
│ │ └── ...
│ └── AnimationUsingKeyFrames (keyframes)
│ ├── DoubleAnimationUsingKeyFrames
│ └── ...
└── EasingFunction (acceleration/deceleration)<Button Content="Hover Me" Width="100">
<Button.Style>
<Style TargetType="Button">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<!-- Width animation -->
<DoubleAnimation
Storyboard.TargetProperty="Width"
To="150"
Duration="0:0:0.3"/>
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation
Storyboard.TargetProperty="Width"
To="100"
Duration="0:0:0.3"/>
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button><Border x:Name="AnimatedBorder" Background="Blue" Width="100" Height="100">
<Border.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard>
<Storyboard>
<!-- Background color animation -->
<ColorAnimation
Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)"
To="Red"
Duration="0:0:0.5"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<BeginStoryboard>
<Storyboard>
<ColorAnimation
Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)"
To="Blue"
Duration="0:0:0.5"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Border.Triggers>
</Border><Border x:Name="SlidingBorder" Margin="0,0,0,0">
<Border.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard>
<Storyboard>
<!-- Slide-in effect -->
<ThicknessAnimation
Storyboard.TargetProperty="Margin"
From="-100,0,0,0"
To="0,0,0,0"
Duration="0:0:0.5"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Border.Triggers>
</Border><Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Width" To="200" Duration="0:0:0.5">
<DoubleAnimation.EasingFunction>
<!-- Various easing functions -->
<!-- Smooth deceleration -->
<QuadraticEase EasingMode="EaseOut"/>
<!-- Elastic effect -->
<!--<ElasticEase Oscillations="3" Springiness="5"/>-->
<!-- Bounce effect -->
<!--<BounceEase Bounces="3" Bounciness="2"/>-->
<!-- Back effect (overshoot) -->
<!--<BackEase Amplitude="0.3"/>-->
<!-- Circular easing -->
<!--<CircleEase EasingMode="EaseInOut"/>-->
</DoubleAnimation.EasingFunction>
</DoubleAnimation>
</Storyboard>| Mode | Description |
|---|---|
| EaseIn | Slow at start, fast at end |
| EaseOut | Fast at start, slow at end |
| EaseInOut | Slow at both ends, fast in middle |
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Opacity">
<!-- Sequential keyframes -->
<LinearDoubleKeyFrame Value="0.3" KeyTime="0:0:0.2"/>
<LinearDoubleKeyFrame Value="1.0" KeyTime="0:0:0.4"/>
<SplineDoubleKeyFrame Value="0.5" KeyTime="0:0:0.8">
<SplineDoubleKeyFrame.KeySpline>
<KeySpline ControlPoint1="0.5,0" ControlPoint2="0.5,1"/>
</SplineDoubleKeyFrame.KeySpline>
</SplineDoubleKeyFrame>
<EasingDoubleKeyFrame Value="1.0" KeyTime="0:0:1">
<EasingDoubleKeyFrame.EasingFunction>
<BounceEase/>
</EasingDoubleKeyFrame.EasingFunction>
</EasingDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
</Storyboard><Storyboard>
<!-- Visibility toggle (non-continuous values) -->
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Visible}"/>
<DiscreteObjectKeyFrame KeyTime="0:0:1" Value="{x:Static Visibility.Hidden}"/>
<DiscreteObjectKeyFrame KeyTime="0:0:2" Value="{x:Static Visibility.Visible}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard><Button Content="Rotate" RenderTransformOrigin="0.5,0.5">
<Button.RenderTransform>
<RotateTransform x:Name="RotateTransform" Angle="0"/>
</Button.RenderTransform>
<Button.Triggers>
<EventTrigger RoutedEvent="Click">
<BeginStoryboard>
<Storyboard>
<!-- Rotation animation -->
<DoubleAnimation
Storyboard.TargetName="RotateTransform"
Storyboard.TargetProperty="Angle"
By="360"
Duration="0:0:0.5"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
</Button><Border Width="100" Height="100" Background="Blue" RenderTransformOrigin="0.5,0.5">
<Border.RenderTransform>
<TransformGroup>
<ScaleTransform x:Name="Scale" ScaleX="1" ScaleY="1"/>
<RotateTransform x:Name="Rotate" Angle="0"/>
<TranslateTransform x:Name="Translate" X="0" Y="0"/>
</TransformGroup>
</Border.RenderTransform>
<Border.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard>
<Storyboard>
<!-- Simultaneous animations -->
<DoubleAnimation Storyboard.TargetName="Scale"
Storyboard.TargetProperty="ScaleX"
To="1.2" Duration="0:0:0.2"/>
<DoubleAnimation Storyboard.TargetName="Scale"
Storyboard.TargetProperty="ScaleY"
To="1.2" Duration="0:0:0.2"/>
<DoubleAnimation Storyboard.TargetName="Rotate"
Storyboard.TargetProperty="Angle"
To="10" Duration="0:0:0.2"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Border.Triggers>
</Border>namespace MyApp.Animations;
using System;
using System.Windows;
using System.Windows.Media.Animation;
public static class AnimationHelper
{
/// <summary>
/// Opacity fade animation
/// </summary>
public static void FadeIn(UIElement element, double durationSeconds = 0.3)
{
var animation = new DoubleAnimation
{
From = 0,
To = 1,
Duration = TimeSpan.FromSeconds(durationSeconds),
EasingFunction = new QuadraticEase { EasingMode = EasingMode.EaseOut }
};
element.BeginAnimation(UIElement.OpacityProperty, animation);
}
public static void FadeOut(UIElement element, double durationSeconds = 0.3, Action? onCompleted = null)
{
var animation = new DoubleAnimation
{
From = 1,
To = 0,
Duration = TimeSpan.FromSeconds(durationSeconds),
EasingFunction = new QuadraticEase { EasingMode = EasingMode.EaseIn }
};
if (onCompleted is not null)
{
animation.Completed += (s, e) => onCompleted();
}
element.BeginAnimation(UIElement.OpacityProperty, animation);
}
}Advanced: See ADVANCED.md for composite Storyboard animation, AnimationController (stop/resume), and VisualStateManager integration.
| Property | Performance | Description |
|---|---|---|
| Opacity | ⭐⭐⭐ | Most efficient |
| RenderTransform | ⭐⭐⭐ | No layout recalculation |
| Clip | ⭐⭐ | Medium performance |
| Width/Height | ⭐ | Causes layout recalculation |
| Margin | ⭐ | Causes layout recalculation |
// Performance optimization hints
RenderOptions.SetBitmapScalingMode(element, BitmapScalingMode.LowQuality);
Timeline.SetDesiredFrameRate(storyboard, 30); // Default 60fps → 30fps~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.