`
zean
  • 浏览: 19219 次
  • 性别: Icon_minigender_1
  • 来自: 广州
文章分类
社区版块
存档分类
最新评论

FLEX WEB流程设计器线条、箭头的绘制

阅读更多

流程设计器里面,最复杂的其实不是拖来拖去的图片,而是线条的绘制包括锚点、箭头,如果把线条绘制好了,那设计器就没什么难度了。

绘制线条会涉及到一些数学知识,主要是三角函数、极坐标等,如果不记得了,赶紧恶补一下吧,这个是必须的。

线条绘制又分多种场景:

1 在一个节点和鼠标所在坐标之间绘制(寻找目标节点过程),这个线条要跟随鼠标的移动而不断重绘。线条的起点为节点中心点坐标与鼠标位置的连线再与节点边缘的交点(有点抽象,等会看图就明白)

可能很多人都以为是在拖动线条,其实这是一个假象,当鼠标移动时,会先擦除线条,然后重新绘制一条节点和鼠标当前位置的连线,当鼠标移动一段距离后,实际上重绘了无数次,这样线条的“拖动”就有连贯性,如果只在鼠标移动结束之后再绘制一条也可以,这样只需要重绘一次,但视觉上的效果要查很多。

2 在两个节点之间绘制,起点和终点坐标分别为两个节点中心点坐标之间的连线分别与节点边缘的交点。

3 拖动锚点(一条线条被分成几段时,子线条之间的交点)绘制,和第1点有些类似,稍微复杂点。

下面举第1种场景中节点在鼠标左上方的例子进行说明:



 上图中x的坐标即为线条的起点

X坐标的计算过程:
X横坐标X.x3=O.x+len
根据相似三角形,存在关系 (x2-x1)/(len/2)=(y2-y1)/H
H=(len/2)(y2-y1)/(x2-x1)
X点的纵坐标X.y3=O.y+len/2+H

计算X坐标的代码如下(考虑了各种场景):

 

/**
		 * 获取起始点与图片边框的交点坐标
		 * 需按矩形对角线划分四个区域(此处为正方形,每90度为一个边界)
		 * acrossNode 参照节点对象(为上图中的节点对象)
		 */
		public static function getLinkPoint(fromPoint:Point,targetPoint:Point,acrossNode:BaseNode):Point
		{
			var angle:Number=getAngel(fromPoint,targetPoint);
			/**计算交点与中心点的垂直和水平距离*/
			var distanceX:Number=Math.abs((targetPoint.x-fromPoint.x)*(acrossNode.width/2)/(targetPoint.y-fromPoint.y));
			var distanceY:Number=Math.abs((targetPoint.y-fromPoint.y)*(acrossNode.width/2)/(targetPoint.x-fromPoint.x));
			
			if(targetPoint.x<fromPoint.x)
			{
				distanceX=-distanceX;
			}
			if(targetPoint.y<fromPoint.y)
			{
				distanceY=-distanceY;
			}
			/**最终xy坐标*/
			var x:Number=0;
			var y:Number=0;
			if(angle>=45&&angle<135)
			{
				x=fromPoint.x+distanceX;
				y=acrossNode.y;
			}
			else if(angle>=135&&angle<225)
			{
				x=acrossNode.x;
				y=fromPoint.y+distanceY;
			}
			else if(angle>=225&&angle<315)
			{
				x=fromPoint.x+distanceX;
				y=fromPoint.y+acrossNode.height/2;
			}
			else
			{
				x=fromPoint.x+acrossNode.width/2;
				y=fromPoint.y+distanceY;
			}
			return new Point(x,y);
		}
		
		/**获取两点夹角的角度*/
		private static function getAngel(fromPoint:Point,targetPoint:Point):Number
		{
			/**为了与三角坐标一致,y坐标的值要反过来*/
			
			/**通过反正切计算弧度*/
			var radian:Number=Math.abs(Math.atan((targetPoint.x-fromPoint.x)/(targetPoint.y-fromPoint.y)));
			/**计算角度*/
			var angle:Number=radian*180/Math.PI;
			if((targetPoint.x>=fromPoint.x)&&(targetPoint.y<=fromPoint.y))//0~90区域 
			{
				angle=90-angle;
			}
			else if((targetPoint.x<=fromPoint.x)&&(targetPoint.y<=fromPoint.y))//90~180区域
			{
				angle=90+angle;
			}
			else if((targetPoint.x<=fromPoint.x)&&(targetPoint.y>=fromPoint.y))//180~270区域
			{
				angle=270-angle;
			}
			else if((targetPoint.x>=fromPoint.x)&&(targetPoint.y>=fromPoint.y))//270~360区域
			{
				angle=270+angle;
			}
			return angle;
		}

 

 

具体绘制线条还有一个技巧,线条绘制出来不仅是摆看的,还要加事件,可以被选取,太细了选择太困难,太粗了又太难看,一个很简单的办法就是绘制两条线,一条1个像素的实线,一条比较粗的透明线,透明线实际上是为了扩大选择区域。

 

graphics.clear();
graphics.moveTo(fromPoint.x,fromPoint.y);
graphics.lineStyle(8,color,0,true,LineScaleMode.NORMAL,CapsStyle.NONE);
graphics.lineTo(targetPoint.x,targetPoint.y);
			
graphics.moveTo(fromPoint.x,fromPoint.y);
graphics.lineStyle(DesignerConstances.LINE_THICKNESS,color);
graphics.lineTo(targetPoint.x,targetPoint.y);

 

 

绘制箭头

为了简化可绘制等边三角形



 三角形被线条平分,先计算3个顶点的坐标,然后绘制3条线,最后填充三角形

平分后的弧度各为PI/6。
1)以下为A点坐标的计算过程:
正切值tan(a)=(y2-y1)/(x2-x1)
通过反正切得弧度a=atan(tan(a))
角AP2O的弧度θ为a+b=a+PI/6
H=len*Sin(θ)
W=len*Cos(θ)
A.x3=P2.x2-W,A.y3=P2.y2-H
2)同理,通过弧度c=PI/6-a可计算出B的坐标.

 

 

/**
		 * 根据线条起始点绘制三角形
		 */
		public function draw(ui:UIComponent,fromPoint:Point,toPoint:Point,color:uint):void
		{
			var vDistance:Number= toPoint.y-fromPoint.y;//起始点垂直距离
			var sDistance:Number=Point.distance(fromPoint,toPoint);//起始点直线距离
			
			var sinValue:Number=vDistance/sDistance;//起始点间的夹角的sin值
			
			/**两点间直线与水平线的角度(弧度)*/
			var radian:Number=Math.asin(sinValue);
			/**用于计算三角形顶点与目标点水平距离的夹角(弧度)*/
			var hRadian:Number=radian-Math.PI/6;
			
			/**用于计算三角形顶点与目标点垂直距离的夹角(弧度)*/
			var vRadian:Number=radian+Math.PI/6;
			/**上顶点与目标点的垂直距离*/
			var topYDis:Number=8*Math.sin(vRadian);
			/**上顶点与目标点的水平距离*/
			var topXDis:Number=8*Math.cos(vRadian);
			/**下顶点与目标点的垂直距离*/
			var botYDis:Number=8*Math.sin(hRadian);
			/**下顶点与目标点的水平距离*/
			var botXDis:Number=8*Math.cos(hRadian);
			
			/**计算三角形上下顶点坐标*/
			var topPointX:Number=toPoint.x-topXDis;
			var topPointY:Number=toPoint.y-topYDis;
			
			var botPointX:Number=toPoint.x-botXDis;
			var botPointY:Number=toPoint.y-botYDis;
			if(toPoint.x<fromPoint.x)
			{
				topPointX=toPoint.x+topXDis;
				botPointX=toPoint.x+botXDis;
			}

			ui.graphics.beginFill(color);
			ui.graphics.moveTo(topPointX,topPointY);
			ui.graphics.lineTo(toPoint.x,toPoint.y);
			ui.graphics.lineTo(botPointX,botPointY);
			ui.graphics.lineTo(topPointX,topPointY);
		}

 

 

 

绘制锚点

以下列出开始节点在结束节点左上方时,起始位置的锚点为例,所有锚点坐标通过极坐标换算(x = r*cos(θ) y = r*sin(θ),r为半径)
前置条件:矩形为正方形,边长为len,矩形被连线平分,即两边中心点与两个个交叉点重合
1) 计算锚点与连线的第二个交叉点X的坐标



 以下为X点的坐标的计算过程
正切值 tan(a)= (y2-y1)/(x2-x1)
由反正切得弧度a=atan(tan(a))
由平行线得出 b=a
极坐标半径 r=len
极坐标弧度θ=2PI-b
X的极坐标X.x3 = r*cos(θ),X.y3 = r*sin(θ)
X的实际坐标为 (P1.x1+ X.x3,P1.y1+X.x3)

 计算四个顶点值



 以下为计算A点坐标过程:
正切值 tan(a)=(y2-y1)/(x2-x1)
由反正切得弧度a=atan(tan(a));
由平行线得出 b=a
极坐标弧度c=PI/4-b
极坐标半径r即线AO为 len*len/4 的平方根
极坐标A.x = r*cos(c),A.y = r*sin(c)
实际坐标为 (x0+A.x,y0-A.y)

 

/**
		 * 极坐标计算矩形四个顶点
		 * x = r*cos(θ) y = r*sin(θ)
		 */ 
		private function drawAnchor(holder:UIComponent,fromPoint:Point,targetPoint:Point):void
		{
			var tan:Number=(fromPoint.x-targetPoint.x)/(targetPoint.y-fromPoint.y);
			var leftTopRadian:Number=Math.PI-(Math.PI/4-Math.atan(tan));//左上顶点弧度
			var r:Number=getRadius();//半径
			var centerPoint:Point=this.getCenterPoint(fromPoint,targetPoint);
			/**计算四个顶点坐标*/
			var leftTopPoint:Point=new Point(r*Math.cos(leftTopRadian)+centerPoint.x,r*Math.sin(leftTopRadian)+centerPoint.y);
			var leftBottomPoint:Point=new Point(r*Math.cos(leftTopRadian+Math.PI/2)+centerPoint.x,r*Math.sin(leftTopRadian+Math.PI/2)+centerPoint.y);
			var rightBottomPoint:Point=new Point(r*Math.cos(leftTopRadian+Math.PI)+centerPoint.x,r*Math.sin(leftTopRadian+Math.PI)+centerPoint.y);
			var rightTopPoint:Point=new Point(r*Math.cos(leftTopRadian+3*Math.PI/2)+centerPoint.x,r*Math.sin(leftTopRadian+3*Math.PI/2)+centerPoint.y);
			
			/**画线*/
			with(holder)
			{
				graphics.lineStyle(1,DesignerConstances.COLOR_LINE_SELECTION);
				graphics.beginFill(0xFFFFFF);
				graphics.moveTo(leftTopPoint.x,leftTopPoint.y);
				
				graphics.lineTo(leftBottomPoint.x,leftBottomPoint.y);
				graphics.lineTo(rightBottomPoint.x,rightBottomPoint.y);
				graphics.lineTo(rightTopPoint.x,rightTopPoint.y);
				graphics.lineTo(leftTopPoint.x,leftTopPoint.y);
				graphics.endFill();
			}
		}
/**极坐标半径*/
		private function getRadius():Number
		{
			return Math.sqrt(Math.pow(DesignerConstances.ANCHOR_LENGTH/2,2));
		}
/**连线中心点坐标 */
		private function getCenterPoint(fromPoint:Point,targetPoint:Point):Point
		{
			return new Point((targetPoint.x+fromPoint.x)/2,(targetPoint.y+fromPoint.y)/2);
		}

 

 

 

 

  • 大小: 4.9 KB
  • 大小: 5.9 KB
  • 大小: 5.2 KB
  • 大小: 6.1 KB
分享到:
评论
3 楼 fireinjava 2012-07-08  
很强大
2 楼 appleman4000 2011-06-19  
我也在做,用flex 4 spark skin 渲染组件,界面和逻辑分开 ,效果不错
有空一起探讨探讨
1 楼 zean 2011-06-16  
自己路过……

相关推荐

    基于Flex的Web流程设计器开发

    基于 Flex 的 Web 流程设计器开发 本文将详细介绍基于 Flex 的 Web 流程设计器的开发,包括其背景、技术路线选择、架构设计、前端设计和后台设计等方面的内容。 Web 流程设计器的背景 ------------------ 在开发 ...

    flex web工作流程图

    Flex Web工作流程图是一种利用Adobe Flex技术创建的用于设计和展示流程、工作流或系统交互的可视化工具。Flex是一款强大的开发框架,主要用于构建富互联网应用程序(Rich Internet Applications, RIA),它基于...

    Flex流程设计器

    Flex流程设计器是一款基于Adobe Flex技术开发的业务流程设计工具,其源码的提供为开发者提供了深入理解并定制流程设计功能的机会。Flex是一种用于构建富互联网应用程序(RIA)的开源框架,它基于ActionScript编程...

    flex wf流程设计器(Workflow)

    Flex WF流程设计器是一款基于Adobe Flex技术开发的可视化工作流设计工具。它允许用户通过图形化界面来设计和构建复杂的业务流程,最终生成的XML文件能够与各种后台系统进行集成,符合JBPM(Java Business Process ...

    基于Flex的web流程设计器

    OrchestraDesigner是由北京航空航天大学计算机学院新技术研究所自主开发的一款基于Flex技术的在线协同工作流编辑工具。该建模工具针对非技术人员,采用一种比BPEL更面向业务、更直观的图元作为建模基础,生成的模型...

    flex4 流程设计器

    不错的流程设计器,实现了连线,拖动,修改属性等,,,

    web流程图设计器 flex版(二)

    NULL 博文链接:https://2621380266.iteye.com/blog/1774767

    流程设计器(flex版)

    《流程设计器(flex版)详解》 流程设计器(flex版)是一种基于Adobe Flex技术的图形化工具,主要用于设计和构建业务流程。Flex是Adobe公司推出的一种开放源代码的富互联网应用(RIA)开发框架,它允许开发者创建具有...

    flex 自定义 制作 流程图 (五种)

    flex 流程图 制作 flex 流程图 制作flex 流程图 制作flex 流程图 制作flex 流程图 制作flex 流程图 制作flex 流程图 制作flex 流程图 制作flex 流程图 制作flex 流程图 制作flex 流程图 制作flex 流程图 制作flex ...

    ArcGIS Flex API和SuperMap Flex API实现的军标箭头库

    在军标箭头库的实现中,开发者可能利用了ArcGIS Flex API的图形对象和符号系统来绘制各种军标箭头,这些箭头可以表示战术动作、方向或兵力部署等。 另一方面,SuperMap Flex API则是SuperMap公司为Flex开发者提供的...

    flex 3.0流程编辑器修改版源码

    在我们所讨论的"flex 3.0流程编辑器修改版源码"中,重点集中在流程图的绘制、元素的拖动、线条的连接以及箭头的处理等方面。 首先,流程编辑器的核心功能在于流程图的创建。流程图是表示工作流程或系统状态变迁的...

    流程设计,extjs、flex、web下的流程设计

    "OrchestraDesigner-3.2-bin"是一个基于Flex的Web流程设计器,它允许用户在Web浏览器中设计和编辑工作流程。这种设计器通常具备图形化的界面,使得非技术人员也能理解和修改流程。 Web工作流管理系统开发是现代企业...

    flex 流程设计器

    flex 流程设计器,flex 流程设计器

    flex 实现 的流程设计器

    总结起来,使用Flex实现的流程设计器涉及图形绘制、事件处理、数据模型构建、数据绑定、工作流逻辑、用户交互、文件导入导出以及系统可扩展性等多个方面。通过熟练掌握和运用这些知识点,开发者可以构建出强大且灵活...

    flex流程设计器源码

    2. **图形用户界面(GUI)设计**:作为一款图形化设计器,Flex流程设计器利用了Flex中的图形绘制和布局管理功能,如Canvas组件用于自定义绘图,以及Layout Manager来处理组件的排列和尺寸计算。 3. **工作流模型**...

    flex画web流程(增加了删除线,选择线条,本地保持等功能)

    标题中的“flex画web流程”指的是使用Adobe Flex技术来创建Web应用程序,特别是涉及到流程图的绘制和管理。Flex是一款强大的开发工具,它基于ActionScript语言和MXML标记语言,允许开发者构建富互联网应用(RIA)。...

    flex 画流程图 流程编辑

    流程编辑器允许用户直观地设计和修改流程,这对于提高工作效率和理解复杂逻辑非常有帮助。 标题所提及的“flex 画流程图 流程编辑”主要涉及以下几个知识点: 1. **Flex图形组件**:Flex中包含了一系列用于绘制...

    flex 画流程图 简单demo

    这个简单的Flex流程图Demo是一个很好的起点,适合初学者学习如何在Flex环境中创建图形化的用户界面,并理解Flex组件、事件处理和图形绘制的概念。通过研究源代码和实践,可以深入了解Flex编程并提升开发技能。

    flex 工作流设计器

    Flex工作流设计器是一种基于Adobe Flex技术的工具,用于创建、编辑和管理业务流程。它提供了图形化的用户界面,使得非技术人员也能理解并构建复杂的业务逻辑。在本文中,我们将深入探讨Flex工作流设计器的主要功能、...

    精典flex图形化流程设计器源码

    Flex图形化流程设计器源码是一套用于创建和编辑工作流的高级开发工具,它基于Adobe Flex技术,提供了直观的可视化界面,使得用户可以方便地构建、定制和管理各种业务流程。这一源码对于开发者来说是极其宝贵的资源,...

Global site tag (gtag.js) - Google Analytics