不同平台(mac、windows—wpf、web、ios、android)下实现页面的转场动画

来源:互联网 发布:网络防火墙导致不上网 编辑:程序博客网 时间:2024/05/16 09:26

最简单的转场动画就是在一个黑色的圆角矩形里面加载一个菊花轮,但如果项目要求高一些,就需要我们自己来实现一个自定义的转场动画了,不多说,先上效果图:


Mac上是通过一个NSTimer计时器然后不停地重绘来实现的,转场动画封装在一个NSView中,具体代码如下:

// <copyright company="上海诸君信息科技有限公司">上海诸君信息科技有限公司版权所有</copyright>// <author>海学权</author>//using System;using AppKit;using CoreGraphics;using Foundation;namespace LoadingViewTest{public class LoadingView:NSView{//缩放比例,原图是按照256*256来画的float scale;//圆形里面的三种颜色CGColor color1;CGColor color2;CGColor color3;//第一条曲线的起始点public CGPoint curve1StartPoint;//第一条曲线的结束点public CGPoint curve1EndPoint;//第二条曲线的起始点public CGPoint curve2StartPoint;//第二条曲线的结束点public CGPoint curve2EndPoint;//圆里面第一条曲线的贝塞尔控制点public CGPoint cp1;public CGPoint cp2;public CGPoint cp3;public CGPoint cp4;public CGPoint cp5;public CGPoint cp6;public CGPoint cp7;public CGPoint cp8;//圆里面第二条曲线的贝塞尔控制点public CGPoint rcp1;public CGPoint rcp2;public CGPoint rcp3;public CGPoint rcp4;public CGPoint rcp5;public CGPoint rcp6;public CGPoint rcp7;public CGPoint rcp8;//闪电路径中的点public CGPoint lightningP1;public CGPoint lightningP2;public CGPoint lightningP3;public CGPoint lightningP4;public CGPoint lightningP5;public CGPoint lightningP6;//嘴的贝塞尔控制点public CGPoint MouthControlP1;public CGPoint MouthControlP2;//左胳膊的贝塞尔控制点public CGPoint LeftArmCP1;public CGPoint LeftArmCP2;//右胳膊贝塞尔控制点public CGPoint RightArmCP1;public CGPoint RightArmCP2;//眼睛的旋转角度public float EyeRotateAngle;float eyeWidth = 26;float eyeLineWidth = 5;//手的旋转角度public float HandRotateAngle;//是否要动化显示的标记bool animationFlag = false;nfloat LightningAlpha = 0;bool showLighting = true;//实例化方法public LoadingView(CGRect frame) : base(frame){scale =(float)(frame.Width / 256);curve1StartPoint = new CGPoint(58, 167).MagnifyPoint(scale);curve1EndPoint = new CGPoint(174, 62.5f).MagnifyPoint(scale);curve2StartPoint = new CGPoint(120, 207.75f).MagnifyPoint(scale);curve2EndPoint = new CGPoint(206.5f, 112.5f).MagnifyPoint(scale);//为属性设置初始值color1 = new CGColor(0, 159 / 255f, 239 / 255f);color2 = new CGColor(85 / 255f, 198 / 255f, 237 / 255f);color3 = new CGColor(153 / 255f, 223 / 255f, 246 / 255f);cp1 = new CGPoint(97, 162).MagnifyPoint(scale);cp2 = new CGPoint(112, 143).MagnifyPoint(scale);cp3 = new CGPoint(87, 81).MagnifyPoint(scale);cp4 = new CGPoint(116, 56).MagnifyPoint(scale);cp5 = new CGPoint(147, 74).MagnifyPoint(scale);cp6 = new CGPoint(156, 77).MagnifyPoint(scale);cp7 = new CGPoint(101, 14.5f).MagnifyPoint(scale);cp8 = new CGPoint(19.75f, 91.5f).MagnifyPoint(scale);rcp1 = new CGPoint(122, 197).MagnifyPoint(scale);rcp2 = new CGPoint(165, 193).MagnifyPoint(scale);rcp3 = new CGPoint(134, 133).MagnifyPoint(scale);rcp4 = new CGPoint(153, 105).MagnifyPoint(scale);rcp5 = new CGPoint(194, 117).MagnifyPoint(scale);rcp6 = new CGPoint(195, 120).MagnifyPoint(scale);rcp7 = new CGPoint(215.75f, 156.5f).MagnifyPoint(scale);rcp8 = new CGPoint(183.5f, 213.25).MagnifyPoint(scale);lightningP1 = new CGPoint(-11, 4).MagnifyPoint(scale);lightningP2 = new CGPoint(-1, 1).MagnifyPoint(scale);lightningP3 = new CGPoint(-1, 5).MagnifyPoint(scale);lightningP4 = new CGPoint(11, -4).MagnifyPoint(scale);lightningP5 = new CGPoint(1, -1).MagnifyPoint(scale);lightningP6 = new CGPoint(1, -5).MagnifyPoint(scale);//CGPoint mouseControlStartP1 = new CGPoint(148.5f,180);//CGPoint mouseControlStartP2 = new CGPoint(156,172.5f);CGPoint mouseControlStartP1 = new CGPoint(120, 162.5f);CGPoint mouseControlStartP2 = new CGPoint(151, 163.5f);CGPoint mouseControlEndP1 = new CGPoint(149.5f, 140.5f);CGPoint mouseControlEndP2 = new CGPoint(174.5f, 145);MouthControlP1 = mouseControlStartP1.MagnifyPoint(scale);MouthControlP2 = mouseControlStartP2.MagnifyPoint(scale);LeftArmCP1 = new CGPoint(-6,59).MagnifyPoint(scale);LeftArmCP2 = new CGPoint(70,69).MagnifyPoint(scale);RightArmCP1 = new CGPoint(253,208).MagnifyPoint(scale);RightArmCP2 = new CGPoint(222,156).MagnifyPoint(scale);EyeRotateAngle = 70;HandRotateAngle = 30;//用一个timer不停地重绘来实现颜色交替变化的动画int i = 0;NSTimer.CreateRepeatingScheduledTimer(0.3, delegate (NSTimer timer){if (animationFlag){i = (i + 1) % 3;CGColor tmpcolor = color1;color1 = color3;color3 = color2;color2 = tmpcolor;SetNeedsDisplayInRect(this.Bounds);}});//嘴巴的贝塞尔控制点的变化范围float diffX1 = ((float)(mouseControlEndP1.X) - (float)(mouseControlStartP1.X))*scale;float diffX2 = ((float)(mouseControlEndP2.X) - (float)(mouseControlStartP2.X)) * scale;float diffY1 = ((float)(mouseControlEndP1.Y) - (float)(mouseControlStartP1.Y)) * scale;float diffY2 = ((float)(mouseControlEndP2.Y) - (float)(mouseControlStartP2.Y)) * scale;float handAngleDiff = -50;float eyeAngleDiff = -70;float eyeWidthDiff = 8;float eyeLineWidthDiff = 5;//控制动画方向的标识bool eyeAddFlag = true;//用一个timer不停地重绘来实现嘴巴、眼睛、手的动画int j = 0;//帧数float frameCount = 30;NSTimer.CreateRepeatingScheduledTimer(0.05, delegate (NSTimer timer){if (animationFlag==false){return;}if (eyeAddFlag){j = j + 1;if (j > frameCount){eyeAddFlag = false;}EyeRotateAngle += 1 / (float)frameCount * eyeAngleDiff;eyeWidth -= 1 / (float)frameCount * eyeWidthDiff;eyeLineWidth += 1 / (float)frameCount * eyeLineWidthDiff;HandRotateAngle += 1 / (float)frameCount * handAngleDiff;MouthControlP1 = new CGPoint(MouthControlP1.X + (diffX1 / frameCount), MouthControlP1.Y + (diffY1 / frameCount));MouthControlP2 = new CGPoint(MouthControlP2.X + (diffX2 / frameCount), MouthControlP2.Y + (diffY2 / frameCount));}else{j = j - 1;if (j < 0){eyeAddFlag = true;}EyeRotateAngle -= 1 / (float)frameCount * eyeAngleDiff;eyeWidth += 1 / (float)frameCount * eyeWidthDiff;eyeLineWidth -= 1 / (float)frameCount * eyeLineWidthDiff;HandRotateAngle -= 1 / (float)frameCount * handAngleDiff;MouthControlP1 = new CGPoint(MouthControlP1.X - (diffX1 / frameCount), MouthControlP1.Y - (diffY1 / frameCount));MouthControlP2 = new CGPoint(MouthControlP2.X - (diffX2 / frameCount), MouthControlP2.Y - (diffY2 / frameCount));}LightningAlpha = j / frameCount;if (j % 10 == 0){showLighting = true;}else{showLighting = false;}SetNeedsDisplayInRect(this.Bounds);});}//开始动画public void StartAnimation() {animationFlag = true;}//结束动画public void StopAnimation() {animationFlag = false;}//绘制方法public override void DrawRect(CGRect dirtyRect){dirtyRect = this.Bounds;//获取当前画布CGContext context = NSGraphicsContext.CurrentContext.GraphicsPort;//圆形的四周边距nfloat margin = 44*scale;//圆形所在的矩形CGRect circleRect = new CGRect(margin,margin,dirtyRect.Width-(margin*2),dirtyRect.Height-(margin*2));//圆形的线宽nfloat lineWidth = 8 * scale;context.SetLineWidth(lineWidth);context.SetStrokeColor(NSColor.Black.CGColor);context.SetFillColor(color2);context.StrokeEllipseInRect(circleRect);margin = 48 * scale;context.FillEllipseInRect(new CGRect(margin, margin, dirtyRect.Width - (margin * 2), dirtyRect.Height - (margin * 2)));//第一条曲线的路径CGPath path1 = new CGPath();path1.MoveToPoint(curve1StartPoint);CGPoint endp = new CGPoint(100, 114).MagnifyPoint(scale);path1.AddCurveToPoint(cp1, cp2, endp);CGPoint endp2 = new CGPoint(140, 72).MagnifyPoint(scale);path1.AddCurveToPoint(cp3, cp4, endp2);path1.AddCurveToPoint(cp5, cp6, curve1EndPoint);path1.AddCurveToPoint(cp7, cp8, curve1StartPoint);context.SetFillColor(color1);context.AddPath(path1);context.FillPath();//第二条曲线CGPath path2 = new CGPath();path2.MoveToPoint(curve2StartPoint);CGPoint rendp = new CGPoint(144, 154).MagnifyPoint(scale);path2.AddCurveToPoint(rcp1, rcp2, rendp);CGPoint rendp2 = new CGPoint(180, 110).MagnifyPoint(scale);path2.AddCurveToPoint(rcp3, rcp4, rendp2);path2.AddCurveToPoint(rcp5, rcp6, curve2EndPoint);path2.AddCurveToPoint(rcp7, rcp8, curve2StartPoint);context.SetFillColor(color3);context.AddPath(path2);context.FillPath();//眼睛context.SetFillColor(NSColor.Black.CGColor);CGPoint leftEyeCenterPoint = new CGPoint(119,165).MagnifyPoint(scale);CGPoint rightEyeCenterPoint = new CGPoint(147,181).MagnifyPoint(scale);float angle = (float)(36f / 180 * Math.PI);float eyeAngle=(float)(EyeRotateAngle / 180 * Math.PI);context.TranslateCTM(leftEyeCenterPoint.X,leftEyeCenterPoint.Y);//移动光标到指定位置context.RotateCTM(angle);float cornerWidth = eyeLineWidth / 2 * scale;context.RotateCTM(eyeAngle);CGPath leftEyePath1 = new CGPath();leftEyePath1.AddRoundedRect(new CGRect(-cornerWidth, -cornerWidth, eyeLineWidth * scale, eyeWidth * scale), cornerWidth, cornerWidth);context.AddPath(leftEyePath1);context.FillPath();context.RotateCTM(-eyeAngle);context.RotateCTM((float)(Math.PI)-eyeAngle);CGPath leftEyePath2 = new CGPath();leftEyePath2.AddRoundedRect(new CGRect(-cornerWidth, -cornerWidth, eyeLineWidth * scale, eyeWidth * scale), cornerWidth, cornerWidth);context.AddPath(leftEyePath2);context.FillPath();context.RotateCTM(eyeAngle-(float)(Math.PI));context.RotateCTM(-angle);//转回去context.TranslateCTM(-leftEyeCenterPoint.X, -leftEyeCenterPoint.Y);context.TranslateCTM(rightEyeCenterPoint.X, rightEyeCenterPoint.Y);//移动光标到指定位置context.RotateCTM(angle);context.RotateCTM(eyeAngle+(float)(Math.PI));CGPath rightEyePath1 = new CGPath();rightEyePath1.AddRoundedRect(new CGRect(-cornerWidth, -cornerWidth, eyeLineWidth * scale, eyeWidth * scale), cornerWidth, cornerWidth);context.AddPath(rightEyePath1);context.FillPath();context.RotateCTM(-eyeAngle-(float)(Math.PI));context.RotateCTM(-eyeAngle);CGPath rightEyePath2 = new CGPath();rightEyePath2.AddRoundedRect(new CGRect(-cornerWidth, -cornerWidth, eyeLineWidth * scale, eyeWidth * scale), cornerWidth, cornerWidth);context.AddPath(rightEyePath2);context.FillPath();context.RotateCTM(eyeAngle);context.RotateCTM(-angle);//转回去context.TranslateCTM(-rightEyeCenterPoint.X, -rightEyeCenterPoint.Y);//嘴巴CGPath mousePaht = new CGPath();CGPoint mousePoint1 = new CGPoint(118,134).MagnifyPoint(scale);CGPoint mousePoint2 = new CGPoint(165,165).MagnifyPoint(scale);mousePaht.MoveToPoint(mousePoint1);mousePaht.AddCurveToPoint(MouthControlP1, MouthControlP2, mousePoint2);context.SetLineWidth(5*scale);context.AddPath(mousePaht);context.StrokePath();context.SetFillColor(NSColor.Black.CGColor);CGRect mouseRect1 = new CGRect(mousePoint1.X-(2.5f*scale),mousePoint1.Y - (2.5f * scale),5 * scale,5 * scale);CGRect mouseRect2 = new CGRect(mousePoint2.X - (2.5f * scale), mousePoint2.Y - (2.5f * scale), 5 * scale,5 * scale);context.FillEllipseInRect(mouseRect1);context.FillEllipseInRect(mouseRect2);//手臂CGPoint leftArmP1 = new CGPoint(48,106).MagnifyPoint(scale);CGPoint leftArmP2 = new CGPoint(129,95).MagnifyPoint(scale);CGPoint rightArmP1 = new CGPoint(188,189).MagnifyPoint(scale);CGPoint rightArmP2 = new CGPoint(163,115).MagnifyPoint(scale);CGPath armPath = new CGPath();armPath.MoveToPoint(leftArmP1);armPath.AddCurveToPoint(LeftArmCP1,LeftArmCP2,leftArmP2);armPath.MoveToPoint(rightArmP1);armPath.AddCurveToPoint(RightArmCP1,RightArmCP2,rightArmP2);context.AddPath(armPath);context.SetLineWidth(8*scale);context.StrokePath();CGPoint leftHandP = leftArmP2;CGPoint rightHandP = rightArmP2;CGPath leftHandPath = new CGPath();leftHandPath.AddRoundedRect(new CGRect(-5* scale, -4* scale, 10* scale, 28* scale), 5* scale, 5* scale);float handAngle = (float)(HandRotateAngle/180 * Math.PI);context.TranslateCTM(leftHandP.X, leftHandP.Y);//移动光标到指定位置context.RotateCTM(handAngle);context.AddPath(leftHandPath);context.FillPath();context.RotateCTM(-handAngle);//转回去context.TranslateCTM(-leftHandP.X, -leftHandP.Y);CGPath rightHandPath = new CGPath();rightHandPath.AddRoundedRect(new CGRect(-5* scale, -24* scale, 10* scale, 28* scale), 5* scale, 5* scale);context.TranslateCTM(rightHandP.X, rightHandP.Y);//移动光标到指定位置context.RotateCTM(handAngle);context.AddPath(rightHandPath);context.FillPath();context.RotateCTM(-handAngle);//转回去context.TranslateCTM(-rightHandP.X, -rightHandP.Y);if (showLighting){CGPoint lightningCenterP = new CGPoint((leftArmP2.X + rightArmP2.X) / 2.0f, (leftArmP2.Y + rightArmP2.Y) / 2.0f);CGPath lightningPath = new CGPath();lightningPath.MoveToPoint(lightningP1);lightningPath.AddLineToPoint(lightningP2);lightningPath.AddLineToPoint(lightningP3);lightningPath.AddLineToPoint(lightningP4);lightningPath.AddLineToPoint(lightningP5);lightningPath.AddLineToPoint(lightningP6);lightningPath.AddLineToPoint(lightningP1);lightningPath.CloseSubpath();context.TranslateCTM(lightningCenterP.X, lightningCenterP.Y);//移动光标到指定位置context.RotateCTM(handAngle);context.AddPath(lightningPath);context.SetFillColor(new CGColor(1, 213 / 255f, LightningAlpha));context.FillPath();context.RotateCTM(-handAngle);//转回去context.TranslateCTM(-lightningCenterP.X, -lightningCenterP.Y);}}}}

Demo可以从下面的地址下载:

Xamarin.Mac版本转场动画Demo

ios上的实现原理和Mac上的相识,只不多ios中的y坐标系和mac上是相反的,所以需要进行上下翻转,代码相识,这里就不写了。


网页版本是通过svg实现的,具体代码如下:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml" ><head><meta charset="utf-8">    <title>svg网页版地球动画</title></head><body><svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="256" height="256"  xml:space="preserve" id="canvas1">    <circle id="canvas1-oval" stroke="rgb(0, 0, 0)" stroke-width="8" fill="rgb(85, 198, 237)" cx="128" cy="128" r="88" >    <animate attributeName="fill" values="rgb(85, 198, 237);rgb(0, 159, 239);rgb(85, 198, 237)" dur="1.5s" repeatCount="indefinite" />    </circle>    <path id="canvas1-bezier1" stroke-width="0" stroke="rgb(0, 159, 239)" fill="rgb(0, 159, 239)" d="M 53.5 89 C 97 94 112 113 100 142 C 87 175 116 200 140 184 C 147 182 156 179 178 195.5 A84 84 0 0 1 53.5 89">    <animate attributeName="fill" values="rgb(0, 159, 239);rgb(153, 223, 246);rgb(85, 198, 237)" dur="1.5s" repeatCount="indefinite" />    </path>    <path id="canvas1-bezier2" stroke-width="0" stroke="rgb(0, 159, 239)" fill="rgb(153, 223, 246)" d="M 116 44.5 C 122 59 165 63 144 102 C 134 123 153 151 180 146 C 194 139 195 136 210 144.5 A84 84 0 0 0 116 44.5">    <animate attributeName="fill" values="rgb(153, 223, 246);rgb(85, 198, 237);rgb(0, 159, 239)" dur="1.5s" repeatCount="indefinite" />    </path>    <path id="canvas1-leftArm" stroke-width="8" stroke="rgb(0, 0, 0)" fill="none" d="M 45 150 C -6 197 70 187 129 161" />    <path id="canvas1-rightArm" stroke-width="8" stroke="rgb(0, 0, 0)" fill="none" d="M 189 67 C 253 48 222 100 163 141" />    <path id="canvas1-mouse" stroke-width="5" stroke="rgb(0, 0, 0)" fill="none" d="M 118 122 C 120 93.5 151 92.5 165 91" >    <animate attributeName="d" values="M 118 122 C 120 93.5 151 92.5 165 91;M 118 122 C 149.5 115.5 174.5 111 165 91;M 118 122 C 120 93.5 151 92.5 165 91" dur="3s" repeatCount="indefinite" />    </path>    <circle id="canvas1-leftMouthPoint" stroke="none" fill="rgb(0, 0, 0)" cx="118" cy="122" r="2.5" />    <circle id="canvas1-rightMouthPoint" stroke="none" fill="rgb(0, 0, 0)" cx="165" cy="91" r="2.5" />        <rect id="leftHand" x="122" y="154" width="30" height="12" rx="6" ry="6" stroke="none" fill="rgb(0, 0, 0)" transform="rotate(-120 128 159)">    <animateTransform attributeName="transform" begin="0s" dur="3s" type="rotate" values="-120 128 159;-60 128 159;-120 128 159" repeatCount="indefinite"/>    </rect>        <rect id="rightHand" x="159" y="135" width="30" height="12" rx="6" ry="6" stroke="none" fill="rgb(0, 0, 0)" transform="rotate(60 163 141)">    <animateTransform attributeName="transform" begin="0s" dur="3s" type="rotate" values="60 163 141;120 163 141;60 163 141" repeatCount="indefinite"/>    </rect>        <rect id="leftEye1" x="119" y="93.5" width="26" height="5" rx="2.5" ry="2.5" stroke="none" fill="rgb(0, 0, 0)" transform="rotate(165 121.5 96)">    <animateTransform attributeName="transform" begin="0s" dur="3s" type="rotate" values="165 121.5 96;225 124 96;165 121.5 96" repeatCount="indefinite"/>    <animate attributeName="y" values="93.5;91;93.5" dur="3s" repeatCount="indefinite" />    <animate attributeName="width" values="26;16;26" dur="3s" repeatCount="indefinite" />    <animate attributeName="height" values="5;10;5" dur="3s" repeatCount="indefinite" />    <animate attributeName="rx" values="2.5;5;2.5" dur="3s" repeatCount="indefinite" />    <animate attributeName="ry" values="2.5;5;2.5" dur="3s" repeatCount="indefinite" />    </rect>        <rect id="leftEye2" x="119" y="93.5" width="26" height="5" rx="2.5" ry="2.5" stroke="none" fill="rgb(0, 0, 0)" transform="rotate(135 121.5 96)">    <animateTransform attributeName="transform" begin="0s" dur="3s" type="rotate" values="135 121.5 96;45 124 96;135 121.5 96" repeatCount="indefinite"/>    <animate attributeName="y" values="93.5;91;93.5" dur="3s" repeatCount="indefinite" />    <animate attributeName="width" values="26;16;26" dur="3s" repeatCount="indefinite" />    <animate attributeName="height" values="5;10;5" dur="3s" repeatCount="indefinite" />    <animate attributeName="rx" values="2.5;5;2.5" dur="3s" repeatCount="indefinite" />    <animate attributeName="ry" values="2.5;5;2.5" dur="3s" repeatCount="indefinite" />    </rect>        <rect id="rightEye1" x="147" y="77.5" width="26" height="5" rx="2.5" ry="2.5" stroke="none" fill="rgb(0, 0, 0)" transform="rotate(-15 149.5 80)">    <animateTransform attributeName="transform" begin="0s" dur="3s" type="rotate" values="-15 149.5 80;45 152 80;-15 149.5 80" repeatCount="indefinite"/>    <animate attributeName="y" values="77.5;75;77.5" dur="3s" repeatCount="indefinite" />    <animate attributeName="width" values="26;16;26" dur="3s" repeatCount="indefinite" />    <animate attributeName="height" values="5;10;5" dur="3s" repeatCount="indefinite" />    <animate attributeName="rx" values="2.5;5;2.5" dur="3s" repeatCount="indefinite" />    <animate attributeName="ry" values="2.5;5;2.5" dur="3s" repeatCount="indefinite" />    </rect>        <rect id="rightEye2" x="147" y="77.5" width="26" height="5" rx="2.5" ry="2.5" stroke="none" fill="rgb(0, 0, 0)" transform="rotate(-45 149.5 80)">    <animateTransform attributeName="transform" begin="0s" dur="3s" type="rotate" values="-45 149.5 80;-135 152 80;-45 149.5 80" repeatCount="indefinite"/>    <animate attributeName="y" values="77.5;75;77.5" dur="3s" repeatCount="indefinite" />    <animate attributeName="width" values="26;16;26" dur="3s" repeatCount="indefinite" />    <animate attributeName="height" values="5;10;5" dur="3s" repeatCount="indefinite" />    <animate attributeName="rx" values="2.5;5;2.5" dur="3s" repeatCount="indefinite" />    <animate attributeName="ry" values="2.5;5;2.5" dur="3s" repeatCount="indefinite" />    </rect>    <path id="canvas1-ligtning" stroke="none" fill="rgb(255,206,31)" d="M -11 -4 L -1 -1 -1 -5 11 4 1 1 1 5 -11 -4">        <animate attributeName="d" values="M -11 -4 L -1 -1 -1 -5 11 4 1 1 1 5 -11 -4;M -5.5 -2 L -0.5 -0.5 -0.5 -2.5 5.5 2 0.5 0.5 0.5 2.5 -5.5 -2;M -11 -4 L -1 -1 -1 -5 11 4 1 1 1 5 -11 -4" dur="3s" repeatCount="indefinite"/>        <animateTransform attributeName="transform" type="translate" values="146 151;146 151" dur="3s" repeatCount="indefinite" additive="sum"/>        <animateTransform attributeName="transform" begin="0s" dur="3s" type="rotate" values="-45 0 0;5 0 0;-45 0 0" repeatCount="indefinite" additive="sum"/>    </path></svg></body></html>

SVG动画相关的知识可以从参考下面的网址:

svg动画相关

Windows版本(WPF)是通过Storyboard的动画来实现的,具体代码如下:

<UserControl             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"              xmlns:d="http://schemas.microsoft.com/expression/blend/2008"              xmlns:local="clr-namespace:earthAnimate"             xmlns:ed="http://schemas.microsoft.com/expression/2010/drawing" x:Class="earthAnimate.LoadAnimate"             mc:Ignorable="d"              d:DesignHeight="300" d:DesignWidth="300" Width="250" Height="250">    <UserControl.Resources>        <Storyboard x:Key="LoadingAnimate" RepeatBehavior="Forever">            <PointAnimationUsingKeyFrames Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[0].(BezierSegment.Point2)" Storyboard.TargetName="path">                <EasingPointKeyFrame KeyTime="0" Value="26.0063068619414,1.29245203797722"/>                <EasingPointKeyFrame KeyTime="0:0:1" Value="52.0063333333333,29.293"/>                <EasingPointKeyFrame KeyTime="0:0:2" Value="26.0063068619414,1.29245203797722"/>            </PointAnimationUsingKeyFrames>            <PointAnimationUsingKeyFrames Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[0].(BezierSegment.Point3)" Storyboard.TargetName="path">                <EasingPointKeyFrame KeyTime="0" Value="53.0779179714247,12.6239846356512"/>                <EasingPointKeyFrame KeyTime="0:0:1" Value="47.1432691945085,10.4907378598698"/>                <EasingPointKeyFrame KeyTime="0:0:2" Value="53.0779179714247,12.6239846356512"/>            </PointAnimationUsingKeyFrames>            <PointAnimationUsingKeyFrames Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.StartPoint)" Storyboard.TargetName="path">                <EasingPointKeyFrame KeyTime="0" Value="8.00601015857884,26.6251668973387"/>                <EasingPointKeyFrame KeyTime="0:0:1" Value="10.673,23.9596666666667"/>                <EasingPointKeyFrame KeyTime="0:0:2" Value="8.00601015857884,26.6251668973387"/>            </PointAnimationUsingKeyFrames>            <PointAnimationUsingKeyFrames Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[0].(BezierSegment.Point1)" Storyboard.TargetName="path">                <EasingPointKeyFrame KeyTime="0" Value="8.00601015857884,26.6251668973387"/>                <EasingPointKeyFrame KeyTime="0:0:1" Value="10.673,23.9596666666667"/>                <EasingPointKeyFrame KeyTime="0:0:2" Value="8.00601015857884,26.6251668973387"/>            </PointAnimationUsingKeyFrames>            <PointAnimationUsingKeyFrames Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.StartPoint)" Storyboard.TargetName="path1">                <EasingPointKeyFrame KeyTime="0" Value="2.99999998384646,14.8115542651442"/>                <EasingPointKeyFrame KeyTime="0:0:1" Value="21.4113333333333,9.667"/>                <EasingPointKeyFrame KeyTime="0:0:2" Value="2.99999998384646,14.8115542651442"/>            </PointAnimationUsingKeyFrames>            <PointAnimationUsingKeyFrames Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[1].(LineSegment.Point)" Storyboard.TargetName="path1">                <EasingPointKeyFrame KeyTime="0" Value="13.0927202192036,33.6863477007917"/>                <EasingPointKeyFrame KeyTime="0:0:1" Value="26.828,22.667"/>                <EasingPointKeyFrame KeyTime="0:0:2" Value="13.0927202192036,33.6863477007917"/>            </PointAnimationUsingKeyFrames>            <PointAnimationUsingKeyFrames Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[1].(LineSegment.Point)" Storyboard.TargetName="path2">                <EasingPointKeyFrame KeyTime="0" Value="11.0927202192036,31.3470675723126"/>                <EasingPointKeyFrame KeyTime="0:0:1" Value="27.337,21.292"/>                <EasingPointKeyFrame KeyTime="0:0:2" Value="11.0927202192036,31.3470675723126"/>            </PointAnimationUsingKeyFrames>            <PointAnimationUsingKeyFrames Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.StartPoint)" Storyboard.TargetName="path2">                <EasingPointKeyFrame KeyTime="0" Value="2.99999998384645,13.4722741366651"/>                <EasingPointKeyFrame KeyTime="0:0:1" Value="22.0870000000001,8.29200000000014"/>                <EasingPointKeyFrame KeyTime="0:0:2" Value="2.99999998384645,13.4722741366651"/>            </PointAnimationUsingKeyFrames>            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)" Storyboard.TargetName="path3">                <EasingDoubleKeyFrame KeyTime="0" Value="1"/>                <EasingDoubleKeyFrame KeyTime="0:0:1" Value="0"/>                <EasingDoubleKeyFrame KeyTime="0:0:2" Value="1"/>            </DoubleAnimationUsingKeyFrames>            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)" Storyboard.TargetName="path3">                <EasingDoubleKeyFrame KeyTime="0" Value="1"/>                <EasingDoubleKeyFrame KeyTime="0:0:1" Value="0"/>                <EasingDoubleKeyFrame KeyTime="0:0:2" Value="1"/>            </DoubleAnimationUsingKeyFrames>            <PointAnimationUsingKeyFrames Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.StartPoint)" Storyboard.TargetName="path5">                <EasingPointKeyFrame KeyTime="0" Value="15.6546741275458,20.9010035613603"/>                <EasingPointKeyFrame KeyTime="0:0:1" Value="15.6546741275458,20.9010035613603"/>                <EasingPointKeyFrame KeyTime="0:0:2" Value="15.6546741275458,20.9010035613603"/>            </PointAnimationUsingKeyFrames>            <PointAnimationUsingKeyFrames Storyboard.TargetProperty="(Path.Data).(PathGeometry.Figures)[0].(PathFigure.Segments)[0].(LineSegment.Point)" Storyboard.TargetName="path4">                <EasingPointKeyFrame KeyTime="0" Value="2.49999572951243,2.50000361637382"/>                <EasingPointKeyFrame KeyTime="0:0:1" Value="2.49999572951243,2.50000361637382"/>                <EasingPointKeyFrame KeyTime="0:0:2" Value="2.49999572951243,2.50000361637382"/>            </PointAnimationUsingKeyFrames>            <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="b1">                <EasingColorKeyFrame KeyTime="0" Value="#FF00B0F5"/>                <EasingColorKeyFrame KeyTime="0:0:0.333" Value="#FF8BE6F7"/>                <EasingColorKeyFrame KeyTime="0:0:0.7" Value="#FF00D4F1"/>                <EasingColorKeyFrame KeyTime="0:0:1" Value="#FF00B0F5"/>                <EasingColorKeyFrame KeyTime="0:0:1.333" Value="#FF8BE6F7"/>                <EasingColorKeyFrame KeyTime="0:0:1.7" Value="#FF00D4F1"/>                <EasingColorKeyFrame KeyTime="0:0:2" Value="#FF00B0F5"/>            </ColorAnimationUsingKeyFrames>            <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="b2">                <EasingColorKeyFrame KeyTime="0" Value="#FF00D4F1"/>                <EasingColorKeyFrame KeyTime="0:0:0.333" Value="#FF00B0F5"/>                <EasingColorKeyFrame KeyTime="0:0:0.7" Value="#FF8BE6F7"/>                <EasingColorKeyFrame KeyTime="0:0:1" Value="#FF00D4F1"/>                <EasingColorKeyFrame KeyTime="0:0:1.333" Value="#FF00B0F5"/>                <EasingColorKeyFrame KeyTime="0:0:1.7" Value="#FF8BE6F7"/>                <EasingColorKeyFrame KeyTime="0:0:2" Value="#FF00D4F1"/>            </ColorAnimationUsingKeyFrames>            <ColorAnimationUsingKeyFrames x:Name="colorAnimationUsingKeyFrames" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="b3">                <EasingColorKeyFrame KeyTime="0" Value="#FF8BE6F7"/>                <EasingColorKeyFrame KeyTime="0:0:0.333" Value="#FF00D4F1"/>                <EasingColorKeyFrame KeyTime="0:0:0.7" Value="#FF00B0F5"/>                <EasingColorKeyFrame KeyTime="0:0:1" Value="#FF8BE6F7"/>                <EasingColorKeyFrame KeyTime="0:0:1.333" Value="#FF00D4F1"/>                <EasingColorKeyFrame KeyTime="0:0:1.7" Value="#FF00B0F5"/>                <EasingColorKeyFrame KeyTime="0:0:2" Value="#FF8BE6F7"/>            </ColorAnimationUsingKeyFrames>            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)" Storyboard.TargetName="path4">                <EasingDoubleKeyFrame KeyTime="0" Value="0"/>                <EasingDoubleKeyFrame KeyTime="0:0:1" Value="30"/>                <EasingDoubleKeyFrame KeyTime="0:0:2" Value="0"/>            </DoubleAnimationUsingKeyFrames>            <PointAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransformOrigin)" Storyboard.TargetName="path4">                <EasingPointKeyFrame KeyTime="0" Value="0.5,0.5"/>                <EasingPointKeyFrame KeyTime="0:0:1" Value="0.5,1"/>                <EasingPointKeyFrame KeyTime="0:0:2" Value="0.5,0.5"/>            </PointAnimationUsingKeyFrames>            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)" Storyboard.TargetName="path5">                <EasingDoubleKeyFrame KeyTime="0" Value="0"/>                <EasingDoubleKeyFrame KeyTime="0:0:1" Value="30"/>                <EasingDoubleKeyFrame KeyTime="0:0:2" Value="0"/>            </DoubleAnimationUsingKeyFrames>            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.StrokeThickness)" Storyboard.TargetName="path1">                <EasingDoubleKeyFrame KeyTime="0" Value="6"/>                <EasingDoubleKeyFrame KeyTime="0:0:1" Value="8"/>                <EasingDoubleKeyFrame KeyTime="0:0:2" Value="6"/>            </DoubleAnimationUsingKeyFrames>            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.StrokeThickness)" Storyboard.TargetName="path2">                <EasingDoubleKeyFrame KeyTime="0" Value="6"/>                <EasingDoubleKeyFrame KeyTime="0:0:1" Value="8"/>                <EasingDoubleKeyFrame KeyTime="0:0:2" Value="6"/>            </DoubleAnimationUsingKeyFrames>        </Storyboard>    </UserControl.Resources>    <UserControl.Triggers>        <EventTrigger RoutedEvent="FrameworkElement.Loaded">            <BeginStoryboard Storyboard="{StaticResource LoadingAnimate}"/>        </EventTrigger>    </UserControl.Triggers>    <Border Background="#FF777778" BorderThickness="0" CornerRadius="20">        <Grid HorizontalAlignment="Center" VerticalAlignment="Center">            <Path x:Name="b2" Data="M49.25882,2.5 L49.891563,2.7516928 C99.700253,22.805404 93.89454,22.542268 106.69724,38.543294 119.37159,54.383912 131.67212,47.689239 136.78944,95.631171 L136.85231,96.256896 136.25598,97.943831 C128.63833,118.21517 112.2016,134.17039 91.62009,141.13518 L90.697735,141.43463 90.425785,140.36446 C84.315968,118.13202 56.595196,123.86007 46.366886,106.9448 33.468063,85.61312 78.159336,46.724566 4.1379318,42.211658 L2.5,42.118983 3.0165176,41.012725 C11.798109,22.78795 27.978783,8.7994452 47.661499,2.944242 z" HorizontalAlignment="Center" Height="137.267" Margin="59.633,57.056,57.515,55.677" Stretch="Fill" Stroke="Black" StrokeThickness="0" VerticalAlignment="Center" Width="132.852" Fill="#FF00D4F1"/>            <Path x:Name="b3" Data="M21.6163,2.5 C61.656945,2.5 94.1163,34.959354 94.1163,75.000004 94.1163,83.133259 92.777036,90.953709 90.307004,98.252857 L90.100873,98.838108 77.418249,122.8896 C84.580697,82.416445 55.453409,93.956983 50.678444,73.639133 44.269802,46.369864 73.598277,17.561866 -7.0986351,10.735069 L2.5,5.0523987 3.4974225,4.7824936 C9.2886889,3.2924652 15.359949,2.5 21.6163,2.5 z" Margin="90,52.556,54.015,74" Stretch="Fill" Stroke="Black" StrokeThickness="0" Fill="#FF8BE6F7" Height="123.444" VerticalAlignment="Center" HorizontalAlignment="Center" Width="105.985"/>            <Path x:Name="b1" Data="M9.1327693,2.5 L10.770701,2.5926743 C84.792105,7.1055832 40.100833,45.994137 52.999655,67.325817 63.227965,84.241085 90.948737,78.513035 97.058554,100.74547 L97.330504,101.81565 96.559279,102.06603 C89.748709,104.18435 82.507621,105.32549 74.999999,105.32549 34.959353,105.32549 2.4999988,72.866131 2.5,32.825489 2.4999988,22.189693 4.7902219,12.088806 8.9044149,2.9890862 z" HorizontalAlignment="Center" Height="104.825" Margin="53,92.175,100.169,53" Stretch="Fill" Stroke="Black" StrokeThickness="0" VerticalAlignment="Center" Width="96.831" Fill="#FF00B0F5"/>            <Ellipse Margin="0" Stroke="Black" Width="150" Height="150" HorizontalAlignment="Center" VerticalAlignment="Center" StrokeThickness="5" d:IsLocked="True"/>            <Path Data="M58.525936,156.73119 C7.8860635,210.3776 92.219771,185.79201 128.35962,164.64614" Height="37.34" Margin="40.891,154.585,118.5,58.075" Stretch="Fill" Stroke="Black" StrokeThickness="5" VerticalAlignment="Center" StrokeDashCap="Round" StrokeStartLineCap="Round" StrokeEndLineCap="Round" HorizontalAlignment="Center" Width="90.609" d:IsLocked="True"/>            <Path Data="M198.32214,99.08387 C255.98402,87.950505 213.3333,138.58305 171.49993,161.83333" HorizontalAlignment="Center" Margin="157.5,82.507,32.66,98.167" Stretch="Fill" Stroke="Black" StrokeThickness="5" Width="59.84" StrokeStartLineCap="Round" StrokeEndLineCap="Round" Height="69.326" VerticalAlignment="Center" d:IsLocked="True"/>            <Path x:Name="path4" Margin="125.063,144.021,117.937,82.578" Stroke="Black" StrokeThickness="7" VerticalAlignment="Center" StrokeEndLineCap="Round" StrokeDashCap="Round" StrokeStartLineCap="Round" HorizontalAlignment="Center" Stretch="Fill" RenderTransformOrigin="0.5,1" d:IsLocked="True">                <Path.RenderTransform>                    <TransformGroup>                        <ScaleTransform/>                        <SkewTransform/>                        <RotateTransform/>                        <TranslateTransform/>                    </TransformGroup>                </Path.RenderTransform>                <Path.Data>                    <PathGeometry>                        <PathFigure StartPoint="3.96799520310798,20.9010028484696">                            <LineSegment Point="2.49999572951243,2.50000361637382"/>                        </PathFigure>                    </PathGeometry>                </Path.Data>            </Path>            <Path x:Name="path5" Margin="157.5,146.877,85.5,79.722" Stroke="Black" StrokeThickness="7" VerticalAlignment="Center" StrokeEndLineCap="Round" StrokeDashCap="Round" StrokeStartLineCap="Round" HorizontalAlignment="Center" Stretch="Fill" RenderTransformOrigin="0.5,0" d:IsLocked="True">                <Path.RenderTransform>                    <TransformGroup>                        <ScaleTransform/>                        <SkewTransform/>                        <RotateTransform/>                        <TranslateTransform/>                    </TransformGroup>                </Path.RenderTransform>                <Path.Data>                    <PathGeometry>                        <PathFigure StartPoint="15.6546741275458,20.9010035613603">                            <LineSegment Point="14.1866746539502,2.50000432926441"/>                        </PathFigure>                    </PathGeometry>                </Path.Data>            </Path>            <Path x:Name="path1" Margin="96.422,84.333,111.667,128.981" Stroke="Black" StrokeThickness="6" StrokeStartLineCap="Round" StrokeEndLineCap="Round" StrokeDashCap="Round" StrokeLineJoin="Round" Height="36.686" VerticalAlignment="Center" HorizontalAlignment="Center" Width="41.911" d:IsLocked="True">                <Path.Data>                    <PathGeometry>                        <PathFigure StartPoint="2.99999998384646,14.8115542651442">                            <LineSegment Point="23.9451613192717,16.0578231031614"/>                            <LineSegment Point="13.0927202192036,33.6863477007917"/>                        </PathFigure>                    </PathGeometry>                </Path.Data>            </Path>            <Path x:Name="path2" HorizontalAlignment="Center" Margin="150.275,83.167,68.369,132.486" Stroke="Black" StrokeThickness="6" Width="31.356" StrokeStartLineCap="Round" StrokeEndLineCap="Round" StrokeDashCap="Round" StrokeLineJoin="Round" Height="34.347" VerticalAlignment="Center" RenderTransformOrigin="0.5,0.5" d:IsLocked="True">                <Path.Data>                    <PathGeometry>                        <PathFigure StartPoint="2.99999998384645,13.4722741366651">                            <LineSegment Point="24.9451613192717,15.2185429746824"/>                            <LineSegment Point="11.0927202192036,31.3470675723126"/>                        </PathFigure>                    </PathGeometry>                </Path.Data>                <Path.RenderTransform>                    <TransformGroup>                        <ScaleTransform/>                        <SkewTransform/>                        <RotateTransform Angle="180"/>                        <TranslateTransform X="-5.6689999999999969" Y="-12.346999999999994"/>                    </TransformGroup>                </Path.RenderTransform>            </Path>            <Path x:Name="path" Margin="115.327,102.707,75.267,111.582" StrokeStartLineCap="Round" StrokeEndLineCap="Round" Stroke="Black" StrokeThickness="4" StrokeLineJoin="Round" Height="35.711" VerticalAlignment="Center" HorizontalAlignment="Center" Width="59.406" d:IsLocked="True">                <Path.Data>                    <PathGeometry>                        <PathFigure StartPoint="8.00601015857884,26.6251668973387">                            <BezierSegment Point3="53.0779179714247,12.6239846356512" Point2="26.0063068619414,1.29245203797722" Point1="8.00601015857884,26.6251668973387"/>                        </PathFigure>                    </PathGeometry>                </Path.Data>            </Path>            <Path x:Name="path3" Data="M144.625,147.623 L141,159.873 145.125,159 146.25,166.748 150,153.998 145.625,155.123 z" Fill="#FFE2E68A" HorizontalAlignment="Center" Height="20.125" Margin="139.5,148.875,100.5,81" Stretch="Fill" Stroke="Black" VerticalAlignment="Center" Width="10" StrokeThickness="0" RenderTransformOrigin="0.5,0.5" d:IsLocked="True">                <Path.RenderTransform>                    <TransformGroup>                        <ScaleTransform/>                        <SkewTransform/>                        <RotateTransform Angle="90"/>                        <TranslateTransform/>                    </TransformGroup>                </Path.RenderTransform>            </Path>        </Grid>    </Border></UserControl>

WPF版本的Demo可以从这里下载:


WPF版本转场动画


Android版本的转场动画和ios的原理相似,只不过是方法名称有些细微差别,具体代码如下:

// <copyright company="上海诸君信息科技有限公司">上海诸君信息科技有限公司版权所有</copyright>// <author>海学权</author>//using System;using Android.Content;using Android.Graphics;using Android.Views;using Java.Util;namespace LoadingViewForAndroid{public class LoadingView:View{protected Context _context;public float Scale { get; set; }//圆形里面的三种颜色public Color color1;public Color color2;public Color color3;//第一条曲线的起始点public PointF curve1StartPoint;//第一条曲线的结束点public PointF curve1EndPoint;//第二条曲线的起始点public PointF curve2StartPoint;//第二条曲线的结束点public PointF curve2EndPoint;//圆里面第一条曲线的贝塞尔控制点public PointF cp1;public PointF cp2;public PointF cp3;public PointF cp4;public PointF cp5;public PointF cp6;public PointF cp7;public PointF cp8;//圆里面第二条曲线的贝塞尔控制点public PointF rcp1;public PointF rcp2;public PointF rcp3;public PointF rcp4;public PointF rcp5;public PointF rcp6;public PointF rcp7;public PointF rcp8;//闪电路径中的点public PointF lightningP1;public PointF lightningP2;public PointF lightningP3;public PointF lightningP4;public PointF lightningP5;public PointF lightningP6;//嘴的贝塞尔控制点public PointF MouthControlP1;public PointF MouthControlP2;//左胳膊的贝塞尔控制点public PointF LeftArmCP1;public PointF LeftArmCP2;//右胳膊贝塞尔控制点public PointF RightArmCP1;public PointF RightArmCP2;//眼睛的旋转角度public float EyeRotateAngle;float eyeWidth = 26;float eyeLineWidth = 4;//手的旋转角度public float HandRotateAngle;//是否要动化显示的标记bool animationFlag = true;float LightningAlpha = 0;bool showLighting = true;public LoadingView(Context context,float scale):base(context){this._context = context;this.Scale = scale;curve1StartPoint = new PointF(58, 167).MagnifyPoint(scale);curve1EndPoint = new PointF(174, 62.5f).MagnifyPoint(scale);curve2StartPoint = new PointF(120, 207.75f).MagnifyPoint(scale);curve2EndPoint = new PointF(206.5f, 112.5f).MagnifyPoint(scale);//为属性设置初始值color1 = new Color(0, 159, 239);color2 = new Color(85, 198, 237);color3 = new Color(153, 223, 246);cp1 = new PointF(97, 162).MagnifyPoint(scale);cp2 = new PointF(112, 143).MagnifyPoint(scale);cp3 = new PointF(87, 81).MagnifyPoint(scale);cp4 = new PointF(116, 56).MagnifyPoint(scale);cp5 = new PointF(147, 74).MagnifyPoint(scale);cp6 = new PointF(156, 77).MagnifyPoint(scale);cp7 = new PointF(101, 14.5f).MagnifyPoint(scale);cp8 = new PointF(19.75f, 91.5f).MagnifyPoint(scale);rcp1 = new PointF(122, 197).MagnifyPoint(scale);rcp2 = new PointF(165, 193).MagnifyPoint(scale);rcp3 = new PointF(134, 133).MagnifyPoint(scale);rcp4 = new PointF(153, 105).MagnifyPoint(scale);rcp5 = new PointF(194, 117).MagnifyPoint(scale);rcp6 = new PointF(195, 120).MagnifyPoint(scale);rcp7 = new PointF(215.75f, 156.5f).MagnifyPoint(scale);rcp8 = new PointF(183.5f, 213.25f).MagnifyPoint(scale);lightningP1 = new PointF(-11, 4).MagnifyPoint(scale);lightningP2 = new PointF(-1, 1).MagnifyPoint(scale);lightningP3 = new PointF(-1, 5).MagnifyPoint(scale);lightningP4 = new PointF(11, -4).MagnifyPoint(scale);lightningP5 = new PointF(1, -1).MagnifyPoint(scale);lightningP6 = new PointF(1, -5).MagnifyPoint(scale);//CGPoint mouseControlStartP1 = new CGPoint(148.5f,180);//CGPoint mouseControlStartP2 = new CGPoint(156,172.5f);PointF mouseControlStartP1 = new PointF(120, 162.5f);PointF mouseControlStartP2 = new PointF(151, 163.5f);PointF mouseControlEndP1 = new PointF(149.5f, 140.5f);PointF mouseControlEndP2 = new PointF(174.5f, 145);MouthControlP1 = mouseControlStartP1.MagnifyPoint(scale);MouthControlP2 = mouseControlStartP2.MagnifyPoint(scale);LeftArmCP1 = new PointF(-6, 59).MagnifyPoint(scale);LeftArmCP2 = new PointF(70, 69).MagnifyPoint(scale);RightArmCP1 = new PointF(253, 208).MagnifyPoint(scale);RightArmCP2 = new PointF(222, 156).MagnifyPoint(scale);EyeRotateAngle = 70;HandRotateAngle = 30;#region timer动画先注释掉//用一个timer不停地重绘来实现颜色交替变化的动画int i = 0;System.Timers.Timer t = new System.Timers.Timer(300);t.Elapsed += delegate (object sender, System.Timers.ElapsedEventArgs e){if (animationFlag){i = (i + 1) % 3;Color tmpcolor = color1;color1 = color3;color3 = color2;color2 = tmpcolor;PostInvalidate();}};t.Enabled = true;t.Start();//嘴巴的贝塞尔控制点的变化范围float diffX1 = ((float)(mouseControlEndP1.X) - (float)(mouseControlStartP1.X)) * scale;float diffX2 = ((float)(mouseControlEndP2.X) - (float)(mouseControlStartP2.X)) * scale;float diffY1 = ((float)(mouseControlEndP1.Y) - (float)(mouseControlStartP1.Y)) * scale;float diffY2 = ((float)(mouseControlEndP2.Y) - (float)(mouseControlStartP2.Y)) * scale;float handAngleDiff = -50;float eyeAngleDiff = -70;float eyeWidthDiff = 8;float eyeLineWidthDiff = 4;//控制动画方向的标识bool eyeAddFlag = true;//用一个timer不停地重绘来实现嘴巴、眼睛、手的动画int j = 0;//帧数float frameCount = 30;System.Timers.Timer t2 = new System.Timers.Timer(50);t2.Elapsed += delegate (object sender, System.Timers.ElapsedEventArgs e){if (animationFlag == false){return;}if (eyeAddFlag){j = j + 1;if (j > frameCount){eyeAddFlag = false;}EyeRotateAngle += 1 / (float)frameCount * eyeAngleDiff;eyeWidth -= 1 / (float)frameCount * eyeWidthDiff;eyeLineWidth += 1 / (float)frameCount * eyeLineWidthDiff;HandRotateAngle += 1 / (float)frameCount * handAngleDiff;MouthControlP1 = new PointF(MouthControlP1.X + (diffX1 / frameCount), MouthControlP1.Y + (diffY1 / frameCount));MouthControlP2 = new PointF(MouthControlP2.X + (diffX2 / frameCount), MouthControlP2.Y + (diffY2 / frameCount));}else{j = j - 1;if (j < 0){eyeAddFlag = true;}EyeRotateAngle -= 1 / (float)frameCount * eyeAngleDiff;eyeWidth += 1 / (float)frameCount * eyeWidthDiff;eyeLineWidth -= 1 / (float)frameCount * eyeLineWidthDiff;HandRotateAngle -= 1 / (float)frameCount * handAngleDiff;MouthControlP1 = new PointF(MouthControlP1.X - (diffX1 / frameCount), MouthControlP1.Y - (diffY1 / frameCount));MouthControlP2 = new PointF(MouthControlP2.X - (diffX2 / frameCount), MouthControlP2.Y - (diffY2 / frameCount));}LightningAlpha = j / frameCount;if (j % 10 == 0){showLighting = true;}else{showLighting = false;}PostInvalidate();};t2.Enabled = true;t2.Start();#endregionthis.RotationX = 180;}protected override void OnDraw(Android.Graphics.Canvas canvas){RectF dirtyRect = new RectF(0,0,256*Scale,256*Scale);canvas.DrawRoundRect(dirtyRect, 25, 25, new Paint(){AntiAlias=true,Color=new Color(255,255,255,128)});//圆形的四周边距float margin = 44 * Scale;//圆形的线宽float lineWidth = 8 * Scale;float circleR = 84 * Scale;canvas.DrawCircle(dirtyRect.Width()/2, dirtyRect.Height() / 2, circleR, new Paint() { AntiAlias=true,Color=color2});Paint p = new Paint();p.AntiAlias = true;p.StrokeWidth = lineWidth;p.Color = new Color(0,0,0);p.SetStyle(Paint.Style.Stroke);canvas.DrawCircle(dirtyRect.Width() / 2, dirtyRect.Height() / 2,  circleR,p);////第一条曲线的路径Path path1 = new Path();path1.MoveTo(curve1StartPoint.X,curve1StartPoint.Y);PointF endp = new PointF(100, 114).MagnifyPoint(Scale);path1.CubicTo(cp1.X,cp1.Y, cp2.X,cp2.Y, endp.X,endp.Y);PointF endp2 = new PointF(140, 72).MagnifyPoint(Scale);path1.CubicTo(cp3.X,cp3.Y, cp4.X,cp4.Y, endp2.X,endp2.Y);path1.CubicTo(cp5.X,cp5.Y, cp6.X,cp6.Y, curve1EndPoint.X,curve1EndPoint.Y);path1.CubicTo(cp7.X,cp7.Y, cp8.X,cp8.Y, curve1StartPoint.X,curve1StartPoint.Y);p.Color = color1;p.SetStyle(Paint.Style.Fill);canvas.DrawPath(path1,p);//第二条曲线Path path2 = new Path();path2.MoveTo(curve2StartPoint.X,curve2StartPoint.Y);PointF rendp = new PointF(144, 154).MagnifyPoint(Scale);path2.CubicTo(rcp1.X,rcp1.Y, rcp2.X,rcp2.Y, rendp.X,rendp.Y);PointF rendp2 = new PointF(180, 110).MagnifyPoint(Scale);path2.CubicTo(rcp3.X,rcp3.Y, rcp4.X,rcp4.Y, rendp2.X,rendp2.Y);path2.CubicTo(rcp5.X,rcp5.Y, rcp6.X,rcp6.Y, curve2EndPoint.X,curve2EndPoint.Y);path2.CubicTo(rcp7.X,rcp7.Y, rcp8.X,rcp8.Y, curve2StartPoint.X,curve2StartPoint.Y);p.Color = color3;canvas.DrawPath(path2,p);//眼睛p.Color = new Color(0,0,0);PointF leftEyeCenterPoint = new PointF(119, 165).MagnifyPoint(Scale);PointF rightEyeCenterPoint = new PointF(147, 181).MagnifyPoint(Scale);float angle = 36;float eyeAngle = EyeRotateAngle;canvas.Translate(leftEyeCenterPoint.X, leftEyeCenterPoint.Y);//移动光标到指定位置canvas.Rotate(angle);float cornerWidth = eyeLineWidth * Scale;canvas.Rotate(eyeAngle);Path leftEyePath1 = new Path();leftEyePath1.AddRoundRect(new RectF(-cornerWidth, -cornerWidth, eyeLineWidth * Scale, eyeWidth * Scale), cornerWidth, cornerWidth,Path.Direction.Cw);p.Color = new Color(0,0,0);canvas.DrawPath(leftEyePath1,p);canvas.Rotate(-eyeAngle);canvas.Rotate(180- eyeAngle);Path leftEyePath2 = new Path();leftEyePath2.AddRoundRect(new RectF(-cornerWidth, -cornerWidth, eyeLineWidth * Scale, eyeWidth * Scale), cornerWidth, cornerWidth,Path.Direction.Cw);canvas.DrawPath(leftEyePath2,p);canvas.Rotate(eyeAngle - 180);canvas.Rotate(-angle);//转回去canvas.Translate(-leftEyeCenterPoint.X, -leftEyeCenterPoint.Y);canvas.Translate(rightEyeCenterPoint.X, rightEyeCenterPoint.Y);//移动光标到指定位置canvas.Rotate(angle);canvas.Rotate(eyeAngle + 180);Path rightEyePath1 = new Path();rightEyePath1.AddRoundRect(new RectF(-cornerWidth, -cornerWidth, eyeLineWidth * Scale,eyeWidth * Scale), cornerWidth, cornerWidth,Path.Direction.Cw);canvas.DrawPath(rightEyePath1,p);canvas.Rotate(-eyeAngle - 180);canvas.Rotate(-eyeAngle);Path rightEyePath2 = new Path();rightEyePath2.AddRoundRect(new RectF(-cornerWidth, -cornerWidth, eyeLineWidth * Scale, eyeWidth * Scale), cornerWidth, cornerWidth,Path.Direction.Cw);canvas.DrawPath(rightEyePath2,p);canvas.Rotate(eyeAngle);canvas.Rotate(-angle);//转回去canvas.Translate(-rightEyeCenterPoint.X, -rightEyeCenterPoint.Y);//嘴巴Path mousePaht = new Path();PointF mousePoint1 = new PointF(118, 134).MagnifyPoint(Scale);PointF mousePoint2 = new PointF(165, 165).MagnifyPoint(Scale);mousePaht.MoveTo(mousePoint1.X,mousePoint1.Y);mousePaht.CubicTo(MouthControlP1.X,MouthControlP1.Y, MouthControlP2.X,MouthControlP2.Y, mousePoint2.X,mousePoint2.Y);p.StrokeWidth = 5 * Scale;p.SetStyle(Paint.Style.Stroke);canvas.DrawPath(mousePaht,p);p.SetStyle(Paint.Style.Fill);canvas.DrawCircle(mousePoint1.X,mousePoint1.Y,2.5f*Scale,p);canvas.DrawCircle(mousePoint2.X, mousePoint2.Y, 2.5f * Scale, p);//手臂PointF leftArmP1 = new PointF(48, 106).MagnifyPoint(Scale);PointF leftArmP2 = new PointF(129, 95).MagnifyPoint(Scale);PointF rightArmP1 = new PointF(188, 189).MagnifyPoint(Scale);PointF rightArmP2 = new PointF(163, 115).MagnifyPoint(Scale);Path armPath = new Path();armPath.MoveTo(leftArmP1.X,leftArmP1.Y);armPath.CubicTo(LeftArmCP1.X,LeftArmCP1.Y, LeftArmCP2.X,LeftArmCP2.Y, leftArmP2.X,leftArmP2.Y);armPath.MoveTo(rightArmP1.X,rightArmP1.Y);armPath.CubicTo(RightArmCP1.X,RightArmCP1.Y, RightArmCP2.X,RightArmCP2.Y, rightArmP2.X,rightArmP2.Y);p.SetStyle(Paint.Style.Stroke);p.StrokeWidth = 8 * Scale;canvas.DrawPath(armPath,p);PointF leftHandP = leftArmP2;PointF rightHandP = rightArmP2;Path leftHandPath = new Path();RectF leftHandRect = new RectF(-4 * Scale, -4 * Scale, 8 * Scale, 28 * Scale);leftHandPath.AddRoundRect(leftHandRect, 5 * Scale, 5 * Scale,Path.Direction.Cw);float handAngle = HandRotateAngle;canvas.Translate(leftHandP.X, leftHandP.Y);//移动光标到指定位置canvas.Rotate(handAngle);p.SetStyle(Paint.Style.Fill);canvas.DrawRoundRect(leftHandRect, 8 * Scale, 8 * Scale, p);canvas.Rotate(-handAngle);//转回去canvas.Translate(-leftHandP.X, -leftHandP.Y);canvas.Translate(rightHandP.X, rightHandP.Y);//移动光标到指定位置canvas.Rotate(handAngle+180);canvas.DrawRoundRect(leftHandRect, 8 * Scale, 8 * Scale,p);canvas.Rotate(-handAngle-180);//转回去canvas.Translate(-rightHandP.X, -rightHandP.Y);if (showLighting){PointF lightningCenterP = new PointF((leftArmP2.X + rightArmP2.X) / 2.0f, (leftArmP2.Y + rightArmP2.Y) / 2.0f);Path lightningPath = new Path();lightningPath.MoveTo(lightningP1.X,lightningP1.Y);lightningPath.LineTo(lightningP2.X,lightningP2.Y);lightningPath.LineTo(lightningP3.X,lightningP3.Y);lightningPath.LineTo(lightningP4.X,lightningP4.Y);lightningPath.LineTo(lightningP5.X,lightningP5.Y);lightningPath.LineTo(lightningP6.X,lightningP6.Y);lightningPath.LineTo(lightningP1.X,lightningP1.Y);lightningPath.Close();canvas.Translate(lightningCenterP.X, lightningCenterP.Y);//移动光标到指定位置p.Color = new Color(255, 221,0);p.SetStyle(Paint.Style.Fill);canvas.Rotate(handAngle);canvas.DrawPath(lightningPath,p);canvas.Rotate(-handAngle);//转回去canvas.Translate(-lightningCenterP.X, -lightningCenterP.Y);}}}}


Android版本的完整DEMO可以从这里下载:

Android版本Demo


0 0
原创粉丝点击