拖拉切割直线

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" creationComplete="onLoad();" >

<fx:Script>
<![CDATA[
import flash.display.Sprite;
import flash.geom.Point;

import mx.controls.Alert;
import mx.core.DragSource;
import mx.core.UIComponent;
import mx.events.DragEvent;
import mx.events.MenuEvent;
import mx.managers.DragManager;

// 最原始的线条对象
private var uxLine:UXLine = new UXLine;
// 拖动初始点
private var dragPoint:Point = new Point;

// 当前线条对象
private var currentLine:UXLine = null;

private function onLoad():void{
// 初始化表格线
initGridLine(mxCanvas);

// 初始化uxLine
uxLine.xFrom = 50;
uxLine.yFrom = 50;
uxLine.xTo = 250;
uxLine.yTo = 250;
uxLine.draw();

mxCanvas.addElement(uxLine);

mxCanvas.addEventListener(UXLine.EVENT_LINE_BROKEN, onLineBroken);
mxCanvas.addEventListener(UXLine.EVENT_LINE_NODE_MOVE, onLineNodeMove);
}


// 线条分割事件
private function onLineBroken(event:MouseEvent):void{
if(event.target is UXLine){
currentLine = UXLine(event.target);
systemManager.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove4LB, true);
systemManager.addEventListener(MouseEvent.MOUSE_UP, onMouseUp4LB, true);
}
}
// 线条分割选择点后 开始移动
private function onMouseMove4LB(event:MouseEvent):void{
event.stopImmediatePropagation();
if(currentLine != null){
currentLine.draw2Line(currentLine.x, event.localY);
/* Alert.show(event.localX.toString(),"title"); */
}
}
// 线条分割选择点后 移动完成
private function onMouseUp4LB(event:MouseEvent):void{
event.stopImmediatePropagation();
systemManager.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove4LB, true);
systemManager.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp4LB, true );

var pointX:Number = event.localX;
var pointY:Number = event.localY;
// 把线条拆分开,即新增加一条线来实现
if(currentLine != null){
var newLine:UXLine = new UXLine;
newLine.xFrom = currentLine.xFrom;
newLine.yFrom = currentLine.yFrom;
newLine.xTo = pointX;
newLine.yTo = pointY;
newLine.draw();
mxCanvas.addElement(newLine);

currentLine.graphics.clear();
currentLine.xFrom = pointX;
currentLine.yFrom = pointY;
currentLine.draw();
//mxCanvas.removeElement(currentLine);
}
currentLine = null;
}

// 选择线起点或终点的移动事件
private function onLineNodeMove(event:MouseEvent):void{
if(event.target is UXLine){
currentLine = UXLine(event.target);
systemManager.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove4Line, true);
systemManager.addEventListener(MouseEvent.MOUSE_UP, onMouseUp4Line, true);
}
}

// 选择线起点或终点的移动事件
private function onMouseMove4Line(event:MouseEvent):void{
event.stopImmediatePropagation();

if(currentLine != null){
if(currentLine.selectedNode == UXLine.SELECTED_FROM_NODE){
currentLine.xFrom = event.localX;
currentLine.yFrom = event.localY;
}else if(currentLine.selectedNode == UXLine.SELECTED_TO_NODE){
currentLine.xTo = event.localX;
currentLine.yTo = event.localY;
}
currentLine.draw();
}
}

// 释放移动动作
private function onMouseUp4Line(event:MouseEvent):void{
event.stopImmediatePropagation();
systemManager.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseMove4Line, true);
systemManager.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp4Line, true );
currentLine = null;
}


/**
* 初始化表格线条
**/
private function initGridLine(uiComponent:UIComponent):void{
const LINE_LENGTH:int = 4;
const LINE_MARGIN:int = 2;
const LINE_OFFSET:int = 24;
var rowIndex:int;
var colIndex:int;
var rowCount:int = Math.floor(this.height / LINE_OFFSET);
var colCount:int = Math.floor(this.width / LINE_OFFSET);
var startX:Number;
var startY:Number;
var endX:Number;
var endY:Number;
var lineIndex:int;
var lineCount:int;
var lineLength:int = (LINE_LENGTH + LINE_MARGIN);
var thickness:Number = 0.5;
var lineColor:uint = 0x000000;

uiComponent.graphics.clear();
uiComponent.graphics.beginFill(0xFFFFFF);
uiComponent.graphics.drawRect(0, 0, this.width, this.height);
uiComponent.graphics.endFill();

uiComponent.graphics.lineStyle(thickness, lineColor, 0.5);

// 画出横线
lineCount = Math.floor(uiComponent.width / lineLength);
for(rowIndex = 1; rowIndex <= rowCount; rowIndex ++){
startY = endY = rowIndex * LINE_OFFSET;
if(rowIndex%2 == 0){
thickness = 1;
uiComponent.graphics.lineStyle(thickness, lineColor, 0.3);
}else{
thickness = 0.5;
uiComponent.graphics.lineStyle(thickness, lineColor, 0.1);
}
for(lineIndex = 0; lineIndex < lineCount; lineIndex ++){
startX = lineIndex * lineLength;
endX = startX + LINE_LENGTH;
uiComponent.graphics.moveTo(startX, startY);
uiComponent.graphics.lineTo(endX, endY);
}
}
// 画出竖线
lineCount = Math.floor(uiComponent.height / lineLength);
for(colIndex = 1; colIndex <= colCount; colIndex ++){
startX = endX = colIndex * LINE_OFFSET;
if(colIndex % 2 == 0){
thickness = 1;
uiComponent.graphics.lineStyle(thickness, lineColor, 0.3);
}else{
thickness = 0.5;
uiComponent.graphics.lineStyle(thickness, lineColor, 0.1);
}

for(lineIndex = 0; lineIndex < lineCount; lineIndex ++){
startY = lineIndex * lineLength;
endY = startY + LINE_LENGTH;
uiComponent.graphics.moveTo(startX, startY);
uiComponent.graphics.lineTo(endX, endY);
}
}
}

]]>
</fx:Script>
<mx:Canvas id="mxCanvas" height="100%" width="100%">
<s:Label text="提示:按住Ctrl再选择线条画折线,选择线的两端可移动线条" toolTip="按住Ctrl再选择线条画折线" x="278" y="11"/>
</mx:Canvas>

</s:Application>

package
{
import flash.events.MouseEvent;
import flash.geom.Point;
import flash.utils.Dictionary;

import mx.collections.ArrayCollection;
import mx.core.UIComponent;

import spark.filters.GlowFilter;

/**
* 线条类
* klinmy@163.com
**/
public class UXLine extends UIComponent
{
/** 常量0,未选择节点 */
public static const SELECTED_NONE_NODE:int = 0;
/** 常量1,选择了From节点 */
public static const SELECTED_FROM_NODE:int = 1;
/** 常量2,选择了To节点 */
public static const SELECTED_TO_NODE:int = 2;

/** 选择了From 或To节点 LineMove的事件 */
public static const EVENT_LINE_NODE_MOVE:String = "EVENT_LINE_NODE_MOVE";
/** 拆线形成拆线的事件 */
public static const EVENT_LINE_BROKEN:String = "EVENT_LINE_BROKEN";

private var _xFrom:Number = 0;
private var _xTo:Number = 0;
private var _yFrom:Number = 0;
private var _yTo:Number = 0;

private var _selectedNode:int = SELECTED_NONE_NODE;
private var _lineStyle:int = 2;
private var _lineColor:uint = 0x0099ff;

// 关联的线条
//private var _linkLines:ArrayCollection = new ArrayCollection;
private var _linkLines:Dictionary = new Dictionary;

/** 有效范围(半径) */
private const _EFFECT_RANGE:int = 3;

public function UXLine()
{
super();
this._selectedNode = SELECTED_NONE_NODE;
this.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
}


/** 0 未选择,1选择了起始节点,2选择了结束节点 */
public function get selectedNode():int
{
return _selectedNode;
}

public function get yTo():Number
{
return _yTo;
}

public function set yTo(value:Number):void
{
_yTo = value;
}

public function get yFrom():Number
{
return _yFrom;
}

public function set yFrom(value:Number):void
{
_yFrom = value;
}

public function get xTo():Number
{
return _xTo;
}

public function set xTo(value:Number):void
{
_xTo = value;
}

public function get xFrom():Number
{
return _xFrom;
}

public function set xFrom(value:Number):void
{
_xFrom = value;
}

public function set lineStyle(value:int):void{
_lineStyle = value;
}
public function get lineStyle():int{
return _lineStyle;
}
public function set lineColor(value:uint):void{
_lineColor = value
}
public function get lineColor():uint{
return _lineColor;
}

/**
* 绑定MouseDown事件
**/
private function onMouseDown(event:MouseEvent):void{
var eventType:String = EVENT_LINE_NODE_MOVE;// 线节点移动

this._selectedNode = SELECTED_NONE_NODE;
// 判断鼠标的位置,如果位于起点或终点的一个有效区域范围内时,触发可移动事件
var mousePoint:Point = new Point(event.localX, event.localY);
if(isInRange(_xFrom, _yFrom, event.localX, event.localY)){
this._selectedNode = SELECTED_FROM_NODE;
}else if(isInRange(_xTo, _yTo, event.localX, event.localY)){
this._selectedNode = SELECTED_TO_NODE;
}else if(event.ctrlKey){
// 生成新的线条的时候
eventType = EVENT_LINE_BROKEN;
}else{
// 其他事件,由外层容器去实现
return;
}

// 阻击冒泡,并派发自己的事件
event.stopPropagation();
var newEvent:MouseEvent = new MouseEvent(eventType, true);
newEvent.localX = event.stageX;
newEvent.localY = event.stageY;
dispatchEvent(newEvent);
}

/**
* 检测某一点是否在另一个点的范围内
* @param x
* @param y
* @param testX 测试点X坐标
* @param testY 测试点Y坐标
* @param effectRange 有效半径
**/
private function isInRange(x:int, y:int, testX:int, testY:int, effectRange:int=_EFFECT_RANGE):Boolean{
return ((x - effectRange <= testX) && (x + effectRange >= testX)
&& (y - effectRange <= testY) && (y + effectRange >= testY));
}

/**
* 绘制直线
**/
public function draw():void{
this.graphics.clear();
this.graphics.lineStyle(_lineStyle,_lineColor,1);
this.graphics.moveTo(_xFrom, _yFrom);
this.graphics.lineTo(_xTo, _yTo);
}

/**
* 绘制拆线
**/
public function draw2Line(pointX:int, pointY:int):void{
this.graphics.clear();
this.graphics.lineStyle(_lineStyle,_lineColor,1);
this.graphics.moveTo(_xFrom, _yFrom);
this.graphics.lineTo(pointX, pointY);
this.graphics.lineTo(_xTo, _yTo);
}
}
}

原文地址:https://www.cnblogs.com/wshsdlau/p/3621870.html