`
sherrysky
  • 浏览: 88905 次
  • 性别: Icon_minigender_2
  • 来自: 北京
社区版块
存档分类
最新评论

flex+degrafa自定义曲线ployline绘制

阅读更多
应用程序
<?xml version="1.0" encoding="utf-8"?>
<mx:Application	xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
				xmlns:degrafa="com.degrafa.*"
				xmlns:paint="com.degrafa.paint.*"
				xmlns:geometry="com.degrafa.geometry.*" viewSourceURL="srcview/index.html" 
				 backgroundColor="#ffffff" xmlns:local="*"
				 creationComplete="inipolyline()" xmlns:text="flash.text.*">
				
	<degrafa:Surface id="asur">
	
		<!-- Creating fills. -->
		<degrafa:fills>
			<paint:SolidFill	id="blue"
								color="#62ABCD"/>
		</degrafa:fills>
		
		<!-- Creating Strokes. -->
		<degrafa:strokes>
			<paint:SolidStroke	id="black"
								color="#000000"
								alpha="1"
								weight="3"/>
			<paint:SolidStroke	id="red"
								color="#FF0000"
								alpha="1"
								weight="3"/>
		</degrafa:strokes>
		<!-- Creating Polyline-->
		<!-- Creating a Geometry Group. -->
		<degrafa:GeometryGroup x="0" y="0">
		
			<!-- Creating a Polygon. -->
			<geometry:Polyline stroke="{black}">
				<geometry:data>0,0 0,20 20,20 20,40 40,40 40,60</geometry:data>
			</geometry:Polyline>
			
		</degrafa:GeometryGroup> 
		<!--自定义曲线-->
		<degrafa:GeometryGroup x="0" y="100" id="geopolytl"/>
	</degrafa:Surface>
	<mx:Button  click="deletepolyline()"  label="deletepolyline" x="100" y="0"/>
	<mx:Script>
		<![CDATA[
			import com.degrafa.GraphicText;
			import com.degrafa.IGeometry;
		public function deletepolyline():void
		{
			    for each(var g:GeometryGroup in asur.graphicsCollection.items)
	        {
	            g.target = null;
	            g.visible = false;
	            for each(var o:IGeometry in g.geometryCollection.items)
	            {
	                o.data = "";
	                g.geometryCollection.removeItem(o);
	            }
	            g.geometry.length = 0;
	            g = null;
	        }
	        asur.graphicsCollection.items.length = 0;
		}
		public function inipolyline():void
		{
		    var polytl: DashedPolylinetl= new DashedPolylinetl();
	        polytl.dash=10;
	        polytl.gap=4;
	        polytl.style=2;
	        var datastl:String="0,0 0,20 20,20 20,40 40,40 40,60 60,60 60,0 ";
	        polytl.data=datastl;
	        polytl.colour=0x1f1fd5;
	        geopolytl.geometryCollection.addItem(polytl);         
		}
			
		]]>
	</mx:Script>
</mx:Application>

自定义的类dashpolylinet1
package  
{   
	import com.degrafa.core.collections.GraphicPointCollection;
	import com.degrafa.geometry.Polyline;
	
	import flash.display.Graphics;
	import flash.geom.Rectangle;
	
	import mx.events.PropertyChangeEvent;
public class DashedPolylinetl extends Polyline
{   
	/**
	 * 构造函数,其中定义了style属性的change事件
	 * */
	public function DashedPolylinetl(points:Array=null)
	{
		super(points);
		addEventListener(PropertyChangeEvent.PROPERTY_CHANGE,redraw);
	}
   /**
   * commandstack用于存储直线绘制信息,主要是moveto和lineto命令 
   **/
    public var	commandstack:Array = new Array();
    private var _points:GraphicPointCollection;
    public var _bounds:Rectangle=new Rectangle();
   
   	override	public function get points():Array{
			if(!_points){_points = new GraphicPointCollection();}
			return _points.items;
		}
	override	public function set points(value:Array):void{			
			if(!_points){_points = new GraphicPointCollection();}
			_points.items = value;
						
			//add a listener to the collection
			if(_points && enableEvents){
				_points.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE,propertyChangeHandler);
			}
			
			invalidated = true;
		
		}
        
        /**
        * 计算dashpolyline的外接矩形
		**/
		  private function calcBounds():void{
		
			var boundsMaxX:Number =0;
			var boundsMaxY:Number =0;
			var boundsMinX:Number =Number.MAX_VALUE;
			var boundsMinY:Number =Number.MAX_VALUE;
						
			for (var i:int = 0;i< _points.items.length; i++) 
			{
				boundsMaxX = Math.max(boundsMaxX, _points.items[i].x);
				boundsMaxY = Math.max(boundsMaxY, _points.items[i].y);
				
				boundsMinX= Math.min(boundsMinX, _points.items[i].x);
				boundsMinY= Math.min(boundsMinY, _points.items[i].y);
				
			}

			_bounds = new Rectangle(boundsMinX,boundsMinY,boundsMaxX-boundsMinX,boundsMaxY-boundsMinY);

		}	
   
   public var length:Number;

   private var _dash:Number;
    /**
     * 每段直线的长度,默认值为0
     **/
    public function get dash():Number
    {
    	if (!_dash)
    		return 0;
		return _dash;
    }
    public function set dash(value:Number):void
    {
		if (_dash != value)
		{
			_dash = value;
			if (gap == 0)
				gap = value;			
			invalidated = true;
        }
    }
    
    private var _style:int;
    
    public function get style():int
    {   if(!_style)
            return 0;
    	return _style;
    }
    
    /**
    * 在style属性change之后分发PropertyChangeEvent事件
    **/
    public function set style(value:int):void
    { 
    	
     if(_style != value)
     {
     	_style=value;
     	invalidated= true;
     }	
     dispatchEvent(new PropertyChangeEvent(PropertyChangeEvent.PROPERTY_CHANGE,false,false, null,int,null,null,this.style));
    }
    
    private var _gap:Number;
  
    /**
     *每段直线之间的距离,默认值为0
     **/
    public function get gap():Number
    {
    	if (!_gap)
    		return 0;
		return _gap;
    }
    public function set gap(value:Number):void
    {
		if (_gap != value)
		{
			_gap = value;
			invalidated = true;
        }
    }
    private var _colour:uint;
  
    /**
     *线的颜色
     **/
    public function get colour():uint
    {
    	if (!_colour)
    		return 0;
		return _colour;
    }
    public function set colour(value:uint):void
    {
		if (_colour != value)
		{
			_colour = value;
			invalidated = true;
        }
    }

	/**
     * 用于绘制之前的指令算法存储至commandstack数组中
     * 根据style值,重组绘制线的数据;
     * style=4,线形为直线,无论如何设置dash,gap,都按照原始data两点一连画直线;
     * style=0,线形为虚线,dash为虚线线段长,gap为虚线间隔,根据二者对原始data进行重组,新的data数据点数大于原始data点个数;
     *         要保证虚线效果,dash+gap必须小于线任意两点间隔或最小距离两点间的距离
     * style=2,线形为虚线并且间隔中有两点,dash为虚线线段长,gap为虚线间隔,根据二者对原始data进行重组,新的data数据点数大于原始data点个数;
     *         要保证效果,该线形适用于数据点任意两点距离大于20的data,线中dash+gap必须小于线任意两点间隔或最小距离两点间的距离,
     *         gap中画了两个点,其位置和gap,dash都有关系,两点距离为20时,dash=10,gap=10,能看到两点效果;算法需要继续改进
     * style=3,线形为虚线并且间隔中有一点,dash为虚线线段长,gap为虚线间隔,根据二者对原始data进行重组,新的data数据点数大于原始data点个数;
     *         要保证效果,该线形适用于数据点任意两点距离大于20的data,线中dash+gap必须小于线任意两点间隔或最小距离两点间的距离,
     *         gap中画了一个点,其位置和gap,dash都有关系,两点距离为20时,dash=5,gap=5,能看到效果;算法需要继续改进
     * style=1,线形为铁路线,算法有问题,无法画出来效果图
      **/
    override public function preDraw():void
    {
		if(invalidated)
		{  
	    	super.preDraw();
          if(points.length==0){ return;}
            commandstack.length=0;                                            
			commandstack.push({type:"m",x:points[0].x+x,y:points[0].y+y});
			//如果style=4,即使设置了dash,gap,它们也不起作用
			if (style==4)
			{    
				for (var i:int = 0;i < points.length; i++)
				{
					commandstack.push({type:"l",x:points[i].x+x,y:points[i].y+y});
				}  
			}
			else
			{   
			   for (var j:int = 0;j < points.length-1; j++)
				switch(style)
				{
				case 0:
					addDashCommands0(commandstack, points[j].x+x, points[j].y+y,points[j+1].x+x, points[j+1].y+y);
				    break;
				case 1:
					  addDashCommands1(commandstack, points[j].x+x, points[j].y+y,points[j+1].x+x, points[j+1].y+y);
                      break;
				case 2:
				case 3:
					addDashCommands2(commandstack, points[j].x+x, points[j].y+y,points[j+1].x+x, points[j+1].y+y);
				      	break;
				default: break;      
				}
			}
                        
			/**
			 * 用于封闭的polyline
			 * */
			if(autoClose)
			{
				commandstack.push({type:"l",x:points[0].x+x,y:points[0].y+y});
			}
	    	calcBounds();
			invalidated = false;
	    }
            
    }
    
    protected var leftOver:int = 0;
    protected var leftOverCount:int = 0;
    
    /**
    *绘制虚线的commandstack命令
    **/
    protected function addDashCommands0(commandstack:Array, x1:int, y1:int, x2:int, y2:int):void
    {
		var length:Number = Math.abs(Math.sqrt(Math.pow(x1-x2, 2) + Math.pow(y1-y2, 2)));  //线段长度
		var count:int = leftOverCount;
		var currentLength:int = 0;  //当前长度
		var ratio:Number = 1;       //比例
		while (currentLength < length)
		{
			
			// 绘制直线
			if (count % 2 == 0)
			{
				currentLength += dash - leftOver;
				ratio = Math.min(1,(currentLength / length));
				commandstack.push({type:"l",x:x1 + ((x2-x1)*ratio),y:y1 + ((y2-y1)*ratio)});
			}
			else
			{
				currentLength += gap - leftOver;
				ratio = Math.min(1,(currentLength / length));
				
				commandstack.push({type:"m",x:x1 + ((x2-x1)*ratio),y:y1 + ((y2-y1)*ratio)});
			}
			if (currentLength > length)
			{
				leftOver = ((count % 2 == 0) ? dash : gap) - (currentLength - length);
				leftOverCount = count;
			}
			else
			{
				leftOver = 0;
				leftOverCount = 0;
			}
			count++;
		}     	
    }
    
        /**
        * 绘制铁路线的commandstack命令
        **/ 
         protected function addDashCommands1(commandStack:Array, x1:int, y1:int, x2:int, y2:int):void
    {
		var length:Number = Math.abs(Math.sqrt(Math.pow(x1-x2, 2) + Math.pow(y1-y2, 2)));  //线段长度
		var count:int = leftOverCount;
		var currentLength:int = 0;  //当前长度
		var ratio:Number = 1;       //比例
		while (currentLength < length)
		{
			
			// dash
			if (count % 2 == 0)
			{
				currentLength += dash - leftOver;
				ratio = Math.min(1,(currentLength / length));
				commandStack.push({type:"l",x:x1 + ((x2-x1)*ratio),y:y1 + ((y2-y1)*ratio)});
			}
			else
			{
				currentLength += gap - leftOver;
				ratio = Math.min(1,(currentLength / length));
				
				commandStack.push({type:"mm",x:x1 + ((x2-x1)*ratio),y:y1 + ((y2-y1)*ratio)});
			}
			if (currentLength > length)
			{
				leftOver = ((count % 2 == 0) ? dash : gap) - (currentLength - length);
				leftOverCount = count;
			}
			else
			{
				leftOver = 0;
				leftOverCount = 0;
			}
			count++;
		}    	
    }
    
    /**
    * 绘制单点线或者双点线的commandstack命令
    **/  
            protected function addDashCommands2(commandstack:Array, x1:int, y1:int, x2:int, y2:int):void
    {
		length= Math.abs(Math.sqrt(Math.pow(x1-x2, 2) + Math.pow(y1-y2, 2)));  //线段长度
		var count:int = leftOverCount;
		var currentLength:int = 0;  //当前长度
		var ratio:Number = 1;       //比例
		while (currentLength < length)
		{
			
			// dash
			if (count % 2 == 0)
			{
				currentLength += dash - leftOver;
				ratio = Math.min(1,(currentLength / length));
				commandstack.push({type:"l",x:x1 + ((x2-x1)*ratio),y:y1 + ((y2-y1)*ratio),x0:x2-x1,y0:y2-y1,xd:((x2-x1)*ratio),yd:((y2-y1)*ratio)});
			}
			else
			{
				currentLength += gap - leftOver;
				ratio = Math.min(1,(currentLength / length));
				
				commandstack.push({type:"m",x:x1 + ((x2-x1)*ratio),y:y1 + (y2-y1)*ratio});
			}
			if (currentLength > length)
			{
				leftOver = ((count % 2 == 0) ? dash : gap) - (currentLength - length);
				leftOverCount = count;
			}
			else
			{
				leftOver = 0;
				leftOverCount = 0;
			}
			count++;
		}     	
    }
           /**
           * 根据style参数来绘制不同的线型
           **/
           
           	private var item:Object;
			private var lengths:Number;
			private var sin:Number;
			private var cos:Number;
			private var xx0:Number;
			private var yy0:Number;
			private var xx:Number;
			private var yy:Number;
			private var dx:Number;
			private var dy:Number;

	   		override public function draw(graphics:Graphics,rc:Rectangle):void{
					
		 	preDraw();
		 							
			if(!rc)				
				super.draw(graphics,_bounds);	
			else
				super.draw(graphics,rc);
			
			for each (item in commandstack)
			{
			graphics.lineStyle(0.1,colour,1);	
			lengths=Math.abs(Math.sqrt(Math.pow(item.x0, 2) + Math.pow(item.y0, 2))) 	
        	sin=item.x0/lengths;//直线的sin值
        	cos=item.y0/lengths;  //直线的cos值 	
        	xx0=item.x+dash*sin/4;               //单点直线的x-coordinate起始位置
        	yy0=item.y+dash*cos/4;               //单点直线的y-coordinate结束位置
        	xx=item.x+dash*sin/2;                //双点直线的x-coordinate起始位置
        	yy=item.y+dash*cos/2;                //双点直线的y-coordinate结束位置
        	dx=(item.x0==0?0:(item.x0)/Math.abs(item.x0));//中间变量,即点的x-coordinate移动距离(取值为0,1,-1)
        	dy=(item.y0==0?0:(item.y0)/Math.abs(item.y0));//中间变量,即点的y-coordinate移动距离(取值为0,1,-1)
        	if(item.type=="m")
        	graphics.moveTo(item.x,item.y);
			else 
			switch(style)
			{
			//绘制虚线的算法	
			case 0:
			//绘制实线的算法
			case 4:
			  {
        		
        		graphics.lineTo(item.x,item.y);
        	    break;
			  }
			case 1:  //绘制铁路线(或者变色线的算法)
			  {
        		  	//graphics.moveTo(item.x,item.y);
        		    if(item.type=="mm")
        		    {
        	         graphics.lineStyle(1,0xff0000,1,true);
        	         graphics.lineTo(item.x,item.y);
        	        }
        		   else 
        		  {
        		    graphics.lineStyle(1,0x000000,1,true);	
        			graphics.lineTo(item.x,item.y);
        		  }
        	    break;
			  }
			  
			case 2:   //绘制双点线型的算法
			  { 
        		graphics.lineTo(item.x,item.y);      
        		 if((Math.abs(xx+dx)<=Math.max(Math.abs(item.x),Math.abs(item.x+item.x0-item.xd)))&&(Math.abs(yy+dy)<=Math.max(Math.abs(item.y),Math.abs(item.y+item.y0-item.yd))))
        		 {        		
        		graphics.moveTo(xx0,yy0);
        		graphics.lineTo(xx0+dx,yy0+dy);//绘制单点,即利用lineto来绘制直线
        		graphics.moveTo(xx,yy);
        		graphics.lineTo(xx+dx,yy+dy);  //绘制双点,即利用lineto来绘制直线
                 }
			  	break;
			  }
			case 3:  //绘制单点线型的算法
			   {
        		graphics.lineTo(item.x,item.y);              //设置线条样式,绘制直线
        		//判断点的绘制是否执行,当点直线x-coordinate和y-coordinate的起始位置在直线之内则绘制单点
        		if((Math.abs(xx)<=Math.max(Math.abs(item.x),Math.abs(item.x+item.x0-item.xd)))&&(Math.abs(yy)<=Math.max(Math.abs(item.y),Math.abs(item.y+item.y0-item.yd))))
        		{        		
        		graphics.moveTo(xx,yy);
        		graphics.lineTo(xx+dx,yy+dy); //绘制单点,即利用lineto来绘制直线
                }
			   	 break;
			   }
			}
			}
			super.endDraw(graphics);
			
			
		}
		  /**
		  * 当style属性发生change则调用重绘函数,能够及时的响应线型改变进行重绘(由于会产生bug导致暂时屏蔽重绘功能,因为会报ss引用为Null)
		  * */
		    public  function redraw(e:PropertyChangeEvent):void
    {
    	    
//    	    draw(ss.graphics,null);
    }
    public function commandstackclear():void
    {
      
    }
	
}

}

分享到:
评论

相关推荐

    Degrafa画矢量曲线

    这篇博文"Degrafa画矢量曲线"可能详细介绍了如何使用 Degrafa 库来绘制和操作曲线。 在计算机图形学中,曲线是一种基本元素,常用于创建艺术作品、UI设计、游戏图形等。矢量曲线的优势在于它们是基于数学公式定义的...

    Degrafa3.1源码

    综上所述,利用 Degrafa 3.1 源码配合 FLEX,开发者可以构建出具有高度自定义和交互性的行政区域地图应用。这涉及到图形渲染、事件处理、数据解析等多个方面的技术,是一个挑战同时也是提升技能的好机会。在实际项目...

    SvgToDegrafa.rar_SvgToDegrafa_degrafa_flex

    通过使用 Degrafa,开发者可以在Flex应用中实现复杂的图形绘制、交互和动画效果。 “SvgToDegrafa.as”是这个项目的核心文件,很可能是用来解析SVG文件并将其转化为 Degrafa 可以处理的格式。在Flex中,通常需要将...

    Degrafa帮助文档

    Degrafa是一款强大的图形绘制工具,专为Adobe Flex开发者设计,用于在Flex应用程序中创建复杂的矢量图形。这款工具的核心是其灵活的图形系统,它允许开发者通过代码控制图形的每一个细节,从而实现动态和交互式的...

    flex svg代码生成图片

    使用 Degrafa 框架,可以在 Flex 应用程序中动态显示和操作 SVG 文档。通过解析 SVG 文件,然后通过 Flex 生成图片。动态加载 SVG 图片可以实现大量的 SVG 图形资源直接在 Flex 应用程序中使用。 三、解析 SVG 文件...

    关于DEGRAFA的简介

    DEGRAFA,全称为“基于SVG的矢量图形绘制框架”,是一个开源的、基于SVG(Scalable Vector Graphics)标准的图形绘制工具包,主要应用于Java平台。它为开发者提供了丰富的API,使得在Java应用程序中创建、编辑和展示...

    关于Degrafa's Fills简介

    通过阅读和理解 `sign05.mxml` 文件,开发者不仅可以学习 Degrafa 的填充功能,还能掌握如何将自定义图形库整合到Flex项目中的技巧。此外,博文作者在提供的链接中可能还详细解释了代码的工作原理,包括图形的创建、...

    flex图形报表控件源代码

    主要是branch中的birdeye。 这里是源代码,但需要借助另外的开源框架Degrafa。我用的是Degrafaflex4.swf。 这里我直接将degrafaflex4.swf和birdeye本身自己写的vis打成一个swf文件。...我的IDE是eclipse3.5+flex4插件。

    degrafa 的帮助文档

    flex开发的画图框架Degrafa 近来需在flex画些简单的图形,根据朋友推荐使用了Degrafa,但是官方没有提供离线的文档下载,于是自己制作了一下。 文档的所有版权均属http://www.degrafa.com 详细情况请查看degrafa的...

    degrafa绘图工具 svg操作

    通过使用Flex技术,开发者可以利用DeGrafa轻松构建交互式的图形用户界面,实现动态图形的绘制和编辑。Flex是一种基于ActionScript的开放源代码框架,用于构建富互联网应用程序(RIA),它与SVG的结合使得图形的创建...

    Degrafa.CHM

    flex开发的画图框架Degrafa 近来需在flex画些简单的图形,根据朋友推荐使用了Degrafa,但是官方没有提供离线的文档下载,于是自己制作了一下。 文档的所有版权均属http://www.degrafa.com 详细情况请查看degrafa的...

    flex3做的流程图

    在Flex3中,利用 Degrafa 库创建流程图,可以实现自定义的图形样式和交互性,这对于软件设计师和开发者来说是一个非常实用的工具。 Degrafa 提供了一套API,允许开发者使用ActionScript来绘制和操作矢量图形。它的...

    深入SVG路径~~~在DEGRAFA中使用PATH

    在DEGRAFA中,你可以利用SVG路径进行各种图形操作,如绘制自定义形状、创建动画、组合路径等。DEGRAFA提供了一些高级功能,比如路径的平移、旋转、缩放,以及剪切、合并和布尔运算等。这些特性使得DEGRAFA成为...

    Degrafa(Beta3)

    5. **自定义图形算法**: Degrafa允许开发者自定义图形算法,通过组合和扩展现有图形组件,可以创造出独特的视觉效果和交互逻辑。 6. **源码开放**:作为开源项目, Degrafa的源码可供学习和研究,开发者可以深入...

    Flex开源项目

    3. **SpringGraph Flex Component**: 这是一个用于绘制拓扑关系图的组件,非常适合展示复杂的网络或数据结构。 4. **Flex Visual Graph Library**: 类似于SpringGraph,它也专注于拓扑图形展示,动态效果出色。 5....

    degrafa源代码

    Degrafa扩展就是在FLEX中增加了对矢量数据的动态处理,包括动态添加,删除和修改,并支持SVG的路径格式数据, 因此只需要对现有的SVG数据进行一些必要的转换(以后会有工具支持,但现在只能手工完成),就可以将SVG...

    Degrafa学习一,(含SDK4.0兼容版本及源码,略微有所修改)

    这为开发者提供了深入理解 Degrafa 内部工作原理的机会,并且允许他们根据需要自定义或扩展框架的功能。对于学习和研究 Degrafa 的人来说,源码是极其宝贵的,因为它可以提供实践编程技巧、调试和性能优化的实践平台...

    一个隐藏式的登录窗口

    在登录窗口中,degrafa可能被用来绘制独特的形状、线条和边框,以创建独特的设计风格,提升界面的视觉吸引力。 “下拉式登录”指的是登录窗口可能从上方、下方或其他位置以滑动或下拉的方式出现。这种方式节省了...

Global site tag (gtag.js) - Google Analytics