必威WPF仿百度Echarts人口迁移图。WPF仿百度Echarts人口迁移图。

GitHub地址:https://github.com/ptddqr/wpf-echarts-map/tree/master

GitHub地址:https://github.com/ptddqr/wpf-echarts-map/tree/master

有关大名鼎鼎的百度Echarts我就无多说了
不了解之冤家一直扣官方的事例吧 http://echarts.baidu.com/examples.html

至于大名鼎鼎的百度Echarts我就算不多说了
不了解之冤家一直看官方的例子吧 http://echarts.baidu.com/examples.html

效果图:

效果图:

必威 1

必威 2

 

 

有关可行性:以前常听人说wpf动画开多矣会生卡,而我吗未尝写了含有大量动画的种,不明了实际怎样,这个地图显然都是卡通片,所以自己写了只测试动画性能的微程序,生成100只点及线跑动画,发现了无呀问题.

至于可行性:以前常放人说wpf动画开多了会客很卡,而己也不曾写了含有大量卡通的档次,不亮实际怎样,这个地图显然都是动画片,所以我勾勒了单测试动画性能的有些程序,生成100只点及线跑动画,发现完全没啊问题.

故而wpf做这东西自然是一心没有问题的.附上这个小程序
卡通性能测试 有趣味的情侣可开点动画
看看windows任务管理器里之cpu和内存的耗费情况

于是wpf做此东西一定是完全没有问题的.附上之小程序
卡通性能测试 有趣味的恋人可开点动画
看看windows任务管理器里之cpu和内存的淘情况

 

 

先期说生约的思绪吧:

预先说生约的笔触吧:

  1. 要是你没下手规划之援你做地图的讲话,基本得去网上搜矢量地图,转后换成path
  2. 找到省会城市的坐标,这就是是动轨迹的起点与极
  3. 依据起点终点生成运动轨迹的path和跑的触发,在接触及开路径动画,生成一个圆,中心放到到达城市之坐标处
  4. 初始化过程的卡通
  1. 苟你没抓规划之协助你做地图的语,基本得去网上搜矢量地图,转后换成path
  2. 找到省会城市之坐标,这就是是走轨迹的起点与极
  3. 依据起点终点生成运动轨迹的path和跑的触发,在接触达到召开路径动画,生成一个圆,中心放到到达市的坐标处
  4. 初始化过程的动画片

布局

头的首,我们得先考虑布局,为了防范一旦做成用户控件的话语,设置尺寸时地图走形.

  1. 极致外层肯定使用Viewbox,按比例缩放.需要专注的凡,Viewbox内部加大之控件是必产生实际的尺码的,它才能够展开缩放,当然不必然要使显式的去装中的Width和Height,只要中有实际意义上的尺寸就行.
  2. Viewbox内先放开一个Grid,分成两排Width全部装成auto,这样能够根据其中控件的莫过于尺寸来支配列宽.
  3. 0列放一个StackPanel.这个是左手当菜单用之RadioButton的器皿,每个RadioButton都来切实的肥瘦,所以0列就起了实际的增幅
  4. 1排列又推广一个Grid,这个Grid一定要安装HorizontalAlignment=”Left”
    VerticalAlignment=”Top”,就是依左上角布局,这样他里头的控件便会受它们撑起来,也尽管发出了实际的尺寸,这样Viewbox才会缩放
  5. 管地图的path全部放权这个Grid里,path的Stretch必须是None,这样path就会见将此Grid给撑起来,在斯Grid里面所有path的底又放开一个Grid,用来举行变通的卡通用底图纸的容器,他的坐标是跟父级Grid的坐标重合的

布局

初期的前期,我们得预考虑布局,为了防一旦做成用户控件的语,设置尺寸时地图走形.

  1. 最为外层肯定使因此Viewbox,按百分比缩放.需要小心的是,Viewbox内部加大之控件是要来切实的尺寸的,它才会展开缩放,当然不肯定要要显式的错过装中的Width和Height,只要其中有实际意义上的尺码就行.
  2. Viewbox内先放一个Grid,分成两排列Width全部装置成auto,这样会因其中控件的实际上尺寸来决定列宽.
  3. 0列放一个StackPanel.这个是左边当菜单用的RadioButton的容器,每个RadioButton都来实际的宽窄,所以0列就起了具体的宽
  4. 1排列又推广一个Grid,这个Grid一定要安装HorizontalAlignment=”Left”
    VerticalAlignment=”Top”,就是借助左上角布局,这样他里面的控件便会见为它们撑起来,也就产生了具体的尺码,这样Viewbox才会缩放
  5. 管地图的path全部置这个Grid里,path的Stretch必须是None,这样path就会将这个Grid给撑起来,在这Grid里面所有path的底还推广一个Grid,用来开变通的卡通片用之图纸的容器,他的坐标是跟父级Grid的坐标重合的

地图

有关寻找地图,不好找,我无什么好之心得.反正目的就是是找一个富含省会标记的地形图矢量图,只要是矢量图,我们不怕当来道将他变成为Xmal.

自家是当百度文库里找到一个ppt版的矢量地图,0生充斥券
矢量地图素材 下充斥下来后因故ppt打开,要为此微软的,别的可能保留不了来文件,右键地图=>另存为=>选.emf格式,然后据此Microsoft
Expression Design打开,然后右键=>导出

必威 3

如此就得了咱们若之path,然后找到每个省会所对应的path,取他们之Canvas.Left+Width/2
Canvas.Top+Height/2 就是对准诺坐标点的(x,y).(我算的远非这样精细,就是大概加了下.这个工作绝干燥,这不是重点.)

先期吐槽下自家查找的之地图,北京和天津凡是连在一起的,廊坊也没有不见了,3个都市全合成了一个path.所以建议大家温馨再错过探寻找

在意wpf的坐标都是为左上角开始之(0,0)
向右加x值 向下加y值 后面我们转变的图样定位时犹设 x值-自身Width/2
y值-自身Height/2 这样才会于图形的为主对需要固定的坐标点

发出了地图和坐标,我们就算可以举行下的做事了

地图

至于寻找地图,不好找,我无呀好之心得.反正目的就是是寻觅一个暗含省会标记的地图矢量图,只要是矢量图,我们就是该有点子把他换成Xmal.

自是在百度文库里找到一个ppt版的矢量地图,0下充斥券
矢量地图素材 下充斥下来后因故ppt打开,要因此微软的,别的可能保留不了来自文件,右键地图=>另存为=>选.emf格式,然后用Microsoft
Expression Design打开,然后右键=>导出

必威 4

这样就是获了咱设的path,然后找到每个省会所对应之path,取他们之Canvas.Left+Width/2
Canvas.Top+Height/2 就是针对性诺坐标点的(x,y).(我算的尚未这样精致,就是约加了下.这个工作太枯燥,这不是重点.)

预先吐槽下自家找的斯地图,北京以及天津大凡连在一起的,廊坊也流失不见了,3个都市遍合成了一个path.所以建议大家好又失探寻找

专注wpf的坐标都是坐左上角开始之(0,0)
向右加x值 向下加y值 后面我们转移的图纸定位时还要 x值-自身Width/2
y值-自身Height/2 这样才会于图形的主干对需要固定的坐标点

来了地图跟坐标,我们就算得举行下的干活了

变化动画所欲之奔走的点,运动轨迹的path,表示到市之周

转动画所急需之奔跑的点,运动轨迹的path,表示到市之环

跑步的接触

奔走的接触,我之所以了一个Grid里面学了一个path和一个Ellipse.

椭圆举行阴影,颜色和轨道一样,加一个透明掩码OpacityMask,里面凡是一个放射型的渐变画刷RadialGradientBrush.原点GradientOrigin(0.8,0.5) offset0高居设置也不透明,offset1处不透明度设置也2/16.

水滴型的path我不怕就此blend里之钢笔随意画了一个,得到了其的Data. Fill给一个线型渐变画刷,StartPoint(0,0),EndPoint(1,0),offset0给一个半透明底轨迹色,offset1让个未透明的纯白.

以此Grid的IsHitTestVisible可以装成false,不插手中测试,这样鼠标在轨道及时,点通过时,不会见阻塞轨迹ToolTip的显示.

代表码控,想协调写path的话,思路好参照我之别一样首博客
WPF绘制简单常用之Path

奔走的点

小跑的触发,我用了一个Grid里面学了一个path和一个Ellipse.

椭圆举行阴影,颜色与轨道一样,加一个晶莹剔透掩码OpacityMask,里面凡是一个放射型的渐变画刷RadialGradientBrush.原点GradientOrigin(0.8,0.5) offset0远在设置为未透明,offset1高居不透明度设置也2/16.

水滴型的path我就算用blend里的钢笔随意画了一个,得到了其的Data. Fill给一个线型渐变画刷,StartPoint(0,0),EndPoint(1,0),offset0给一个半晶莹剔透底轨迹色,offset1受个未透明的纯白.

斯Grid的IsHitTestVisible可以装成false,不插手中测试,这样鼠标在轨道及不时,点通过时,不见面阻塞轨迹ToolTip的显示.

代码控,想协调写path的话,思路好参照我之其余一样篇博客
WPF绘制简单常用之Path

城市之无微不至

他即便是只圆圈,没什么好说的,注意一下基本的定位就是行了 Ellipse
颜色和轨迹一样 ToolTip写上你想展示的物

都市的统筹兼顾

外即使是独周,没什么好说的,注意一下中坚的一定就是执行了 Ellipse
颜色和轨道一样 ToolTip写及你想展示的东西

移步轨迹

自于是的凡弧线ArcSegment
两只市的触及确定了,那么得经过简单独点之x,y,根据勾股定理计算出线段落的长度.给一个接触,连接这半独都之触发,可以构成一个三角,两独都整合的线对面的雅角可以装成一个角度参数,

斯线条固定,对竞赛的角度固定,那么他所对应的外接圆之半圆形就是一定的.我们可依据正弦定理a/sinA=2r请求来他搭圆的半径.虽可画出这个弧线来了.然后好被这个path的ToolTip附上鼠标移上失去想展示的文字.改下ToolTip的样式就尽了

运动轨迹

本人为此的凡弧线ArcSegment
两单城市之接触规定了,那么可透过个别单点之x,y,根据勾股定理计算出线截的长度.给一个碰,连接这片个城市的接触,可以做一个三角,两单城市做的线对面的雅角可以设置成一个角度参数,

此线条固定,对竞赛的角度固定,那么他所对应之外接圆的拱形就是永恒的.我们得以根据正弦定理a/sinA=2r告来他过渡圆的半径.即使足以画出这个弧线来了.然后方可于这path的ToolTip附上鼠标移上失去思展示的文字.改下ToolTip的体就行了

动画

动画

点沿着轨迹跑的卡通片

当下片动画,我便隐瞒了,参考周银辉的博客 http://www.cnblogs.com/zhouyinhui/archive/2007/07/31/837893.html

 

点沿着轨迹跑的卡通片

即有些卡通,我虽隐瞒了,参考周银辉的博客 http://www.cnblogs.com/zhouyinhui/archive/2007/07/31/837893.html

 

城市的圆满之卡通片

给Ellipse的晶莹掩码OpacityMask加一个放射型的渐变画刷RadialGradientBrush,加三单节点,offset0,offset1且是匪透明底,在他们中加一个毕透明底节点,然后动画控制offset值由0到1要是因为1到0,效果不同.

都市之统筹兼顾的卡通片

让Ellipse的透明掩码OpacityMask加一个放射型的渐变画刷RadialGradientBrush,加三单节点,offset0,offset1且是勿透明底,在他们中加一个完全透明底节点,然后动画控制offset值由0到1要么出于1到0,效果不同.

初始化过程的卡通

即时有些卡通其实就是计量时间,在适用的年月开始当的动画.

运动轨迹的表现:就是为移动轨迹path的晶莹掩码给一个线型渐变画刷,根据往左,右,上,下活动,设置好StartPoint和EndPoint,然后简单单节点一个晶莹剔透,一个无透明,同时从0向1举行动画,需要留意的凡如果一前一后运动,一定要是透明底异常节点在前边走,

再不会油然而生非常奇怪的表现,把此动画的工夫设置成跑的触及的一半之时间.这样轨迹比点跑的不久,不至于点走过去了,路径还从未见到那么

至于市的周,这有些加的较多,首先可以据此一个DoubleAnimation来控制Ellipse的透明度,开始日是轨道呈现的日子,也尽管是沾的时光/2,这样恰好好轨迹呈现到圆时,圆开始显现,动画时间吗安成轨迹呈现时间,这样刚好点走及全面的下,圆就全见完.

下一场加一个ColorAnimation,来控制到透明掩码里放射画刷的老二个节点,也就算是控制点,让他改成透明,用时0就可以,这样就算足以延续到的放射型动画了.开始日便是触发走到完善的时间.

接通下去就是片RadioButton,ToolTip,Path的体制问题了.这有豪门看心情,做个祥和喜欢的样式就足以了.

 

2016-08-01更新:

以称注册动画改呢对象注册动画

必威 5必威 6

  1         private void AddPointToStoryboard(Grid runPoint, Ellipse toEll, Storyboard sb, Path particlePath, double l, ProvincialCapital from, MapToItem toItem)
  2         {
  3             double pointTime = l / m_Speed;//点运动所需的时间
  4             double particleTime = pointTime / 2;//轨迹呈现所需时间(跑的比点快两倍)
  5             ////生成为控件注册名称的guid
  6             //string name = Guid.NewGuid().ToString().Replace("-", "");
  7 
  8             #region 运动的点
  9             TransformGroup tfg = new TransformGroup();
 10             MatrixTransform mtf = new MatrixTransform();
 11             tfg.Children.Add(mtf);
 12             TranslateTransform ttf = new TranslateTransform(-runPoint.Width / 2, -runPoint.Height / 2);//纠正最上角沿path运动到中心沿path运动
 13             tfg.Children.Add(ttf);
 14             runPoint.RenderTransform = tfg;
 15             //this.RegisterName("m" + name, mtf);
 16 
 17             MatrixAnimationUsingPath maup = new MatrixAnimationUsingPath();
 18             maup.PathGeometry = particlePath.Data.GetFlattenedPathGeometry();
 19             maup.Duration = new Duration(TimeSpan.FromSeconds(pointTime));
 20             maup.RepeatBehavior = RepeatBehavior.Forever;
 21             maup.AutoReverse = false;
 22             maup.IsOffsetCumulative = false;
 23             maup.DoesRotateWithTangent = true;
 24             //Storyboard.SetTargetName(maup, "m" + name);
 25             //Storyboard.SetTargetProperty(maup, new PropertyPath(MatrixTransform.MatrixProperty));
 26             Storyboard.SetTarget(maup, runPoint);
 27             Storyboard.SetTargetProperty(maup, new PropertyPath("(Grid.RenderTransform).Children[0].(MatrixTransform.Matrix)"));
 28             sb.Children.Add(maup);
 29             #endregion
 30 
 31             #region 达到城市的圆
 32             //this.RegisterName("ell" + name, toEll);
 33             //轨迹到达圆时 圆呈现
 34             DoubleAnimation ellda = new DoubleAnimation();
 35             ellda.From = 0.2;//此处值设置0-1会有不同的呈现效果
 36             ellda.To = 1;
 37             ellda.Duration = new Duration(TimeSpan.FromSeconds(particleTime));
 38             ellda.BeginTime = TimeSpan.FromSeconds(particleTime);//推迟动画开始时间 等轨迹连接到圆时 开始播放圆的呈现动画
 39             ellda.FillBehavior = FillBehavior.HoldEnd;
 40             //Storyboard.SetTargetName(ellda, "ell" + name);
 41             //Storyboard.SetTargetProperty(ellda, new PropertyPath(Ellipse.OpacityProperty));
 42             Storyboard.SetTarget(ellda, toEll);
 43             Storyboard.SetTargetProperty(ellda, new PropertyPath(Ellipse.OpacityProperty));
 44             sb.Children.Add(ellda);
 45             //圆呈放射状
 46             RadialGradientBrush rgBrush = new RadialGradientBrush();
 47             GradientStop gStop0 = new GradientStop(Color.FromArgb(255, 0, 0, 0), 0);
 48             //此为控制点 color的a值设为0 off值走0-1 透明部分向外放射 初始设为255是为了初始化效果 开始不呈放射状 等跑动的点运动到城市的圆后 color的a值才设为0开始呈现放射动画
 49             GradientStop gStopT = new GradientStop(Color.FromArgb(255, 0, 0, 0), 0);
 50             GradientStop gStop1 = new GradientStop(Color.FromArgb(255, 0, 0, 0), 1);
 51             rgBrush.GradientStops.Add(gStop0);
 52             rgBrush.GradientStops.Add(gStopT);
 53             rgBrush.GradientStops.Add(gStop1);
 54             toEll.OpacityMask = rgBrush;
 55             //this.RegisterName("e" + name, gStopT);
 56             //跑动的点达到城市的圆时 控制点由不透明变为透明 color的a值设为0 动画时间为0
 57             ColorAnimation ca = new ColorAnimation();
 58             ca.To = Color.FromArgb(0, 0, 0, 0);
 59             ca.Duration = new Duration(TimeSpan.FromSeconds(0));
 60             ca.BeginTime = TimeSpan.FromSeconds(pointTime);
 61             ca.FillBehavior = FillBehavior.HoldEnd;
 62             //Storyboard.SetTargetName(ca, "e" + name);
 63             //Storyboard.SetTargetProperty(ca, new PropertyPath(GradientStop.ColorProperty));
 64             Storyboard.SetTarget(ca, toEll);
 65             Storyboard.SetTargetProperty(ca, new PropertyPath("(Ellipse.OpacityMask).(GradientBrush.GradientStops)[1].(GradientStop.Color)"));
 66             sb.Children.Add(ca);
 67             //点达到城市的圆时 呈现放射状动画 控制点的off值走0-1 透明部分向外放射
 68             DoubleAnimation eda = new DoubleAnimation();
 69             eda.To = 1;
 70             eda.Duration = new Duration(TimeSpan.FromSeconds(2));
 71             eda.RepeatBehavior = RepeatBehavior.Forever;
 72             eda.BeginTime = TimeSpan.FromSeconds(particleTime);
 73             //Storyboard.SetTargetName(eda, "e" + name);
 74             //Storyboard.SetTargetProperty(eda, new PropertyPath(GradientStop.OffsetProperty));
 75             Storyboard.SetTarget(eda, toEll);
 76             Storyboard.SetTargetProperty(eda, new PropertyPath("(Ellipse.OpacityMask).(GradientBrush.GradientStops)[1].(GradientStop.Offset)"));
 77             sb.Children.Add(eda);
 78             #endregion
 79 
 80             #region 运动轨迹
 81             //找到渐变的起点和终点
 82             Point startPoint = GetProvincialCapitalPoint(from);
 83             Point endPoint = GetProvincialCapitalPoint(toItem.To);
 84             Point start = new Point(0, 0);
 85             Point end = new Point(1, 1);
 86             if (startPoint.X > endPoint.X)
 87             {
 88                 start.X = 1;
 89                 end.X = 0;
 90             }
 91             if (startPoint.Y > endPoint.Y)
 92             {
 93                 start.Y = 1;
 94                 end.Y = 0;
 95             }
 96             LinearGradientBrush lgBrush = new LinearGradientBrush();
 97             lgBrush.StartPoint = start;
 98             lgBrush.EndPoint = end;
 99             GradientStop lgStop0 = new GradientStop(Color.FromArgb(255, 0, 0, 0), 0);
100             GradientStop lgStop1 = new GradientStop(Color.FromArgb(0, 0, 0, 0), 0);
101             lgBrush.GradientStops.Add(lgStop0);
102             lgBrush.GradientStops.Add(lgStop1);
103             particlePath.OpacityMask = lgBrush;
104             //this.RegisterName("p0" + name, lgStop0);
105             //this.RegisterName("p1" + name, lgStop1);
106             //运动轨迹呈现
107             DoubleAnimation pda0 = new DoubleAnimation();
108             pda0.To = 1;
109             pda0.Duration = new Duration(TimeSpan.FromSeconds(particleTime));
110             pda0.FillBehavior = FillBehavior.HoldEnd;
111             //Storyboard.SetTargetName(pda0, "p0" + name);
112             //Storyboard.SetTargetProperty(pda0, new PropertyPath(GradientStop.OffsetProperty));
113             Storyboard.SetTarget(pda0, particlePath);
114             Storyboard.SetTargetProperty(pda0, new PropertyPath("(Path.OpacityMask).(GradientBrush.GradientStops)[0].(GradientStop.Offset)"));
115             sb.Children.Add(pda0);
116             DoubleAnimation pda1 = new DoubleAnimation();
117             //pda1.From = 0.5; //此处解开注释 值设为0-1 会有不同的轨迹呈现效果
118             pda1.To = 1;
119             pda1.Duration = new Duration(TimeSpan.FromSeconds(particleTime));
120             pda1.FillBehavior = FillBehavior.HoldEnd;
121             //Storyboard.SetTargetName(pda1, "p1" + name);
122             //Storyboard.SetTargetProperty(pda1, new PropertyPath(GradientStop.OffsetProperty));
123             Storyboard.SetTarget(pda1, particlePath);
124             Storyboard.SetTargetProperty(pda1, new PropertyPath("(Path.OpacityMask).(GradientBrush.GradientStops)[1].(GradientStop.Offset)"));
125             sb.Children.Add(pda1);
126             #endregion
127         }

View Code

2016-12-19更新:

发布到GitHub,地址:https://github.com/ptddqr/wpf-echarts-map/tree/master

 

源码下载:仿百度Echarts人口迁移图.zip

初始化过程的卡通片

立即有些动画其实就是测算时,在适合的日开始当的动画.

移步轨迹的表现:就是叫移动轨迹path的晶莹掩码给一个线型渐变画刷,根据往左,右,上,下活动,设置好StartPoint和EndPoint,然后简单只节点一个透明,一个未透明,同时从0向1召开动画,需要小心的是若一前一后运动,一定要透明的挺节点在前方走,

不然会现出很怪异的作为,把此动画的年华设置成跑的点的一半之时间.这样轨迹比点跑的尽早,不至于点走过去了,路径还没见到那么

至于城市之宏观,这片加的较多,首先得用一个DoubleAnimation来控制Ellipse的透明度,开始时是轨道呈现的日子,也即是触发之时光/2,这样刚好轨迹呈现到圆时,圆开始呈现,动画时间为安成轨迹呈现时间,这样刚好点运动及健全之当儿,圆就全呈现完.

接下来加一个ColorAnimation,来支配到透明掩码里放射画刷的老二个节点,也不怕是控制点,让他改成透明,用时0就足以,这样即便得延续到之放射型动画了.开始时间就是接触运动及全面的时间.

连接下便是片RadioButton,ToolTip,Path的体问题了.这部分豪门看心情,做个祥和爱的样式就得了.

 

2016-08-01更新:

将称注册动画改吗对象注册动画

必威 7必威 8

  1         private void AddPointToStoryboard(Grid runPoint, Ellipse toEll, Storyboard sb, Path particlePath, double l, ProvincialCapital from, MapToItem toItem)
  2         {
  3             double pointTime = l / m_Speed;//点运动所需的时间
  4             double particleTime = pointTime / 2;//轨迹呈现所需时间(跑的比点快两倍)
  5             ////生成为控件注册名称的guid
  6             //string name = Guid.NewGuid().ToString().Replace("-", "");
  7 
  8             #region 运动的点
  9             TransformGroup tfg = new TransformGroup();
 10             MatrixTransform mtf = new MatrixTransform();
 11             tfg.Children.Add(mtf);
 12             TranslateTransform ttf = new TranslateTransform(-runPoint.Width / 2, -runPoint.Height / 2);//纠正最上角沿path运动到中心沿path运动
 13             tfg.Children.Add(ttf);
 14             runPoint.RenderTransform = tfg;
 15             //this.RegisterName("m" + name, mtf);
 16 
 17             MatrixAnimationUsingPath maup = new MatrixAnimationUsingPath();
 18             maup.PathGeometry = particlePath.Data.GetFlattenedPathGeometry();
 19             maup.Duration = new Duration(TimeSpan.FromSeconds(pointTime));
 20             maup.RepeatBehavior = RepeatBehavior.Forever;
 21             maup.AutoReverse = false;
 22             maup.IsOffsetCumulative = false;
 23             maup.DoesRotateWithTangent = true;
 24             //Storyboard.SetTargetName(maup, "m" + name);
 25             //Storyboard.SetTargetProperty(maup, new PropertyPath(MatrixTransform.MatrixProperty));
 26             Storyboard.SetTarget(maup, runPoint);
 27             Storyboard.SetTargetProperty(maup, new PropertyPath("(Grid.RenderTransform).Children[0].(MatrixTransform.Matrix)"));
 28             sb.Children.Add(maup);
 29             #endregion
 30 
 31             #region 达到城市的圆
 32             //this.RegisterName("ell" + name, toEll);
 33             //轨迹到达圆时 圆呈现
 34             DoubleAnimation ellda = new DoubleAnimation();
 35             ellda.From = 0.2;//此处值设置0-1会有不同的呈现效果
 36             ellda.To = 1;
 37             ellda.Duration = new Duration(TimeSpan.FromSeconds(particleTime));
 38             ellda.BeginTime = TimeSpan.FromSeconds(particleTime);//推迟动画开始时间 等轨迹连接到圆时 开始播放圆的呈现动画
 39             ellda.FillBehavior = FillBehavior.HoldEnd;
 40             //Storyboard.SetTargetName(ellda, "ell" + name);
 41             //Storyboard.SetTargetProperty(ellda, new PropertyPath(Ellipse.OpacityProperty));
 42             Storyboard.SetTarget(ellda, toEll);
 43             Storyboard.SetTargetProperty(ellda, new PropertyPath(Ellipse.OpacityProperty));
 44             sb.Children.Add(ellda);
 45             //圆呈放射状
 46             RadialGradientBrush rgBrush = new RadialGradientBrush();
 47             GradientStop gStop0 = new GradientStop(Color.FromArgb(255, 0, 0, 0), 0);
 48             //此为控制点 color的a值设为0 off值走0-1 透明部分向外放射 初始设为255是为了初始化效果 开始不呈放射状 等跑动的点运动到城市的圆后 color的a值才设为0开始呈现放射动画
 49             GradientStop gStopT = new GradientStop(Color.FromArgb(255, 0, 0, 0), 0);
 50             GradientStop gStop1 = new GradientStop(Color.FromArgb(255, 0, 0, 0), 1);
 51             rgBrush.GradientStops.Add(gStop0);
 52             rgBrush.GradientStops.Add(gStopT);
 53             rgBrush.GradientStops.Add(gStop1);
 54             toEll.OpacityMask = rgBrush;
 55             //this.RegisterName("e" + name, gStopT);
 56             //跑动的点达到城市的圆时 控制点由不透明变为透明 color的a值设为0 动画时间为0
 57             ColorAnimation ca = new ColorAnimation();
 58             ca.To = Color.FromArgb(0, 0, 0, 0);
 59             ca.Duration = new Duration(TimeSpan.FromSeconds(0));
 60             ca.BeginTime = TimeSpan.FromSeconds(pointTime);
 61             ca.FillBehavior = FillBehavior.HoldEnd;
 62             //Storyboard.SetTargetName(ca, "e" + name);
 63             //Storyboard.SetTargetProperty(ca, new PropertyPath(GradientStop.ColorProperty));
 64             Storyboard.SetTarget(ca, toEll);
 65             Storyboard.SetTargetProperty(ca, new PropertyPath("(Ellipse.OpacityMask).(GradientBrush.GradientStops)[1].(GradientStop.Color)"));
 66             sb.Children.Add(ca);
 67             //点达到城市的圆时 呈现放射状动画 控制点的off值走0-1 透明部分向外放射
 68             DoubleAnimation eda = new DoubleAnimation();
 69             eda.To = 1;
 70             eda.Duration = new Duration(TimeSpan.FromSeconds(2));
 71             eda.RepeatBehavior = RepeatBehavior.Forever;
 72             eda.BeginTime = TimeSpan.FromSeconds(particleTime);
 73             //Storyboard.SetTargetName(eda, "e" + name);
 74             //Storyboard.SetTargetProperty(eda, new PropertyPath(GradientStop.OffsetProperty));
 75             Storyboard.SetTarget(eda, toEll);
 76             Storyboard.SetTargetProperty(eda, new PropertyPath("(Ellipse.OpacityMask).(GradientBrush.GradientStops)[1].(GradientStop.Offset)"));
 77             sb.Children.Add(eda);
 78             #endregion
 79 
 80             #region 运动轨迹
 81             //找到渐变的起点和终点
 82             Point startPoint = GetProvincialCapitalPoint(from);
 83             Point endPoint = GetProvincialCapitalPoint(toItem.To);
 84             Point start = new Point(0, 0);
 85             Point end = new Point(1, 1);
 86             if (startPoint.X > endPoint.X)
 87             {
 88                 start.X = 1;
 89                 end.X = 0;
 90             }
 91             if (startPoint.Y > endPoint.Y)
 92             {
 93                 start.Y = 1;
 94                 end.Y = 0;
 95             }
 96             LinearGradientBrush lgBrush = new LinearGradientBrush();
 97             lgBrush.StartPoint = start;
 98             lgBrush.EndPoint = end;
 99             GradientStop lgStop0 = new GradientStop(Color.FromArgb(255, 0, 0, 0), 0);
100             GradientStop lgStop1 = new GradientStop(Color.FromArgb(0, 0, 0, 0), 0);
101             lgBrush.GradientStops.Add(lgStop0);
102             lgBrush.GradientStops.Add(lgStop1);
103             particlePath.OpacityMask = lgBrush;
104             //this.RegisterName("p0" + name, lgStop0);
105             //this.RegisterName("p1" + name, lgStop1);
106             //运动轨迹呈现
107             DoubleAnimation pda0 = new DoubleAnimation();
108             pda0.To = 1;
109             pda0.Duration = new Duration(TimeSpan.FromSeconds(particleTime));
110             pda0.FillBehavior = FillBehavior.HoldEnd;
111             //Storyboard.SetTargetName(pda0, "p0" + name);
112             //Storyboard.SetTargetProperty(pda0, new PropertyPath(GradientStop.OffsetProperty));
113             Storyboard.SetTarget(pda0, particlePath);
114             Storyboard.SetTargetProperty(pda0, new PropertyPath("(Path.OpacityMask).(GradientBrush.GradientStops)[0].(GradientStop.Offset)"));
115             sb.Children.Add(pda0);
116             DoubleAnimation pda1 = new DoubleAnimation();
117             //pda1.From = 0.5; //此处解开注释 值设为0-1 会有不同的轨迹呈现效果
118             pda1.To = 1;
119             pda1.Duration = new Duration(TimeSpan.FromSeconds(particleTime));
120             pda1.FillBehavior = FillBehavior.HoldEnd;
121             //Storyboard.SetTargetName(pda1, "p1" + name);
122             //Storyboard.SetTargetProperty(pda1, new PropertyPath(GradientStop.OffsetProperty));
123             Storyboard.SetTarget(pda1, particlePath);
124             Storyboard.SetTargetProperty(pda1, new PropertyPath("(Path.OpacityMask).(GradientBrush.GradientStops)[1].(GradientStop.Offset)"));
125             sb.Children.Add(pda1);
126             #endregion
127         }

View Code

2016-12-19更新:

发布到GitHub,地址:https://github.com/ptddqr/wpf-echarts-map/tree/master

 

源码下载:仿百度Echarts人口迁移图.zip

Leave a Comment.