用到的有三个类,BrokenLine.as,BrokenLineEdge.as,BrokenLineRect.as,效果如图:

当拖到直线后可以折回去。
源码在附件上。有bug的话希望提出来哈。谢谢。
svn地址http://forever-framework.googlecode.com/svn/design/,
箭头效果已经做好了。在svn上。
箭头的制作参照了这位师兄的内容http://zean.iteye.com/blog/1070471
核心类:
package org.forever.view
{
import flash.events.MouseEvent;
import flash.geom.Point;
import mx.collections.ArrayList;
import mx.core.UIComponent;
import mx.logging.ILogger;
import mx.logging.Log;
import mx.utils.UIDUtil;
import spark.components.BorderContainer;
import spark.components.SkinnableContainer;
/**
* 折线的实现(初始化状态是3点两边)
*/
public class BrokenLine extends UIComponent
{
private var _app_container:SkinnableContainer;
private static var _log:ILogger = Log.getLogger("org.forever.view.BrokenLine");
private var _fromPoint:Point;
private var _toPoint:Point;
private var _firstRect:BrokenLineRect;
private var _secondRect:BrokenLineRect;
private var _thirdRect:BrokenLineRect;
private var _firstEdge:BrokenLineEdge;
private var _rect_w:Number = 6;
private var _startMove:Boolean = false;
private var _moving:Boolean = false;
private var _currentClickRect:BrokenLineRect;
private var _rectList:ArrayList;
private var _edgeList:ArrayList;
public function BrokenLine()
{
}
/**画折线的方法*/
public function draw():void{
initContainer();
_firstRect = new BrokenLineRect();
_secondRect = new BrokenLineRect();
_thirdRect = new BrokenLineRect();
_firstEdge = new BrokenLineEdge();
initFirstRect();
initSecondRect();
initThirdRect();
initFirstEdge();
//建立矩形关联边
_firstRect.secondEdge = _firstEdge;
_secondRect.firstEdge = _firstEdge;
//建立边关联矩形
_firstEdge.firstRect = _firstRect;
_firstEdge.secondRect = _secondRect;
//建立矩形关联的矩形
_firstRect.nextRect = _thirdRect;
_secondRect.prevRect = _thirdRect;
_thirdRect.prevRect = _firstRect;
_thirdRect.nextRect = _secondRect;
//添加顺序导致组件的重叠z轴顺序
addChild(_firstEdge);
addChild(_firstRect);
addChild(_thirdRect);
addChild(_secondRect);
_rectList = new ArrayList(new Array(_firstRect,_thirdRect,_secondRect));
_edgeList = new ArrayList(new Array(_firstEdge));
}
/**初始化容器事件*/
public function initContainer():void{
_app_container.addEventListener(MouseEvent.MOUSE_MOVE,appContainerMouseMoveHandler);
_app_container.addEventListener(MouseEvent.MOUSE_UP,appContainerMouseUpHandler);
}
/**获取指定两个矩形的距离,AB=√[(x1-x2)²+(y1-y2)²]*/
public function getDistance(firstRect:BrokenLineRect,secondRect:BrokenLineRect):Number{
return Math.sqrt(Math.pow(firstRect.x - secondRect.x,2) + Math.pow(firstRect.y - secondRect.y,2));
}
/**处理拖动180度直线后,去掉左右控制点的方法*/
public function process180():Boolean{
if(_currentClickRect.isSplit){//是拆分过的控制点
var a:Number = getDistance(_currentClickRect,_currentClickRect.prevRect);
var b:Number = getDistance(_currentClickRect,_currentClickRect.nextRect);
var c:Number = getDistance(_currentClickRect.prevRect,_currentClickRect.nextRect);
var cosC:Number=(a*a+b*b-c*c)/(2*a*b);
//求出控制点拖动时夹角的及时角度
var acos:Number =(int)(Math.acos(cosC) * 180 / Math.PI);
_log.debug("*************角度:"+acos+"**************");
if(_currentClickRect.direction==0 && acos<=165){//第一次将控制点拖动时,角度会逐渐变小,小于165度后确定为正方向
_currentClickRect.direction = 1;
_log.debug("*************正方向拖动中**************");
}else if(_currentClickRect.direction==1 && acos>=165){//如果满足正方向拖动后,在往反方向拖动,角度会逐渐变大,大于165度后确定为反方向
_currentClickRect.direction = -1;
_log.debug("*************反方向拖动中**************");
}
//如果反方向行动,并且角度在指定范围内,去掉前后控制点
if(_currentClickRect.direction==-1 && acos>=176 && acos<=180){
_log.debug("*************进入去掉前后控制点范围**************");
//获取当前控制点矩形的前驱前驱矩形和后继后继矩形
var prevPrevRect:BrokenLineRect = _currentClickRect.prevRect.prevRect;
var nextNextRect:BrokenLineRect = _currentClickRect.nextRect.nextRect;
//将当前控制点矩形的前驱矩形和后继矩形从容器界面中移除
this.removeChild(_currentClickRect.prevRect);
this.removeChild(_currentClickRect.nextRect);
//更新各个控制点的关联关系
_currentClickRect.prevRect = prevPrevRect;
_currentClickRect.nextRect = nextNextRect;
prevPrevRect.nextRect = _currentClickRect;
nextNextRect.prevRect = _currentClickRect;
//if(prevPrevRect!=_firstRect){//头矩形没有第一条边
//prevPrevRect.firstEdge = _currentClickRect.secondEdge;
//}
prevPrevRect.secondEdge = _currentClickRect.secondEdge;
_currentClickRect.secondEdge.firstRect = prevPrevRect;
_currentClickRect.secondEdge.drawLine();
updateRectTop(_currentClickRect.secondEdge);
this.removeChild(_currentClickRect.firstEdge);
_currentClickRect.firstEdge = null;
_currentClickRect.secondEdge = null;
_currentClickRect.isSplit = false;
_currentClickRect.x = (_currentClickRect.prevRect.x + _currentClickRect.nextRect.x)/2;
_currentClickRect.y = (_currentClickRect.prevRect.y + _currentClickRect.nextRect.y)/2;
_moving = false;
_startMove = false;
_currentClickRect.direction = 0;
return true;
}
}
return false;
}
public function appContainerMouseMoveHandler(event:MouseEvent):void{
if(_moving){
_currentClickRect.x = mouseX;
_currentClickRect.y = mouseY;
if(process180())return;
_currentClickRect.refresh();
}
}
public function appContainerMouseUpHandler(event:MouseEvent):void{
if(_moving && null != _currentClickRect){
_startMove = false;
_moving = false;
//_log.debug(_currentClickRect.desc + "结束移动......");
}
}
public function addRectEvent(rect:BrokenLineRect):void{
rect.addEventListener(MouseEvent.MOUSE_DOWN,rectMouseDownHandler);
rect.addEventListener(MouseEvent.MOUSE_MOVE,rectMouseMoveHandler);
rect.addEventListener(MouseEvent.MOUSE_UP,rectMouseUpHandler);
}
/**矩形鼠标释放事件,一旦释放,停止拖动*/
public function rectMouseUpHandler(event:MouseEvent):void{
_startMove = false;
_moving = false;
//_log.debug(_currentClickRect.desc + "结束移动......");
}
public function rectMouseDownHandler(event:MouseEvent):void{
_startMove = true;//点击组件做移动准备
_moving = false;//并未真正移动
_currentClickRect = event.currentTarget as BrokenLineRect;
_currentClickRect.print();
//_log.debug(_currentClickRect.desc + "被点击,准备开始移动......坐标:x=" + _currentClickRect.x + "y=" + _currentClickRect.y );
}
public function rectMouseMoveHandler(event:MouseEvent):void{
if(_startMove && !_moving){//如果准备好移动
//既不是头矩形,也不是尾矩形,也没有拆分过
if(_currentClickRect != _firstRect && _currentClickRect!=_secondRect && !_currentClickRect.isSplit){
var _newRectOne:BrokenLineRect = createRect();//新增第一个控制点矩形
//该矩形是当前控制点矩形和前驱矩形的中间矩形
_newRectOne.x = (_currentClickRect.x + _currentClickRect.prevRect.x)/2;
_newRectOne.y = (_currentClickRect.y + _currentClickRect.prevRect.y)/2;
_newRectOne.desc = UIDUtil.createUID();
//新增第二个控制点矩形,该矩形是当前控制点矩形和后继矩形的中间矩形
var _newRectTwo:BrokenLineRect = createRect();
_newRectTwo.x = (_currentClickRect.x + _currentClickRect.nextRect.x)/2;
_newRectTwo.y = (_currentClickRect.y + _currentClickRect.nextRect.y)/2;
_newRectTwo.desc = UIDUtil.createUID();
//获取当前控制点前驱控制点的第二条关联边
var _secondEdge:BrokenLineEdge = _currentClickRect.prevRect.secondEdge;
//更新关联边的第一个控制点为当前控制点
_secondEdge.firstRect = _currentClickRect;
//更新关联边的第二个控制点为当前控制点的后继控制点
_secondEdge.secondRect = _currentClickRect.nextRect;
//更新当前矩形的第二条关联边
_currentClickRect.secondEdge = _secondEdge;
//重绘边
_secondEdge.drawLine();
updateRectTop(_secondEdge);//将该边的两端控制点置顶
//新增一条边,建立该节点与前驱节点的边关系
var _newEdge:BrokenLineEdge = new BrokenLineEdge();
_newEdge.firstRect = _currentClickRect.prevRect;
_newEdge.secondRect = _currentClickRect;
_newEdge.desc = UIDUtil.createUID();
_newEdge.drawLine();
addChild(_newEdge);
addChild(_newRectOne);
addChild(_newRectTwo);
updateRectTop(_newEdge);
//更新当前控制点矩形的前驱矩形的关联边为新边
_currentClickRect.prevRect.secondEdge = _newEdge;
//更新当前控制点矩形的第一条关联边
_currentClickRect.firstEdge = _newEdge;
//更新控制点矩形之间的引用关系
_currentClickRect.prevRect.nextRect = _newRectOne;
_currentClickRect.nextRect.prevRect = _newRectTwo;
_newRectOne.prevRect = _currentClickRect.prevRect;
_newRectOne.nextRect = _currentClickRect;
_newRectTwo.prevRect = _currentClickRect;
_newRectTwo.nextRect = _currentClickRect.nextRect;
_currentClickRect.prevRect = _newRectOne;
_currentClickRect.nextRect = _newRectTwo;
_currentClickRect.isSplit = true;//标记为已拆分
//添加到集合中
_edgeList.addItem(_newEdge);
}
_moving = true;
_log.debug(_currentClickRect.desc + "移动中......坐标:x=" + _currentClickRect.x + "y=" + _currentClickRect.y);
}
}
/**创建一个新的矩形点*/
public function createRect():BrokenLineRect{
var _newRect:BrokenLineRect = new BrokenLineRect();
_newRect.width = _rect_w;
_newRect.height = _rect_w;
_newRect.setStyle("borderColor","#70B2EE");
addRectEvent(_newRect);
return _newRect;
}
/**更新指定边的两端矩形置顶*/
public function updateRectTop(_edge:BrokenLineEdge):void{
this.setChildIndex(_edge.firstRect,this.numChildren-1);
this.setChildIndex(_edge.secondRect,this.numChildren-1);
}
/**初始化第一个端点到中点的边*/
public function initFirstEdge():void{
_firstEdge.firstRect = _firstRect;
_firstEdge.secondRect = _secondRect;
_firstEdge.desc = UIDUtil.createUID();
_firstEdge.drawLine();
}
/**初始化中点矩形*/
public function initThirdRect():void{
_thirdRect.width = _rect_w;
_thirdRect.height = _rect_w;
_thirdRect.setStyle("borderColor","#70B2EE");
_thirdRect.x = (_firstRect.x + _secondRect.x)/2;
_thirdRect.y = (_firstRect.y + _secondRect.y)/2;
_thirdRect.desc = "_thirdRect";
addRectEvent(_thirdRect);
}
/**初始化第二个端点的矩形*/
public function initSecondRect():void{
_secondRect.width = _rect_w;
_secondRect.height = _rect_w;
_secondRect.x = _toPoint.x;
_secondRect.y = _toPoint.y - _secondRect.height/2;
_secondRect.setStyle("borderColor","#70B2EE");
_secondRect.desc = "_secondRect";
addRectEvent(_secondRect);
}
/**初始化第一个端点的矩形*/
public function initFirstRect():void{
_firstRect.width = _rect_w;
_firstRect.height = _rect_w;
_firstRect.x = _fromPoint.x - _firstRect.width;
_firstRect.y = _fromPoint.y - _firstRect.height/2;
_firstRect.setStyle("borderColor","#70B2EE");
_firstRect.desc = "_firstRect";
addRectEvent(_firstRect);
}
/******************* get and set ******************/
/**线终点*/
public function get toPoint():Point
{
return _toPoint;
}
/**
* @private
*/
public function set toPoint(value:Point):void
{
_toPoint = value;
}
/**线起点*/
public function get fromPoint():Point
{
return _fromPoint;
}
/**
* @private
*/
public function set fromPoint(value:Point):void
{
_fromPoint = value;
}
/**显示所有可变组件的容器*/
public function get app_container():SkinnableContainer
{
return _app_container;
}
/**
* @private
*/
public function set app_container(value:SkinnableContainer):void
{
_app_container = value;
}
public function get moving():Boolean
{
return _moving;
}
public function set moving(value:Boolean):void
{
_moving = value;
}
}
}
辅助类:
package org.forever.view
{
import flash.events.MouseEvent;
import flash.geom.Point;
import mx.core.UIComponent;
import mx.logging.ILogger;
import mx.logging.Log;
/**折线用的线条边类*/
public class BrokenLineEdge extends UIComponent
{
private static var _log:ILogger = Log.getLogger("org.forever.view.BrokenLineEdge");
private var _fromPoint:Point;
private var _toPoint:Point;
private var _lineColor:uint=0x000000;
private var _thickness:Number = 1;
private var _alpha:Number = 1;
private var _firstRect:BrokenLineRect;
private var _secondRect:BrokenLineRect;
private var _desc:String;
public function BrokenLineEdge()
{
super();
_fromPoint = new Point();
_toPoint = new Point();
addEventListener(MouseEvent.MOUSE_DOWN,mouseDownHandler);
}
public function mouseDownHandler(e:MouseEvent):void{
print();
}
public function print():void{
_log.debug("*******************("+_desc+")信息************************************");
_log.debug("第一个端点矩形:"+_firstRect.desc);
_log.debug("第二个端点矩形:"+_secondRect.desc);
_log.debug("*********************************************************************");
}
/**绘制线条*/
public function drawLine():void{
_log.debug("重绘边" + _desc + ";" + _firstRect.desc + ":" + _secondRect.desc);
fromPoint.x = _firstRect.x + _firstRect.width/2;
fromPoint.y = _firstRect.y + _firstRect.height/2;
toPoint.x = _secondRect.x+_secondRect.width/2;
toPoint.y = _secondRect.y + _secondRect.height/2;
this.graphics.clear();
this.graphics.lineStyle(_thickness,_lineColor,_alpha);
this.graphics.moveTo(_fromPoint.x,_fromPoint.y);
this.graphics.lineTo(_toPoint.x,_toPoint.y);
}
/**线起点*/
public function get fromPoint():Point
{
return _fromPoint;
}
/**
* @private
*/
public function set fromPoint(value:Point):void
{
_fromPoint = value;
}
/**线终点*/
public function get toPoint():Point
{
return _toPoint;
}
/**
* @private
*/
public function set toPoint(value:Point):void
{
_toPoint = value;
}
/**线条颜色*/
public function get lineColor():uint
{
return _lineColor;
}
/**
* @private
*/
public function set lineColor(value:uint):void
{
_lineColor = value;
}
/**关联的第一个端点*/
public function get firstRect():BrokenLineRect
{
return _firstRect;
}
/**
* @private
*/
public function set firstRect(value:BrokenLineRect):void
{
_firstRect = value;
}
/**关联的第二个端点*/
public function get secondRect():BrokenLineRect
{
return _secondRect;
}
/**
* @private
*/
public function set secondRect(value:BrokenLineRect):void
{
_secondRect = value;
}
public function get desc():String
{
return _desc;
}
public function set desc(value:String):void
{
_desc = value;
}
}
}
控制点类:
package org.forever.view
{
import flash.events.MouseEvent;
import mx.logging.ILogger;
import mx.logging.Log;
import spark.components.BorderContainer;
/**折线用到的矩形点类*/
public class BrokenLineRect extends BorderContainer
{
private static var _log:ILogger = Log.getLogger("org.forever.view.BrokenLineRect");
private var _firstEdge:BrokenLineEdge;
private var _secondEdge:BrokenLineEdge;
private var _prevRect:BrokenLineRect;
private var _nextRect:BrokenLineRect;
private var _isSplit:Boolean = false;
private var _rect_w:Number = 6;
private var _count:Number = 0;
private var _direction:Number = 0;
private var _desc:String;
public function BrokenLineRect()
{
}
public function print():void{
_log.debug("*******************("+_desc+")信息************************************");
_log.debug("前驱矩形:" + (_prevRect!=null?_prevRect.desc:"没有前驱矩形"));
_log.debug("后继矩形:" + (_nextRect!=null? _nextRect.desc:"没有后继矩形"));
_log.debug("第一条关联边:" + (_firstEdge!=null? _firstEdge.desc:"没有第一条关联边"));
_log.debug("第二条关联边:" + (_secondEdge!=null? _secondEdge.desc:"没有第二条关联边"));
_log.debug("*********************************************************************");
}
public function refresh():void{
updateFirstEdgePosition();
updateSecondEdgePosition();
updateNextRectPosition();
updatePrevRectPosition();
}
/**更新第二条边的位置*/
public function updateSecondEdgePosition():void{
if(_secondEdge != null){
_secondEdge.drawLine();
}
}
/**更新后继矩形的位置*/
public function updateNextRectPosition():void{
if(_nextRect != null && _nextRect.nextRect != null){
_nextRect.x = (x + _nextRect.nextRect.x)/2;
_nextRect.y = (y + _nextRect.nextRect.y)/2;
}
}
/**更新前驱矩形的位置*/
public function updatePrevRectPosition():void{
if(_prevRect != null && _prevRect.prevRect != null){
_prevRect.x = (x + _prevRect.prevRect.x)/2;
_prevRect.y = (y + _prevRect.prevRect.y)/2;
}
}
/**更新第一条边的位置*/
public function updateFirstEdgePosition():void{
if(_firstEdge != null){
_firstEdge.drawLine();
}
}
public function updateFirstEdge():void{
if(_firstEdge != null ){
}
}
/**矩形关联的第一条边(左边)*/
public function get firstEdge():BrokenLineEdge
{
return _firstEdge;
}
/**
* @private
*/
public function set firstEdge(value:BrokenLineEdge):void
{
_firstEdge = value;
}
/**矩形关联的第二条边(右边)*/
public function get secondEdge():BrokenLineEdge
{
return _secondEdge;
}
/**
* @private
*/
public function set secondEdge(value:BrokenLineEdge):void
{
_secondEdge = value;
}
/**前驱矩形节点*/
public function get prevRect():BrokenLineRect
{
return _prevRect;
}
/**
* @private
*/
public function set prevRect(value:BrokenLineRect):void
{
_prevRect = value;
}
/**后继矩形节点*/
public function get nextRect():BrokenLineRect
{
return _nextRect;
}
/**
* @private
*/
public function set nextRect(value:BrokenLineRect):void
{
_nextRect = value;
}
/**是否拆分过,即创建了该矩形与前驱(后继)矩形的中点矩形*/
public function get isSplit():Boolean
{
return _isSplit;
}
/**
* @private
*/
public function set isSplit(value:Boolean):void
{
_isSplit = value;
}
public function get desc():String
{
return _desc;
}
public function set desc(value:String):void
{
_desc = value;
}
/**拖动方向,0未初始化,1正方向,-1反方向*/
public function get direction():Number
{
return _direction;
}
/**
* @private
*/
public function set direction(value:Number):void
{
_direction = value;
}
}
}
5590

被折叠的 条评论
为什么被折叠?



