详解WPF Blend工具中的复合路径功能 ( 含路径标记语法 )
2013-11-14 01:31
232 查看
写此文章的目的是为了简单分析一下Blend工具中提供的"复合路径"功能.有人在我的博文中留言问我复合路径的问题.
稍微琢磨一下,觉得应该是对的.因此贴出来和大家分享.有不对的说错的欢迎指正.
在此之前我们先了解一下WPF的"路径标记语法"
M:表示绘制起点//M0,0
L:表示绘制直线(H:横线V:竖线)//L100,0
C:三次方贝塞尔曲线//C100,200200,400300,200
Q:二次曲线
z:闭合
......
要注意的是每一次的绘制都是基于上一次的终点(或者原点M)
例如M0,0L100,0L200,50表示移动绘制原点到(0,0)然后绘制直线到(100,0)紧接着从(100,0)开始再绘制直线到(200,50),也就是说每一次绘制命令都是接着上一次开始的.
*手写语法命令的时候注意空格的使用,以及逗号的使用.
等等MSDN有详细介绍不了解的可以去看看.
大致了解路径标记语法后我们来探讨一下"复合路径"功能.
首先我们绘制两条线
(一)
看下效果
我们在看Blend->复合路径后的代码
我们仔细观察复合前的2个Path.Data的语法和复合后的Path.Data的差别.
看看看看看看....嗯...IQ处理中......................
我们把前两个拼起来看看!
看看后两个Path有什么一样的地方吗?!
是的Blend好像也是给拼接起来的?可是为什么有2.5的误差呢?为什么每个数都是2.5怎么不是0.1不是其他呢?奥秘就在这里:StrokeThickness="5"
2.5正好是5的一半嘛,是的,这个2.5只是算了粗细而已.我们可以去掉它也不会影响整体的形状的.
当我们把5改为1后(什么你说改成0??0像素好粗啊会闪下我氪金狗眼的!别闹~~~)
再使用复合路径得到的数据是M0.5,0.5L50.5,120.5M0.5,0.5L150.5,120.5,看看"误差"变为0.5了吧.如果你手动去掉所有的小数,那么你会看到形状不变的.这里我就不去演示了.
那么我们初步得到结论:复合路径=路径1+路径2+路径3+.....(拼接所有的路径部分).
(二)
下面我们再来看一组数据:
效果:
在看Blend复合后的代码:
首先我们基于(一)的结论忽略掉粗细误差2.5(顺便验证一下这个结论)得到结果
Blend中我们看到形状位置都没变.
接下来我们尝试手动拼接上面(二)的2个Path得到
这是为什么?怎么分离的这么远?
我们来解密一下:
看看第二条Path他有这个附加属性Canvas.Left="50"居然给右移了50!!!!那么我们给他挪回去试试?
得到
/*******************************************************/
欢迎转载!欢迎拍砖!
版权所有©Vito野子
E-mail:vito2015@live.com
转载请注明出处/article/7001340.html
/*******************************************************/
稍微琢磨一下,觉得应该是对的.因此贴出来和大家分享.有不对的说错的欢迎指正.
在此之前我们先了解一下WPF的"
M:表示绘制起点//M0,0
L:表示绘制直线(H:横线V:竖线)//L100,0
C:三次方贝塞尔曲线//C100,200200,400300,200
Q:二次曲线
z:闭合
......
要注意的是每一次的绘制都是基于上一次的终点(或者原点M)
例如M0,0L100,0L200,50表示移动绘制原点到(0,0)然后绘制直线到(100,0)紧接着从(100,0)开始再绘制直线到(200,50),也就是说每一次绘制命令都是接着上一次开始的.
*手写语法命令的时候注意空格的使用,以及逗号的使用.
等等MSDN有详细介绍不了解的可以去看看.
大致了解路径标记语法后我们来探讨一下"复合路径"功能.
首先我们绘制两条线
(一)
<Canvas> <PathData="M0,0L50,120"Stretch="Fill"Stroke="red"StrokeThickness="5"/> <PathData="M100,0L250,120"Stretch="Fill"Stroke="green"StrokeThickness="5"/> </Canvas>
看下效果
我们在看Blend->复合路径后的代码
<PathData="M2.5,2.5L52.5,122.5M2.5,2.5L152.5,122.5"Stretch="Fill"Stroke="red"StrokeThickness="5"/>
我们仔细观察复合前的2个Path.Data的语法和复合后的Path.Data的差别.
看看看看看看....嗯...IQ处理中......................
我们把前两个拼起来看看!
//拼前: <PathData="M0,0L50,120"Stretch="Fill"Stroke="red"StrokeThickness="5"/> <PathData="M100,0L250,120"Stretch="Fill"Stroke="green"StrokeThickness="5"/> //拼后: <PathData="M0,0L50,120M100,0L250,120"Stretch="Fill"Stroke="red"StrokeThickness="5"/> //Blend复合的: <PathData="M2.5,2.5L52.5,122.5M2.5,2.5L152.5,122.5"Stretch="Fill"Stroke="red"StrokeThickness="5"/>
看看后两个Path有什么一样的地方吗?!
是的Blend好像也是给拼接起来的?可是为什么有2.5的误差呢?为什么每个数都是2.5怎么不是0.1不是其他呢?奥秘就在这里:StrokeThickness="5"
2.5正好是5的一半嘛,是的,这个2.5只是算了粗细而已.我们可以去掉它也不会影响整体的形状的.
当我们把5改为1后(什么你说改成0??0像素好粗啊会闪下我氪金狗眼的!别闹~~~)
再使用复合路径得到的数据是M0.5,0.5L50.5,120.5M0.5,0.5L150.5,120.5,看看"误差"变为0.5了吧.如果你手动去掉所有的小数,那么你会看到形状不变的.这里我就不去演示了.
那么我们初步得到结论:复合路径=路径1+路径2+路径3+.....(拼接所有的路径部分).
(二)
下面我们再来看一组数据:
<PathData="M0,0L50,120"Stretch="Fill"Stroke="red"StrokeThickness="5"/> <PathData="M100,0L300,120"Canvas.Left="50"Stretch="Fill"Stroke="red"StrokeThickness="5"/>
效果:
在看Blend复合后的代码:
<PathData="M2.5,2.5L52.5,122.5M52.5,2.5L252.5,122.5"Stretch="Fill"Stroke="red"StrokeThickness="5"/>
首先我们基于(一)的结论忽略掉粗细误差2.5(顺便验证一下这个结论)得到结果
<PathData="M0,0L50,120M50,0L250,120"Stretch="Fill"Stroke="red"StrokeThickness="5"/>
Blend中我们看到形状位置都没变.
接下来我们尝试手动拼接上面(二)的2个Path得到
<PathData="M0,0L50,120"Stretch="Fill"Stroke="red"StrokeThickness="5"/> <PathData="M100,0L300,120"Canvas.Left="50"Stretch="Fill"Stroke="green"StrokeThickness="5"/> 手动拼接: <PathData="M0,0L50,120M100,0L300,120"Stretch="Fill"Stroke="red"StrokeThickness="5"/>
这是为什么?怎么分离的这么远?
我们来解密一下:
看看第二条Path他有这个附加属性Canvas.Left="50"居然给右移了50!!!!那么我们给他挪回去试试?
得到
<PathData="M0,0L50,120"Stretch="Fill"Stroke="red"StrokeThickness="5"/> <PathData="M100,0L300,120"Canvas.Left="50"Stretch="Fill"Stroke="green"StrokeThickness="5"/> 手动拼接: <PathData="M0,0L50,120M100,0L300,120"Stretch="Fill"Stroke="red"StrokeThickness="5"/>
把第二个Path的Left50左移回去得到:<PathData="M0,0L50,120M50,0L250,120"Stretch="Fill"Stroke="red"StrokeThickness="5"/>
左移后<PathData="M0,0L50,120M50,0L250,120"Stretch="Fill"Stroke="red"StrokeThickness="5"/>效果:是不是一样了!左移第二条线是移动原点M和L的横坐标所以得到M50,0L250,120" (被左移-X需要减掉相应值.被右移-X需要加上相应值) 上下移同理,上移(Top负数)需加,下移(Top正数)需减 这个过程我们暂且称为"复位" 因此我们又得到一个结论Canvas.Left同样会影响复合路径!当然这里也包括Canvas.Top/Right/Bottom, 值得提醒的是当Left/Top等的值为负数时直接简单拼接和"复位"是不对的.因为你可能复不到位.不信你试试看. 这里稍微解释一下标记语法一个特别的地方(我猜的!没有去MSDN考证.) <PathData="M100,0L300,120"Stretch="Fill"Stroke="green"StrokeThickness="5"/> <PathData="M0,0L200,120"Stretch="Fill"Stroke="green"StrokeThickness="5"/> <PathData="M-100,0L100,120"Stretch="Fill"Stroke="green"StrokeThickness="5"/> 这3个Path是一样的! 当Path中只有一段图形时(这里是只有一段Line),Line整体平移(指的是原点从0,0平移到100,0且端点从200,120平移到300,120)是不会影响Path形状和位置的. 因此在只有一段图形的Path中我们可以约掉这个平移我们暂且称为"约分"(参考数学分数的约分哈,不严谨好记而已~~) 所以上面我说当Canvas.Left为负数时不能简单直接拼接和复位.怎么办呢?我们需要先约分!先把所有能约分的线段的原点约分到不能再约分的实际原点, 例如上面的三个Path的实际原点其实都是M0,0.约分处理完所有图形片段后再进行拼接和复位.最后就能得到复合路径的结果了. 另外,凡是所有能影响Path位置的属性改变都会影响复合路径的结果,比如RenderTransform和Margin等. 如果想手动去算复合路径可能是非常繁琐的一个过程~~~您可能需要为所有影响Path位置变化的属性改变都写一个复位的方法.在执行复合路径之前需要先调用所有的复位/约分方法来恢复Path的Data到实际值.再进行拼接计算. 以上是我粗略分析后的一些看法和结论.我之前也不知道这些的,只不过是在我的一片 自定义MessageBox的文章中有人问我这个问题,我就试着猜猜. 这位童鞋@距离永远您可请俺喝酒啊!!嘻嘻~~ 如果哪位童鞋有在code中动态计算路径的需求,不妨参考一下此文. 在下拙见,若有达人,不吝赐教!
/*******************************************************/
欢迎转载!欢迎拍砖!
版权所有©
E-mail:
转载请注明出处
/*******************************************************/
相关文章推荐
- Win7中隐藏的上帝模式——GodMode
- java 简单的单例模式 例子
- Android 4.4 Kitkat 编译时对于存储器挂载方式的修改,以泛泰820,860为例
- [未解决]数据库异常:多步 OLE DB 操作产生错误。如果可能,请检查每个 OLE DB 状态值。
- window API一天一练之邮槽
- wamp5如何配置多个自定义域名访问本地不同的项目
- Fedora 18/19没有注销
- C# 中有关 using 关键字
- 【数据挖掘概念与技术】学习笔记5-数据立方体技术
- Find M Integers from an Array of Size N equally
- svg图形
- C#中IPAddress和IPEndPoint的关系
- HDR照片算法去抖动
- 根据用户需求分析同行提升网站关键词排名
- 将博客搬至CSDN
- 转帖:粘包、丢包及TCP信息收发
- C# 多线程 线程中参数传递
- MyEclipse+Struts+Hibernate+Mysql开发环境配置
- PHP結合PYTHON的一個小例子
- 单片机C语言模板