WPF之动画
Posted lonelyxmas
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WPF之动画相关的知识,希望对你有一定的参考价值。
原文:WPF之动画
线性关键帧、不连续关键帧动画:
<Window.Triggers>
<EventTrigger RoutedEvent="Window.Loaded">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<PointAnimationUsingKeyFrames Storyboard.TargetName="ellipse" Storyboard.TargetProperty="Fill.GradientOrigin"
RepeatBehavior="Forever" >
<LinearPointKeyFrame Value="0.7,0.3" KeyTime="0:0:0"></LinearPointKeyFrame>
<LinearPointKeyFrame Value="0.3,0.7" KeyTime="0:0:5"></LinearPointKeyFrame>
<LinearPointKeyFrame Value="0.5,0.9" KeyTime="0:0:8"></LinearPointKeyFrame>
<LinearPointKeyFrame Value="0.9,0.6" KeyTime="0:0:10"></LinearPointKeyFrame>
<LinearPointKeyFrame Value="0.8,0.2" KeyTime="0:0:12"></LinearPointKeyFrame>
<LinearPointKeyFrame Value="0.7,0.3" KeyTime="0:0:14"></LinearPointKeyFrame>
<DiscretePointKeyFrame Value="0.7,0.3" KeyTime="0:0:20"></DiscretePointKeyFrame>
<DiscretePointKeyFrame Value="0.3,0.7" KeyTime="0:0:25"></DiscretePointKeyFrame>
<DiscretePointKeyFrame Value="0.5,0.9" KeyTime="0:0:28"></DiscretePointKeyFrame>
<DiscretePointKeyFrame Value="0.9,0.6" KeyTime="0:0:20"></DiscretePointKeyFrame>
<DiscretePointKeyFrame Value="0.8,0.2" KeyTime="0:0:22"></DiscretePointKeyFrame>
<DiscretePointKeyFrame Value="0.7,0.3" KeyTime="0:0:24"></DiscretePointKeyFrame>
</PointAnimationUsingKeyFrames>
<ColorAnimation Storyboard.TargetName="ellipse" Storyboard.TargetProperty="Fill.GradientStops[1].Color"
To="Black" Duration="0:0:10"
AutoReverse="True" RepeatBehavior="Forever"></ColorAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Window.Triggers>
<Grid>
<Ellipse Name="ellipse" Margin="5" Grid.Row="1" Stretch="Uniform">
<Ellipse.Fill>
<RadialGradientBrush
RadiusX="1" RadiusY="1" GradientOrigin="0.7,0.3">
<GradientStop Color="White" Offset="0" ></GradientStop>
<GradientStop Color="Blue" Offset="1" ></GradientStop>
</RadialGradientBrush>
</Ellipse.Fill>
</Ellipse>
</Grid>
视觉动画:
<Button Name="visual" HorizontalAlignment="Center" VerticalAlignment="Center">
<Button.Content>Test</Button.Content>
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard RepeatBehavior="Forever">
<DoubleAnimation Storyboard.TargetName="rectangle"
Storyboard.TargetProperty="RenderTransform.Children[0].AngleY"
To="180" Duration="0:0:15" AutoReverse="True"></DoubleAnimation>
<DoubleAnimation Storyboard.TargetName="rectangle"
Storyboard.TargetProperty="RenderTransform.Children[1].Angle"
To="180" Duration="0:0:20" AutoReverse="True"></DoubleAnimation>
<DoubleAnimation Storyboard.TargetName="rectangle"
Storyboard.TargetProperty="Opacity"
To="0.1" Duration="0:0:4" AutoReverse="True"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Button.Triggers>
</Button>
<Rectangle Grid.Row="1" Name="rectangle" Width="100" Stretch="Uniform" ClipToBounds="False" RenderTransformOrigin="0.5,0.5">
<Rectangle.Fill>
<VisualBrush Visual="{Binding ElementName=visual}">
</VisualBrush>
</Rectangle.Fill>
<Rectangle.RenderTransform>
<TransformGroup>
<SkewTransform CenterX="0.5"></SkewTransform>
<RotateTransform CenterX="0.5" CenterY="0.5"></RotateTransform>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
</Grid>
样式动画:
<Style TargetType="{x:Type Button}">
<Setter Property="HorizontalAlignment" Value="Center"></Setter>
<Setter Property="RenderTransformOrigin" Value="0.5,0.5"></Setter>
<Setter Property="Padding" Value="20,15"></Setter>
<Setter Property="Margin" Value="2"></Setter>
<Setter Property="Effect">
<Setter.Value>
<BlurEffect Radius="10"></BlurEffect>
</Setter.Value>
</Setter>
<Style.Triggers>
<EventTrigger RoutedEvent="Button.MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Effect.Radius"
To="0" Duration="0:0:0.4"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="Button.MouseLeave">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Effect.Radius" To="10"
Duration="0:0:0.2"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
<StackPanel Margin="5">
<Button>One</Button>
<Button>Two</Button>
<Button>Three</Button>
<Button>Four</Button>
<TextBlock Name="lbl" Margin="5"></TextBlock>
</StackPanel>
<Window.Triggers>
<EventTrigger RoutedEvent="Window.Loaded">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard SpeedRatio="1.5">
<DoubleAnimation Storyboard.TargetName="element"
Storyboard.TargetProperty="Opacity"
From="0.2" To="1" Duration="0:0:2.5"></DoubleAnimation>
<DoubleAnimation Storyboard.TargetName="element"
Storyboard.TargetProperty="RenderTransform.Children[1].Angle"
From="70" To="0" Duration="0:0:2" ></DoubleAnimation>
<DoubleAnimation Storyboard.TargetName="element"
Storyboard.TargetProperty="RenderTransform.Children[0].ScaleX"
From="0" To="1" Duration="0:0:2" AccelerationRatio="1"></DoubleAnimation>
<DoubleAnimation Storyboard.TargetName="element"
Storyboard.TargetProperty="RenderTransform.Children[0].ScaleY"
From="0" To="1" Duration="0:0:2" AccelerationRatio="1"></DoubleAnimation>
<DoubleAnimation Storyboard.TargetName="element"
Storyboard.TargetProperty="RenderTransform.Children[0].ScaleX"
To="0.98" BeginTime="0:0:2" Duration="0:0:0.05" DecelerationRatio="1"></DoubleAnimation>
<DoubleAnimation Storyboard.TargetName="element"
Storyboard.TargetProperty="RenderTransform.Children[0].ScaleY"
To="0.98" BeginTime="0:0:2" Duration="0:0:0.05" DecelerationRatio="1"></DoubleAnimation>
<DoubleAnimation Storyboard.TargetName="element"
Storyboard.TargetProperty="RenderTransform.Children[0].ScaleX"
To="1" BeginTime="0:0:2.05" Duration="0:0:0.2" AccelerationRatio="1"></DoubleAnimation>
<DoubleAnimation Storyboard.TargetName="element"
Storyboard.TargetProperty="RenderTransform.Children[0].ScaleY"
To="1" BeginTime="0:0:2.05" Duration="0:0:0.2" AccelerationRatio="1"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Window.Triggers>
<Window.Triggers>
<EventTrigger RoutedEvent="Window.Loaded">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard SpeedRatio="1.5" Completed="storyboardCompleted">
<DoubleAnimation Storyboard.TargetName="rectangle"
Storyboard.TargetProperty="Opacity"
From="0.2" To="1" Duration="0:0:2.5"></DoubleAnimation>
<DoubleAnimation Storyboard.TargetName="rectangle"
Storyboard.TargetProperty="RenderTransform.Children[1].Angle"
From="70" To="0" Duration="0:0:2" ></DoubleAnimation>
<DoubleAnimation Storyboard.TargetName="rectangle"
Storyboard.TargetProperty="RenderTransform.Children[0].ScaleX"
From="0" To="1" Duration="0:0:2" AccelerationRatio="1"></DoubleAnimation>
<DoubleAnimation Storyboard.TargetName="rectangle"
Storyboard.TargetProperty="RenderTransform.Children[0].ScaleY"
From="0" To="1" Duration="0:0:2" AccelerationRatio="1"></DoubleAnimation>
<DoubleAnimation Storyboard.TargetName="rectangle"
Storyboard.TargetProperty="RenderTransform.Children[0].ScaleX"
To="0.98" BeginTime="0:0:2" Duration="0:0:0.05" DecelerationRatio="1"></DoubleAnimation>
<DoubleAnimation Storyboard.TargetName="rectangle"
Storyboard.TargetProperty="RenderTransform.Children[0].ScaleY"
To="0.98" BeginTime="0:0:2" Duration="0:0:0.05" DecelerationRatio="1"></DoubleAnimation>
<DoubleAnimation Storyboard.TargetName="rectangle"
Storyboard.TargetProperty="RenderTransform.Children[0].ScaleX"
To="1" BeginTime="0:0:2.05" Duration="0:0:0.2" AccelerationRatio="1"></DoubleAnimation>
<DoubleAnimation Storyboard.TargetName="rectangle"
Storyboard.TargetProperty="RenderTransform.Children[0].ScaleY"
To="1" BeginTime="0:0:2.05" Duration="0:0:0.2" AccelerationRatio="1"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Window.Triggers>
基于帧的动画:
private bool rendering = false;
private void cmdStart_Clicked(object sender, RoutedEventArgs e)
{
if (!rendering)
{
ellipses.Clear();
canvas.Children.Clear();
CompositionTarget.Rendering += RenderFrame;
rendering = true;
}
}
private void cmdStop_Clicked(object sender, RoutedEventArgs e)
{
StopRendering();
}
private void StopRendering()
{
CompositionTarget.Rendering -= RenderFrame;
rendering = false;
}
private List<EllipseInfo> ellipses = new List<EllipseInfo>();
private double accelerationY = 0.1;
private int minStartingSpeed = 1;
private int maxStartingSpeed = 50;
private double speedRatio = 0.1;
private int minEllipses = 20;
private int maxEllipses = 100;
private int ellipseRadius = 10;
private void RenderFrame(object sender, EventArgs e)
{
if (ellipses.Count == 0)
{
// Animation just started. Create the ellipses.
int halfCanvasWidth = (int)canvas.ActualWidth / 2;
Random rand = new Random();
int ellipseCount = rand.Next(minEllipses, maxEllipses+1);
for (int i = 0; i < ellipseCount; i++)
{
Ellipse ellipse = new Ellipse();
ellipse.Fill = Brushes.LimeGreen;
ellipse.Width = ellipseRadius;
ellipse.Height = ellipseRadius;
Canvas.SetLeft(ellipse, halfCanvasWidth + rand.Next(-halfCanvasWidth, halfCanvasWidth));
Canvas.SetTop(ellipse, 0);
canvas.Children.Add(ellipse);
EllipseInfo info = new EllipseInfo(ellipse, speedRatio * rand.Next(minStartingSpeed, maxStartingSpeed));
ellipses.Add(info);
}
}
else
{
for (int i = ellipses.Count-1; i >= 0; i--)
{
EllipseInfo info = ellipses[i];
double top = Canvas.GetTop(info.Ellipse);
Canvas.SetTop(info.Ellipse, top + 1 * info.VelocityY);
if (top >= (canvas.ActualHeight - ellipseRadius*2 - 10))
{
// This circle has reached the bottom.
// Stop animating it.
ellipses.Remove(info);
}
else
{
// Increase the velocity.
info.VelocityY += accelerationY;
}
if (ellipses.Count == 0)
{
// End the animation.
// There‘s no reason to keep calling this method
// if it has no work to do.
StopRendering();
}
}
}
}
}
public class EllipseInfo
{
public Ellipse Ellipse
{
get; set;
}
public double VelocityY
{
get; set;
}
public EllipseInfo(Ellipse ellipse, double velocityY)
{
VelocityY = velocityY;
Ellipse = ellipse;
}
}
KeySpline:
<Window.Triggers>
<EventTrigger RoutedEvent="Window.Loaded">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingKeyFrames
Storyboard.TargetName="ellipse1" Storyboard.TargetProperty="(Canvas.Left)" >
<SplineDoubleKeyFrame KeyTime="0:0:5" Value="250" KeySpline="0.25,0 0.5,0.7"></SplineDoubleKeyFrame>
<SplineDoubleKeyFrame KeyTime="0:0:10" Value="500" KeySpline="0.25,0.8 0.2,0.4"></SplineDoubleKeyFrame>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimation
Storyboard.TargetName="ellipse2" Storyboard.TargetProperty="(Canvas.Left)"
To="500" Duration="0:0:10">
</DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Window.Triggers>
<Canvas Margin="10">
<Ellipse Name="ellipse1" Canvas.Left="0" Fill="Red" Width="10" Height="10"></Ellipse>
<Path Stroke="Blue" StrokeThickness="1" StrokeDashArray="2 1" Canvas.Top="25">
<Path.Data>
<PathGeometry>
<PathFigure>
<BezierSegment Point1="25,0" Point2="50,70" Point3="100,100" />
</PathFigure>
</PathGeometry>
</Path.Data>
<Path.RenderTransform>
<ScaleTransform ScaleX="2.5"></ScaleTransform>
</Path.RenderTransform>
</Path>
<Path Stroke="Blue" StrokeThickness="1" StrokeDashArray="2 1" Canvas.Left="250" Canvas.Top="25">
<Path.Data>
<PathGeometry>
<PathFigure>
<BezierSegment Point1="25,80" Point2="20,40" Point3="100,100" />
</PathFigure>
</PathGeometry>
</Path.Data>
<Path.RenderTransform>
<ScaleTransform ScaleX="2.5"></ScaleTransform>
</Path.RenderTransform>
</Path>
<Ellipse Name="ellipse2" Canvas.Top="150" Canvas.Left="0" Fill="Red" Width="10" Height="10"></Ellipse>
</Canvas>
基于路径动画:
<Window.Resources>
<PathGeometry x:Key="path">
<PathFigure IsClosed="True">
<ArcSegment Point="100,200" Size="15,10" SweepDirection="Clockwise"></ArcSegment>
<ArcSegment Point="400,50" Size="5,5" ></ArcSegment>
</PathFigure>
</PathGeometry>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="Window.Loaded">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimationUsingPath Storyboard.TargetName="image"
Storyboard.TargetProperty="(Canvas.Left)"
PathGeometry="{StaticResource path}"
Duration="0:0:5" RepeatBehavior="Forever" Source="X" />
<DoubleAnimationUsingPath Storyboard.TargetName="image"
Storyboard.TargetProperty="(Canvas.Top)"
PathGeometry="{StaticResource path}"
Duration="0:0:5" RepeatBehavior="Forever" Source="Y" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Window.Triggers>
<Canvas Margin="10">
<Path Stroke="Red" StrokeThickness="1" Data="{StaticResource path}" Canvas.Top="10" Canvas.Left="10">
</Path>
<Image Name="image">
<Image.Source>
<DrawingImage>
<DrawingImage.Drawing>
<GeometryDrawing Brush="LightSteelBlue">
<GeometryDrawing.Geometry>
<GeometryGroup>
<EllipseGeometry Center="10,10" RadiusX="9" RadiusY="4" />
<EllipseGeometry Center="10,10" RadiusX="4" RadiusY="9" />
</GeometryGroup>
</GeometryDrawing.Geometry>
<GeometryDrawing.Pen>
<Pen Thickness="1" Brush="Black" />
</GeometryDrawing.Pen>
</GeometryDrawing>
</DrawingImage.Drawing>
</DrawingImage>
</Image.Source>
</Image>
</Canvas>
旋转动画:
<Style TargetType="{x:Type Button}">
<Setter Property="HorizontalAlignment" Value="Center"></Setter>
<Setter Property="RenderTransformOrigin" Value="0.5,0.5"></Setter>
<Setter Property="Padding" Value="20,15"></Setter>
<Setter Property="Margin" Value="2"></Setter>
<Setter Property="RenderTransform">
<Setter.Value>
<RotateTransform></RotateTransform>
</Setter.Value>
</Setter>
<Style.Triggers>
<EventTrigger RoutedEvent="Button.MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard Name="rotateStoryboardBegin">
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="RenderTransform.Angle"
To="360" Duration="0:0:0.8" RepeatBehavior="Forever"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="Button.MouseLeave">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="RenderTransform.Angle"
Duration="0:0:0.2"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
<StackPanel Margin="5" Button.Click="cmd_Clicked">
<Button>One</Button>
<Button>Two</Button>
<Button>Three</Button>
<Button>Four</Button>
<TextBlock Name="lbl" Margin="5"></TextBlock>
</StackPanel>
布局动画:
<Style TargetType="{x:Type Button}">
<Setter Property="HorizontalAlignment" Value="Center"></Setter>
<Setter Property="RenderTransformOrigin" Value="0.5,0.5"></Setter>
<Setter Property="Padding" Value="20,15"></Setter>
<Setter Property="Margin" Value="2"></Setter>
<Setter Property="LayoutTransform">
<Setter.Value>
<RotateTransform></RotateTransform>
</Setter.Value>
</Setter>
<Style.Triggers>
<EventTrigger RoutedEvent="Button.MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard Name="rotateStoryboardBegin">
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="LayoutTransform.Angle"
To="360" Duration="0:0:0.8" RepeatBehavior="Forever"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="Button.MouseLeave">
<EventTrigger.Actions>
<!-- <RemoveStoryboard BeginStoryboardName="rotateStoryboardBegin"></RemoveStoryboard> -->
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="LayoutTransform.Angle"
Duration="0:0:0.2"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
<StackPanel Margin="5" Button.Click="cmd_Clicked">
<Button>One</Button>
<Button>Two</Button>
<Button>Three</Button>
<Button>Four</Button>
<TextBlock Name="lbl" Margin="5"></TextBlock>
</StackPanel>
private void cmd_Clicked(object sender, RoutedEventArgs e)
{
lbl.Text = "You clicked: " + ((Button)e.OriginalSource).Content;
}
以上是关于WPF之动画的主要内容,如果未能解决你的问题,请参考以下文章
WPF学习笔记之如何把数据库里的值读取出来然后显示在页面上:动画系列之
[WPF 学习] 13.DataTrigger之EnterAction和ExitAction