My Silverlight系列(10)—— Silverlight中的InkCanvas
2009-04-25 12:04:36 来源:WEB开发网其中DrawingAttributes这个属性是用于描述画笔的颜色的,而StylusPoints描述了Stroke内点的集合。学过数学的人都知道,线是由点组成的,因此只要我们找到了应该插入到这个Stroke中所有的点,那么生成一个新的Stroke不在话下。所幸MouseEventArgs中,有一个StylusDevice只读属性,而它的一个公共方法public StylusPointCollection GetStylusPoints(UIElement relativeTo)可以在鼠标事件触发的时候,得到这些“点”的集合。我们只需要为InkPresenter加上MouseLeftButtonDown,MouseMove,MouseLeftButtonUp三个handler,那么我们就可以在鼠标进行轨迹上把那些点加到线上,并将这条线加入到InkPresenter这个“面”里。代码比较多,最后我会把工程放在下面,就不一段一段的贴了。
其实这个Ink模式,不算什么难点,而后面这个EraseByStroke也相对简单,最笨的方法就是遍历InkPresenter内所有的Stroke,然后一一检验它是否与我们的"Eraser"有交叉,如果有,则将它Remove。但是,最后这个EraseByPoint可没那么容易了,因为当橡皮将一条线拦腰截断的时候,不但要把擦掉的部分去掉,还要把余下的两段保留在Strokes这个StrokeCollection中,这才能达到一分为二的效果。我最初在实现这个功能的时候,由于设计的算法时间复杂度居高不下,造成如果相交的线过多,或者橡皮拖动太快,就会出现卡死的现象。在与微软silverlight开发小组的stefan swick交流之后,他决定实现这一功能,并且将其做成一个Custom Control。昨天他告诉我他把这个东西做好了,要我去他的Blog上下载。今天我仔细研究了他的算法,发现这个算法与我的算法有一个最大的不同之处就是:我在将一条线一分为二的过程中,完全是按照从前向后的顺序,将每个点一一挎贝并缓存,从前向后判断这个点是否被橡皮擦中,如果被擦中的话,马上生成一个新的Stroke,把旧的加入Strokes内,并对新的Stroke进行上述相同的操作。而stefan的算法则分为了两个部分,首先从前向后把前面没有被擦中的点取出来存到一个新的Stroke中,然后停止,再从后往前寻找后面的点,将没有被擦中的点加入到一个新的Stroke中,直到遇到被擦中的点停止。这样的话,可以保证一个Stroke可以被一分为二。
Tags:My Silverlight 系列
编辑录入:爽爽 [复制链接] [打 印]更多精彩
赞助商链接