最简单的转场动画就是在一个黑色的圆角矩形里面加载一个菊花轮,但如果项目要求高一些,就需要我们自己来实现一个自定义的转场动画了,不多说,先上效果图:
Mac上是通过一个NSTimer计时器然后不停地重绘来实现的,转场动画封装在一个NSView中,具体代码如下:
// 上海诸君信息科技有限公司版权所有
// 海学权
//
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实现的,具体代码如下:
svg网页版地球动画
SVG动画相关的知识可以从参考下面的网址:
svg动画相关
Windows版本(WPF)是通过Storyboard的动画来实现的,具体代码如下:
WPF版本的Demo可以从这里下载:
WPF版本转场动画
Android版本的转场动画和ios的原理相似,只不过是方法名称有些细微差别,具体代码如下:
// 上海诸君信息科技有限公司版权所有
// 海学权
//
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();
#endregion
this.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