9.7 模拟实现微信的彩蛋动画 大家在玩微信的时候有没有发现节日的时候发一些节日问候语句如“情人节快乐”,这时候会出现很多爱心形状从屏幕上面飘落下来,我们这小节就是要模拟实现这样的一种动画效果。可能微信里面实现的动画效果都 ...
9.7 模拟实现微信的彩蛋动画
大家在玩微信的时候有没有发现节日的时候发一些节日问候语句如“情人节快乐”,这时候会出现很多爱心形状从屏幕上面飘落下来,我们这小节就是要模拟实现这样的一种动画效果。可能微信里面实现的动画效果都是采用固定的小图片来最为动画的对象,但是我们这小节要对该动画效果增加一些改进,也就是要实现的彩蛋动画的针对的图形形状是动态随机生成的,所以看到从屏幕上面飘落的图形都是形状不太一样的。下面来看一下如何实现星星飘落动画。
9.7.1 实现的思路
首先,我们来分析一下星星飘落动画的实现思路。
(1)动画对象
微信的彩蛋动画可以采用固定的图片对象作为动画的对象,但是因为我们要实现的星星动画,这个星星的形状和颜色是不一样的,所以不能直接用图片做为星星的对象。要创建出不同的星星形状需要用到Path图形绘图的方式来实现,定义好画图的规则,然后用随机数来决定某些点的位置这样就可以绘制出各种不同形状的星星。颜色的随机定义就很好办了,可以先产生随机的0-255的三原**值,然后用三原色的方式来创建颜色对象。
(2)动画的实现方式
从微信的彩蛋动画效果可以看出来,这些动画的随机型很大,轨迹运动轨迹、速度、方向都是随机,这种情况是很难使用线性插值动画或者关键帧动画去实现的,所以这个动画的实现方式很明显是要采用基于帧动画去实现。在基于帧动画里面,通过CompositionTarget.Rendering事件的处理程序来实现动画的效果,星星飘落的动画效果是星星对象从一个固定区域的最上面某个位置飘落到该区域的最底下,然后再销毁星星对象。我们可以采用Canvas面板来定义动画的区域,用Canvas.LeftProperty和Canvas.TopProperty属性作为定义星星对象位置的坐标,然后通过改变这个坐标来实现星星的下落。
(3)动画的封装
在对动画的实现方式和动画对象的封装的思路清楚之后,我们开始考虑如何来封装这样的一种动画效果。星星对象的实现需要通过一个星星工厂类(StarFactory类)来封装星星创建的逻辑。因为每个星星的运动轨迹都是不一样的,都有其自己飘落的速度和方向,所以我们需要封装一个星星的对象,在星星对象里面负责处理星星的速度,方向,运动轨迹等逻辑。最后动画可以通过附加属性的方式在Canvas面板上实现动画。
下面我们来详细地看一下星星飘落动画的编码实现。
代码清单9-18:星星飘落动画(源代码:第9章\Examples_9_18)
9.7.2 星星创建工厂
首先,我们先来实现星星的创建工厂StarFactory类,StarFactory类的作用是创建动画里面的星星对象,动画的实现需要向调用StarFactory类来创建出星星对象,然后对星星进行动画处理,所以StarFactory类是一个非常单一的星星构造工厂,里面不涉及动画的操作,只涉及星星Path对象的创建。
(1)星星对象的绘图原理
星星的对象的绘图坐标模型如图9.28所示,首先,需要确定确定坐标系三个点a、b、c,然后再取三条线段ab、ac、bc的三分之一和三分之二的点坐标和两点区域之前一个随机点,经过这样一个处理之后原来的是3条线段的星星图形,变成了3*4条线段的星星图形,在递归一次就会变成3*4*4条线段的星星图形如此类推。
下面把星星图形形状的构造封装了3个方法:_RefactorPoints方法是用于取两个点线段之间的三分之一点、三分之二点和两点区域间的随机点,最后在加上原来的两个点,返回一个5个点的点集合;_RecurseSide方法是封装了两个点之间递归之后所取到的点集合;_CreatePath方法则是把这些点集合连接起来创建一个Path图形表示星星图形。三个方法的代码如下所示:
StarFactory.cs文件部分代码------------------------------------------------------------------------------------------------------------------ /// <summary> /// 把两个点转化成多级的点的集合 /// </summary> /// <param name="a">第一个点</param> /// <param name="b">第二个点</param> /// <param name="level">递归的次数</param> /// <returns>新的点的集合</returns> private static List<Point> _RecurseSide(Point a, Point b, int level) { // 递归完成后,返回此线段 if (level == 0) { return new List<Point> { a, b }; } else { // 首先,需要建立起第一次递归的点的列表,一直递归到级别为0 List<Point> newPoints = new List<Point>(); // 把区域分成5个点 foreach (Point point in _RefactorPoints(a, b)) { newPoints.Add(point); } List<Point> aggregatePoints = new List<Point>(); // 把每一个线段进一步分解 for (int x = 0; x < newPoints.Count; x++) { int y = x + 1 == newPoints.Count ? 0 : x + 1; aggregatePoints.AddRange(_RecurseSide(newPoints[x], newPoints[y], level - 1)); } return aggregatePoints; } } /// <summary> /// 通过输入两个点来构建一个有多个三角形组成的Star形状 /// </summary> /// <param name="a">第一个点</param> /// <param name="b">第二个点</param> /// <returns>一个新的几何图形的点的集合</returns> private static IEnumerable<Point> _RefactorPoints(Point a, Point b) { // 第一个点 yield return a; double dX = b.X - a.X; double dY = b.Y - a.Y; // 第一个点到第二个点1/3处的一个点 yield return new Point(a.X + dX / 3.0, a.Y + dY / 3.0); double factor = _random.NextDouble() - 0.5; double vX = (a.X + b.X) / (2.0 + factor) + Math.Sqrt(3.0 + factor) * (b.Y - a.Y) / (6.0 + factor * 2.0); double vY = (a.Y + b.Y) / (2.0 + factor) + Math.Sqrt(3.0 + factor) * (a.X - b.X) / (6.0 + factor * 2.0); // 中间的三角形的顶点 yield return new Point(vX, vY); //第二个点到第一个点1/3处的一个点 yield return new Point(b.X - dX / 3.0, b.Y - dY / 3.0); //第二个点 yield return b; } /// <summary> /// 使用一系列的点来创建路径图形 /// </summary> /// <param name="points">点的集合</param> /// <returns>路径图形</returns> private static Path _CreatePath(List<Point> points) { PathSegmentCollection segments = new PathSegmentCollection(); bool first = true; // 把点添加到线段里面 foreach (Point point in points) { if (first) { first = false; } else { segments.Add( new LineSegment { Point = point }); } } PathGeometry pathGeometry = new PathGeometry(); //通过线段构建几何图形 pathGeometry.Figures.Add( new PathFigure { IsClosed = true, StartPoint = points[0], Segments = segments }); return new Path { Data = pathGeometry }; }
原标题:[深入浅出Windows 10]模拟实现微信的彩蛋动画
关键词:Windows
*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们:
admin#shaoqun.com
(#换成@)。