您的位置:首页 > 其它

通通玩blend美工(8)——动态绘制路径动画,画出个萌妹子~

2012-10-19 15:40 288 查看
  2年前我在玩Flex的时候就一直有一个疑问,就是如何来实现一个蚊香慢慢烧完的Loading动画呢?  

  刚经历了某甲方高强度一个月的洗礼后,这几天刚好闲下来,这个问题又浮现在我脑海里。于是经过几番思索纠结后,我发现了一个更好玩的效果,如下:

  

画线方法

/// <summary>
/// 开始绘制一条路径
/// </summary>
/// <param name="path">路径样本</param>
private void PathPlay(Path path)
{
Path ph = new Path();//当前绘制的路径
drawPathList.Add(ph);
ph.Stroke = new SolidColorBrush(Colors.Black);
drawGrid.Children.Add(ph);//添加进画布

PathGeometry thisPG = new PathGeometry();//动画路径的数据
ph.Data = thisPG;
StringToPathGeometryConverter _s = new StringToPathGeometryConverter();
PG = _s.Convert(path.Data.ToString());//读取样本路径,分解段
PF = new PathFigure();//创建集合
endPoint = PF.StartPoint = PG.Figures[0].StartPoint;//设置起始点,一开始的终结点为起始点
thisPG.Figures.Add(PF);
Play();//开始绘制分段的路径

}

/// <summary>
/// 绘制路径的一段
/// </summary>
private void Play()
{
try
{
if (pathNum >= list.Count)//画完所有的路径
{
FillColor();//开始填充颜色
Group.Visibility = Visibility.Visible;
return;
}
else if (num >= PG.Figures[0].Segments.Count)//画完一条线
{
if (pathNum < list.Count)
{
num = 0;
PathPlay(list[pathNum++] as Path);//播放完毕就播放下一条线
return;
}
}
PathSegment item = PG.Figures[0].Segments[num++];//读取下一个点
if (item.ToString().Contains("Line"))//如果这个点是直线
{
LineSegment _ls = new LineSegment();
_ls.Point = endPoint;
PathSegment PS = _ls;//创建一条直线的初始状态点

PointAnimation PA = new PointAnimation();//动画到读取的点的位置
PA.To=(item as LineSegment).Point;
PA.Duration = new Duration(TimeSpan.FromMilliseconds(50));
PA.Completed += new EventHandler((sender1, e1) =>//播放完毕后进行递归,绘制下一条线
{
Play();
});
PF.Segments.Add(PS);//添加点
//PS.BeginAnimation(LineSegment.PointProperty, PA);
Storyboard sb = new Storyboard();
sb.Children.Add(PA);
Storyboard.SetTarget(PA, PS);
Storyboard.SetTargetProperty(PA, new PropertyPath("Point"));
sb.Begin();//开始动画
endPoint = (item as LineSegment).Point;//记录终结点

}
else if (item.ToString().Contains("Bezier"))//如果这个点是贝尔曲线
{
BezierSegment _bs = new BezierSegment();
_bs.Point1 = _bs.Point2 = _bs.Point3 = endPoint;
PathSegment PS = _bs;
PointAnimationUsingPath PA = new PointAnimationUsingPath();//创建终结点的路径动画,曲线要严格按照路径来运动
PA.Target = PS;
PA.TargetProperty = new PropertyPath("Point3");
PA.Duration = TimeSpan.FromMilliseconds(50);
//生成动画的路径形状
PathGeometry newPG = new PathGeometry();
PathFigure newPF = new PathFigure();//创建集合
newPF.StartPoint = endPoint;//s设置起始点和每次动画的种植点
newPG.Figures.Add(newPF);
BezierSegment _bs1 = new BezierSegment();
_bs1.Point1 = (item as BezierSegment).Point1;
_bs1.Point2 = (item as BezierSegment).Point2;
_bs1.Point3 = (item as BezierSegment).Point3;
newPF.Segments.Add(_bs1);

PA.PathGeometry = newPG;
PA.Completed += new EventHandler((sender1, e1) =>
{
Play();
});
PA.Begin();
//同样对控制点也要进行一般的动画
PointAnimation PA1 = new PointAnimation();
PA1.To=(item as BezierSegment).Point1;
PA1.Duration=new Duration(TimeSpan.FromMilliseconds(500));
PointAnimation PA2 = new PointAnimation();
PA2.To=(item as BezierSegment).Point2;
PA2.Duration=new Duration(TimeSpan.FromMilliseconds(500));
PF.Segments.Add(PS);
//PS.BeginAnimation(BezierSegment.Point3Property, PA);
//PS.BeginAnimation(BezierSegment.Point1Property, PA1);
//PS.BeginAnimation(BezierSegment.Point2Property, PA2);
Storyboard sb = new Storyboard();
//sb.Children.Add(PA);
//Storyboard.SetTarget(PA, PS);
//Storyboard.SetTargetProperty(PA, new PropertyPath("Point"));
//sb.Begin();//开始动画
endPoint = (item as BezierSegment).Point3;
}
}
catch
{

}
}


方法里用了各种递归是因为处理完一条Path的所有动画后执行下一条Path的动画,而每一条Path里的每一小段也得依次处理, 要让一序列的动画依次播放,得在动画播放完毕后再播放下一段动画,各位大虾有没有更好的方法来依次播放一序列动画呢??

后记

  原版是Wpf的,wpf自带了PointAnimationUsingPath动画,所以实现起来代码少得多了。接下来我打算优化后把它封成一个行为,方便以后使用。

  文中出现了这么多外国牛人的文章,当然了以小弟的强烈爱国情怀是无法完全理解,所以特别谢/article/4658551.html

觉得本文还可以的话要点击下面的推荐哦

喵~

  

  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: