原文:WPF Path实现虚线流动效果

最近闲来无事,每天上上网,看看博客生活也过得惬意,这下老总看不过去了,给我一个任务,叫我用WPF实现虚线流动效果,我想想,不就是虚线流动嘛,这简单于是就答应下来了,谁也没想到这简单的东西搞了3天没搞定,最后搞定了居然是那么的简单,自己是想得太复杂了,哎,脑子生锈了,废话不多说,进入这3天的无脑思考中。

  思路1:

  根据老总的说法,他只要我实现效果就行了,那好,我就偷一下懒,用Line实现,用一个Line数组,装入一定量的Line对象,使他们间隔相同的距离,开启多线程,使得每一个Line对象每秒向前移动 1/3,但是最后一个Line向前移动的时候,需要每次减掉 1/3的长度,直到长度为0,这样才让人有一种视觉错觉虚线在向某个方向流动,当最后一个Line长度为0的时候,把最后一个对象移动到数组的第一位,其他对象依次想后移,下面是代码:

  1. 1 Line[] line = new Line[11];
    2 double width;
    3 double height;
    4 int i = 0;
    5 public MainWindow()
    6 {
    7 InitializeComponent();
    8 }
    9 /// <summary>
    10 /// 线段向某方向移动
    11 /// </summary>
    12 private void LineMove()
    13 {
    14 double x1 = width / 20;
    15 double x2 = x1 / 3;
    16 for (int i = 10; i >=0; i--)
    17 {
    18 if (i == 10)
    19 {
    20 if (line[i].X1 >= line[i].X2)//如果最后一条长度为0的时候,就移动到第一位
    21 {
    22 LineArryMove();
    23 }
    24 line[i].X1 += x2;
    25 }
    26 else
    27 {
    28 line[i].X1 += x2;
    29 line[i].X2 += x2;
    30 }
    31
    32 }
    33 }
    34 /// <summary>
    35 /// 最后一个对象移到第一位
    36 /// </summary>
    37 private void LineArryMove()
    38 {
    39 double x1 = width / 20;
    40 double x2 = x1 / 3;
    41 Line temp = line[0];
    42 line[0] = line[10];
    43 for (int i = 0; i < 10; i++)
    44 {
    45 Line temp1 = line[i + 1];
    46 line[i + 1] = temp;
    47 temp = temp1;
    48 }
    49 for (int i = 1; i<11; i++)
    50 {
    51 line[i].X1 += x2;
    52 line[i].X2 += x2;
    53 }
    54 line[0].X1 = x2;
    55 line[0].X2 = x2 + x1;
    56 }
    57 /// <summary>
    58 /// 画出一条虚线
    59 /// </summary>
    60 private void LineDraw()
    61 {
    62 height=this.canvas.ActualHeight;
    63 width = this.canvas.ActualWidth;
    64 double x1 = width / 20;
    65 double x2 = x1 / 3;
    66 for (int i = 0; i < 11; i++)
    67 {
    68 line[i] = new Line();
    69 line[i].Stroke = Brushes.Red;
    70 line[i].StrokeThickness = 3;
    71 line[i].X1 = (i + 1) * x2 + i * x1;
    72 line[i].X2 = (i + 1) * x2 + (i+1)* x1;
    73 line[i].Y1 = height / 2;
    74 line[i].Y2 = height / 2;
    75 this.canvas.Children.Add(line[i]);
    76 }
    77 }
    78 /// <summary>
    79 /// 开启多线程
    80 /// </summary>
    81 private void ThreadStart()
    82 {
    83 Thread P_th = new Thread(//建立线程
    84
    85 () =>//使用lambda表达式
    86 {
    87
    88 while (true)//开始无限循环
    89 {
    90
    91 this.Dispatcher.BeginInvoke(//在窗体线程中执行相关代码
    92
    93 System.Windows.Threading.DispatcherPriority.Normal,//设置线程优先级
    94
    95 (ThreadStart)(() =>//使用lambda表达式
    96 {
    97
    98 LineMove();
    99
    100 }));
    101
    102 Thread.Sleep(1000);//线程挂起1秒钟
    103 i++;
    104
    105 }
    106
    107 });
    108
    109 P_th.IsBackground = true;//设置线程为后台线程
    110
    111 P_th.Start();//线程开始
    112 }
    113 private void button1_Click(object sender, RoutedEventArgs e)
    114 {
    115 LineDraw();
    116 }
    117
    118 private void button2_Click(object sender, RoutedEventArgs e)
    119 {
    120 ThreadStart();
    121 }

  好吧,这样效果是实现了,但也仅仅是测试一下效果,要是曲线,或者一些不规则的线段的话,肯定不能这样实现,又想了一下,WPF可以实现动画效果,那我们试试用动画实现看看,这就涉及到了路径动画的实现,路径动画,也就是某个对象沿着一条路径运动,这就有了下一个思路。

  思路2:

  还是用Line作为填充对象,每一个对象的的运动周期是一样的,但是动画开始的时间不一样,设置间隔递增的开始时间,这样开始动画的时候,每个Line都会依次出现,这样就就有了流动的效果,但是还有一个问题,就是它有一个填充时间,当第一个对象的一个周期后,这条虚线才被填充完毕,- -这和老总说的有出入,也不知道能不能通过,下面是主要代码:

  1. 1 /// <summary>
    2 ///
    3 /// </summary>
    4 /// <param name="btnPath"></param>
    5 /// <param name="xNum">第N个对象</param>
    6 /// <param name="sleepTime">间隔时间</param>
    7 /// <param name="pathLine">Path对象</param>
    8 /// <param name="DuTime">动画时间</param>
    9 private void AnimationStart(Line btnPath, int xNum, int sleepTime,Path pathLine,int DuTime)
    10 {
    11
    12 double realTime = ((double)sleepTime) / ((double)1000);
    13 string strTranslate = "translate"+xNum;
    14 string strRote = "rotate"+xNum;
    15
    16 //btnPath.Width = 20;
    17 //btnPath.Height = 5;
    18 btnPath.Stroke = Brushes.Red;
    19 btnPath.X1 = 0;
    20 btnPath.X2 = 20;
    21 btnPath.StrokeThickness = 5;
    22
    23 Canvas.SetTop(btnPath, -2.5);
    24 Canvas.SetLeft(btnPath, -10);//为了使对象与路径更加重合,可自己调节初始坐标
    25
    26 btnPath.RenderTransformOrigin = new Point(0.5, 0.5);
    27
    28 TranslateTransform translate = new TranslateTransform();
    29 RotateTransform rotate = new RotateTransform();
    30 TransformGroup group = new TransformGroup();
    31
    32 group.Children.Add(rotate);//先旋转
    33 group.Children.Add(translate);//再平移
    34
    35 NameScope.SetNameScope(this, new NameScope());
    36
    37 this.RegisterName(strTranslate, translate);
    38 this.RegisterName(strRote, rotate);
    39
    40 btnPath.RenderTransformOrigin = new Point(0.5, 0.5);
    41 this.canvas.Children.Add(btnPath);
    42
    43 btnPath.RenderTransform = group;
    44 //设置物体X轴的目标
    45 DoubleAnimationUsingPath animationX = new DoubleAnimationUsingPath();
    46 animationX.PathGeometry = pathLine.Data.GetFlattenedPathGeometry();
    47 animationX.Source = PathAnimationSource.X;
    48 animationX.Duration = new Duration(TimeSpan.FromSeconds(DuTime));
    49 animationX.BeginTime = TimeSpan.FromSeconds(xNum * realTime);
    50 animationX.RepeatBehavior = RepeatBehavior.Forever;
    51 //设置物体Y轴的目标
    52 DoubleAnimationUsingPath animationY = new DoubleAnimationUsingPath();
    53 animationY.PathGeometry = pathLine.Data.GetFlattenedPathGeometry();
    54 animationY.Source = PathAnimationSource.Y;
    55 animationY.Duration = animationX.Duration;
    56 animationY.BeginTime = TimeSpan.FromSeconds(xNum * realTime);
    57 animationY.RepeatBehavior = RepeatBehavior.Forever;
    58
    59 //设置物体的旋转角度
    60 DoubleAnimationUsingPath animationAngle = new DoubleAnimationUsingPath();
    61 animationAngle.PathGeometry = pathLine.Data.GetFlattenedPathGeometry();
    62 animationAngle.Source = PathAnimationSource.Angle;
    63 animationAngle.Duration = animationX.Duration;
    64 animationAngle.BeginTime = TimeSpan.FromSeconds(xNum * realTime);
    65 animationAngle.RepeatBehavior = RepeatBehavior.Forever;
    66
    67 translate.BeginAnimation(TranslateTransform.XProperty, animationX);
    68 translate.BeginAnimation(TranslateTransform.YProperty, animationY);
    69 rotate.BeginAnimation(RotateTransform.AngleProperty, animationAngle);
    70
    71 }

  现在最大的一个问题来了,都传说WPF的动画很耗资源,一看CPU,哇,I5的处理器都达到百分之15,这不是坑爹么,这怎么拿出去见人啊,又到了思考的时候,CPU该怎么降下来,试了很多种方法,都是差不多,动画对象一多,CPU就高,当思路进入死胡同的时候,想出来就不那么容易了 - -,就这样耗费了两天时间,突然灵机一闪,我去MSDN一个个的查看Path的方法和属性,这一看,好吧,我承认自己脑残了。。。。

  Path主要属性:

  StrokeThickness 线段的粗细

  Data 路径数据  如:Data=“Data="M25,522 C25,522 6.5,322.5 102.5,319.5 198.5,316.5 245.49957,361.5 369.4992,207.5 493.49883,53.5 468.49891,29.5 559.49864,59.5 650.49837,89.5 692.49827,292.49995 698.49825,304.49996 704.49823,316.49996 698.49823,484.49999 615.49848,501.5
532.49872,518.5 317.4995,543.5 251.49967,516.5 185.49983,489.49999 789.49832,175.49996 502.49904,127.49994"”;

  StrokeDashArray 虚线的设置 如:StrokeDashArray=“10,5”;意思就是把Path分成若干线段,每一段是10,间隔为5,。

  StrokeDashOffset 线段的偏移量!好吧,这就是我们所需要的最重要属性。减去或加上一个数,线段就会向某个方向移动一段距离,要想做成移动的虚线,只要循环设置StrokeDashOffset的值就可以了,代码:

  1. 1 private void ThreadStart()
    2 {
    3 Thread P_th = new Thread(//建立线程
    4
    5 () =>//使用lambda表达式
    6 {
    7
    8 while (flag)//开始无限循环
    9 {
    10
    11 this.Dispatcher.BeginInvoke(//在窗体线程中执行相关代码
    12
    13 System.Windows.Threading.DispatcherPriority.Normal,//设置线程优先级
    14
    15 (ThreadStart)(() =>//使用lambda表达式
    16 {
    17 this.path1.StrokeDashOffset -=10;
    18
    19 }));
    20
    21 Thread.Sleep(500);//线程挂起
    22 }
    23
    24 });
    25
    26 P_th.IsBackground = true;//设置线程为后台线程
    27
    28 P_th.Start();//线程开始
    29 }

  本文来自01_code的博客,原文地址:http://www.cnblogs.com/01codeworld/archive/2012/02/17/loce.html

WPF Path实现虚线流动效果的更多相关文章

  1. WPF 图片浏览 伪3D效果

    原文:WPF 图片浏览 伪3D效果 首先上效果图: 因项目要求,需要把图片以"好看"."炫"的效果展示出来,特地研究了一下WPF关于3D方面的制作,奈何最终成果 ...

  2. Shape流动效果

    <Window x:Class="MvvmLight1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/ ...

  3. WPF中画虚线

    原文:WPF中画虚线 在WPF中,画线的方法十分简单,只要声明一个Line然后添加到指定的位置就可以了,但Line并不仅仅只能画一条直线,还可以对直线进行修饰. 1.Line.StrokeDashAr ...

  4. 基于HTML5实现3D监控应用流动效果

    http://www.hightopo.com/guide/guide/core/lighting/examples/example_flowing.html 流动效果在3D领域有着广泛的应用场景,如 ...

  5. HT for Web中3D流动效果的实现与应用

    流动效果在3D领域有着广泛的应用场景,如上图中医学领域可通过3D的流动直观的观察人体血液的流动,燃气领域可用于监控管道内流动的液体或气体的流向.流速和温度等指标. 如今企业数据中心机房普遍面临着设备散 ...

  6. WPF Multi-Touch 开发:惯性效果(Inertia)

    原文 WPF Multi-Touch 开发:惯性效果(Inertia) 从上一篇实例可以发现在图片移动过程中如果将手指移开屏幕则图片会立刻停止,根据这种情况WPF 提供另外一种惯性效果(Inertia ...

  7. 【WPF】两则动画效果

    原文:[WPF]两则动画效果 引言 利用WPF的动画可以轻而易举的实现各种各样的特效,如擦除,滑动进入等,先看两个效果图 第一个效果 这个动画其实利用了OpacityMask和LinearGradie ...

  8. 用WPF轻松打造iTunes CoverFlow效果

    原文:用WPF轻松打造iTunes CoverFlow效果 用WPF轻松打造iTunes CoverFlow效果                                             ...

  9. WPF特效-实现3D足球效果

    原文:WPF特效-实现3D足球效果 WPF 实现 3D足球效果,效果图如下:  每个面加载不同贴图. <UserControl x:Class="MediaBalll.Model3Ds ...

随机推荐

  1. Android JAVA中的时间大小比较

    import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; imp ...

  2. 【t010】最近距离

    Time Limit: 1 second Memory Limit: 32 MB [问题描述] 聚类方法要求将空间中的点集,按照一点的方式进行归类,要求每一类中的点集相互之间的距离足够的"近 ...

  3. keepalived.conf 配置文件小结

    vrrp_script vs_mysql_82 {     script "/etc/keepalived/checkMySQL.py -h 192.168.11.82 -P 3306&qu ...

  4. Mac OSX 下配置 LNMP开发环境

    不久前负责了一个项目需要配置PHP7的开发环境,因为之前所有的项目用的是PHP5的,所以研究了这些东西,但是很遗憾,电脑出了问题,不得已重装了系统,然后你懂得...什么都没有了,要重新来过.. 虽然本 ...

  5. 【BZOJ1426】收集邮票 概率DP 论文题 推公式题

    链接: #include <stdio.h> int main() { puts("转载请注明出处[辗转山河弋流歌 by 空灰冰魂]谢谢"); puts("网 ...

  6. ECharts.js 超简单入门(本质canvas)

    ECharts.js 超简单入门(本质canvas) 一.总结 一句话总结:echarts这些图标的本质都是canvas. 二.ECharts.js学习(一) 简单入门 EChart.js 简单入门 ...

  7. [NativeScript] Create new application and run emulator

    Install: npm i -g nativescript Create: tns create <app_name> --ng Run: tns emulate ios List al ...

  8. Android加载图片导致内存溢出(Out of Memory异常)

    Android在加载大背景图或者大量图片时,经常导致内存溢出(Out of Memory  Error),本文根据我处理这些问题的经历及其它开发者的经验,整理解决方案如下(部分代码及文字出处无法考证) ...

  9. 颜色转换:#hhhfff->UIColor (MHHexColoring)

    MHHexColoring为开发者快速获取想要的十六进制颜色(Hex Color) 查找16进制色码的网站:http://www.color-hex.com // 版权属于原作者 MHHexColor ...

  10. 模块化模式与 OSGi

    模块化模式与 OSGi Android 模块化探索与实践 一.前言 万维网发明人 Tim Berners-Lee 谈到设计原理时说过:“简单性和模块化是软件工程的基石:分布式和容错性是互联网的生命.” ...