WPF之動畫
阿新 • • 發佈:2018-10-22
gradient mine dna prope onu sele wid str ane 原文: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之動畫