实现的效果:
1.选择直线的起始或结束节点时,可以移动直线
2.当按住Ctrl后,再点击直线,可以创建出一个折线,如下图:
基本思路:
当直线被MouseDown后,判断选择的位置,如果是起始或结束节点的范围,则移动该节点,重新绘制直线。
如果有Ctrl按下,则在MouseMove事件中根据鼠标的位置,绘制出一条拆线,当MouseUp后,添加一个新的UIComponent把那条拆线重新绘制一次。
UXLine 简单地封装了画直线的类
package cn.ui
{
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);
}
}
}
不废话,直接上MXML
<?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:Style source="BrokenLineDemo.css"/>
<fx:Script>
<![CDATA[
import cn.ui.UXCanvas;
import cn.ui.UXLine;
import flash.display.Sprite;
import flash.geom.Point;
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(event.localX, event.localY);
}
}
// 线条分割选择点后 移动完成
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>
- 大小: 14 KB
分享到:
相关推荐
本示例“Flex画线(直线,折线)完美实现”专注于提供一种高效、灵活的方法来绘制动态直线和折线,并允许用户进行实时编辑。通过这个项目,开发者可以学习如何在Flex应用中实现这一功能,提升用户体验。 首先,Flex是...
在Flex编程中,动态画直线是一项基础且实用的技术,尤其在构建交互式用户界面或图形应用时。本文将深入探讨如何使用Flex实现这个功能,并基于提供的"Flex 动态画直线"主题,解释核心概念和步骤。 首先,让我们了解...
"flex画线可以删除"这个标题和描述可能是指在使用Flex布局时,如何通过CSS样式来实现或删除元素之间的分隔线。这里我们将深入探讨Flex布局以及如何控制其中的线条。 Flex布局(Flexible Box Layout)是CSS3引入的一...
Flex 画线 两点画线 画布画线 Flex3.0 画线段
在IT行业中,尤其是在Web开发领域,"flex 图片画线,拖动"是一个常见的交互功能需求,用于增强用户体验。这个功能通常涉及到HTML5、CSS3和JavaScript等技术,特别是Flex布局和SVG图形技术。让我们详细探讨一下这个...
在“flex画线”的场景中,我们通常是指利用Flexbox( Flexible Box 或 Flex 布局)来创建各种线性结构,如分割线、网格线或者自定义的布局分隔。 在CSS中,`display: flex;`属性是开启Flex布局的关键。一旦一个容器...
这个类提供了丰富的绘图方法,如`beginFill()`、`lineTo()`、`moveTo()`等,可以用来画线、填充形状、绘制曲线。 3. **曲线绘制**: - 曲线绘制通常涉及到贝塞尔曲线,包括线性贝塞尔曲线和三次贝塞尔曲线。线性...
在本案例中,"Flex实现拓扑,可以拖动 画线等",指的是利用Flex技术开发了一个具有拓扑图展示功能的应用,该应用允许用户进行节点拖动和连线绘制,提高了用户体验和互动性。 拓扑图通常用于表示网络、系统或流程中...
这个示例代码展示了如何在Flex应用中实现用户通过鼠标绘制直线、清除直线以及多点折线的功能。以下是详细的知识点解析: 1. **Flex架构**:这个应用基于Adobe Flex框架,使用Spark组件库,如`s:Application`、`s:...
根据提供的文件信息,我们可以分析出该文件主要涉及的是使用Adobe Flex技术实现的一种画线动画效果。下面将对该示例中的关键技术点进行详细解读。 ### 一、Adobe Flex简介 Adobe Flex是一个免费开源的软件框架,...
本文将深入探讨“flex节点画线”与“拖动节点线动”的技术实现,帮助开发者掌握这两项关键技能。 首先,我们要理解什么是Flex节点。在Flex布局中,节点通常指的是容器内的子元素,这些子元素可以灵活地调整自己的...
在Flex编程中,"flex成功画一个点"这个主题涉及到的是如何在用户界面元素上绘制一个像素级别的点。Flex是一种基于ActionScript的开源框架,主要用于创建富互联网应用程序(RIA)。在Flex中,我们可以利用图形库或者...
在Flex编程中,"flex 画线,并连接到物体上" 这一主题涉及到图形绘制、事件处理和对象定位等多个核心知识点。Flex是一款基于ActionScript 3.0的开源框架,主要用于构建富互联网应用程序(RIA)。下面将详细介绍如何...
在Flex4开发中,创建坐标轴曲线图是一种常见的需求,特别是在数据可视化和图表展示的应用中。Flex是一个基于ActionScript和MXML的开放源代码框架,主要用于构建富互联网应用程序(RIA)。它提供了强大的图形和组件库...
4. 笔触形状:可能包含直线、曲线、填充等不同笔触模式,让用户可以自由选择线条的形态。 5. 透明度调整:用户可以改变线条或填充的透明度,创建半透明效果,增加作品层次感。 6. 工具窗口:预留了一个空白的工具栏...
动画颜色flex源码动画颜色flex源码动画颜色flex源码动画颜色flex源码动画颜色flex源码动画颜色flex源码动画颜色flex源码动画颜色flex源码动画颜色flex源码动画颜色flex源码动画颜色flex源码动画颜色flex源码动画颜色...
在这个特定的项目中,“FLEX ActionScript超强仿visio画线功能”是指使用ActionScript实现的类似Microsoft Visio的图形绘制功能。 Visio是一款流行的图表和流程图绘制软件,允许用户轻松创建各种复杂的图形。在FLEX...
4. 动态画线和更新线条: 如果需要动态创建或更新线条,可以修改`data`属性。例如,根据用户的输入或程序逻辑改变线条的长度和方向。 5. 处理多个线条: 如果有多个线条,可以创建一个数组来存储所有线条,然后遍...
flex真是个很强大的工具,当然demo也是我们学习的主要方法,flex拖拽画矩形,很流畅的,一点不卡