1、动态变换。
变换提供了自定义元素的最强大方式之一。每个元素都能以两种不同的方式使用变换,RenderTransform属性和LayoutTransform属性。RenderTransform属性效率更高。因为是在布局之后应用变换,并且用于变换最终的渲染输出。LayoutTransform在布局前应用,从而其他控件需要重新排列以适应变换。
使用 RenderTransform:
效果图:
使用LayOutTransform:
效果图:
2、动态改变多个变换。
就是在TransformGroup中放置多个变换类。
xaml代码:
效果图:
3、动态改变画刷。
使用ColorAnimation改变颜色,使用PointAnimatin改变坐标。
xaml代码:
效果图:
4、动态改变像素着色器。
效果图:
5、关键帧动画。
如果需要创建具有多个分段的动画和不规则移动的动画,这个时候可以使用关键帧动画。关键帧动画是由许多较短的段构成的动画,每段表示动画的初始值、最终值或中间值。当运行动画时,她平滑地从一个值移动到另一个值。关键帧对象基本上都有Value属性和KeyTime属性。和其他普通动画不同的是Value属性的数据类型,在LinearPointKeyFrame类中是Point类型,在DoubleKeyFrame类中是double类型。
xaml代码:
效果图:
6、离散的关键帧动画。
如上图,使用的是线性关键帧动画,所以,它在关键帧动画之间平滑地过度。另一种选择是使用离散关键帧,离散关键帧不是进行插值,当到达关键时间时,属性突然改变为新值。线性关键帧类通常使用"Linear"+数据类型+KeyFrame"的形式进行命名,离散关键帧类使用"Discrete数据类型+KeyFrame"的形式命名。当运行这个动画时中心点会在适当的时间从一个位置跳转到下一个位置。所有关键帧动画类都支持离散关键帧,但只有一部分关键动画类支持线性关键帧。
Xaml代码:
效果图:
7、缓动关键帧。
由离散关键帧可以得出:尽管关键帧动画被分割成多段,但每段仍使用普通的线性插值。常用的缓动关键帧类有:EasingDoubleKeyFrame、EasingColorKeyFrame、EasyingPointKeyFrame。每个缓动关键帧类和对应的线性插值关键帧类的工作方式相同,但是额外提供了EasyingFunction属性。
Xaml代码:
效果图:
8、关键帧动画。
效果图:
9、基于帧的动画。
使用帧的动画要为静态的CompositionTarger.Rendering事件关联事件处理程序,一旦关联这个处理程序,WPF就开始不断地调用这个事件处理程序,WPF将每秒调用60次。当动画结束后,分离事件处理程序。
xaml代码:
后台代码(EllipseInfo类):
public class EllipseInfo{ public Ellipse Ellipse { get; set; } ////// Y轴的速度。 /// public double VelocityY { get; set; } public EllipseInfo(Ellipse _ellipse, double _velocityY) { Ellipse = _ellipse; VelocityY = _velocityY; } }
后台代码:
public partial class MainWindow : Window{ public MainWindow() { InitializeComponent(); } private ListlistEllipse = new List (); //声明一个Ellipse类型的list集合。 private double acclerationY = 0.1;//Y轴加速度。 private int minStartingSpeed = 1; //开始时最慢的速度。 private int maxStartingSpeed = 50; //开始时最快速度。 private double speedRatio = 0.1; //速度比率:0.1 private int minEllipses = 20; //最少椭圆数量。 private int maxEllipses = 100; //最多椭圆数量。 private int ellipseRadius = 10; //椭圆的半径。 private bool rendering = false; private void btnStart_Click(object sender, RoutedEventArgs e) { if (rendering == false) { listEllipse.Clear(); canvas.Children.Clear(); CompositionTarget.Rendering += CompositionTarget_Rendering; rendering = true; } } void CompositionTarget_Rendering(object sender, EventArgs e) { if (listEllipse.Count == 0) { int halfCanvasWidth = (int)canvas.ActualWidth / 2; Random random = new Random(); int ellipseCount = random.Next(minEllipses, maxEllipses + 1); for (int i = 0; i < ellipseCount; i++) { Ellipse ellipse = new Ellipse();//创建一个椭圆。 ellipse.Fill = new SolidColorBrush(Colors.LimeGreen);//设置椭圆颜色。 ellipse.Width = ellipseRadius;//设置椭圆的宽。 ellipse.Height = ellipseRadius;//设置椭圆的高。 Canvas.SetLeft(ellipse, halfCanvasWidth + random.Next(-halfCanvasWidth, halfCanvasWidth)); //设置椭圆位置。 Canvas.SetTop(ellipse, 0); //设置椭圆位置。 canvas.Children.Add(ellipse); //将创建出来的椭圆加入到canvas面板中。 EllipseInfo info = new EllipseInfo(ellipse, speedRatio * random.Next(minStartingSpeed, maxStartingSpeed)); //实例化EllipseInfo。 listEllipse.Add(info); //将创建好的EllipseInfo加入到listEllipse集合中。 } } else { for (int i = listEllipse.Count-1; i >= 0; i--) { EllipseInfo info = listEllipse[i]; //得到椭圆。 double top = Canvas.GetTop(info.Ellipse);//得到top坐标值。 Canvas.SetTop(info.Ellipse, top + 1 * info.VelocityY); if (top >= canvas.ActualHeight - ellipseRadius * 2 - 10) { listEllipse.Remove(info); } else { info.VelocityY += acclerationY; } if (listEllipse.Count == 0) { StopRendering(); } } } } //取消关联事件处理程序。 private void StopRendering() { CompositionTarget.Rendering -= CompositionTarget_Rendering; rendering = false; } private void btnStop_Click(object sender, RoutedEventArgs e) { StopRendering(); }}
效果图:
End!