本人一直都是在.NET平台上混饭吃的,没想到第一篇博文居然献给了Flex,呵呵!在做B/S的开发中,HTML+JavaScript+Ajax在单纯的数据处理和表现上能完成的很好,但在其他的一些方面,例如客户端画图,就显的有些力不从心了。由于项目需要,我开始转向于其他的RIA技术(Flex or SilverLight)。网上关于Flex and SilverLight的争论纷纷扰扰,我的看法是两个技术都应该学,其实这两个技术的学习成本是比较低的,SilverLight可以用C#,Flex使用的ActionScript基本上就是强数据类型的JavaScript,有网页开发经验的人都可以很容易上手。要是在Windows平台上部署的的话,我会首选SilverLight,毕竟都是MS自家的技术,要是Linux就选Flex咯,虽说有个跨平台版的SilverLight(Mono的MoonLight),但个人并不是很看好。
呵呵,闲扯了一段,现在切入主题。本文主要介绍使用ActionScript实现跟随鼠标移动画直线的一种方法,所谓跟随鼠标移动画直线意思是当点击鼠标的时候,确定画直线的起点,当鼠标移动的时候,从起点到鼠标当前的坐标画直线作为预览,当再次点击鼠标的时候从起点到鼠标点击的地方画出一条直线,类似于Windows画图板的画直线功能。我在这里采用GDI画图时常用到的双缓存思想,其实原理也很简单,设置两个画布_canvasTop和_canvasBottom,_canvasTop叠加在_canvasBottom上,将_canvasTop的背景设为透明,点击鼠标确定画线的开始点,当鼠标移动时,先擦除_canvasTop上原来的直线,然后以鼠标当前的坐标为画线结束点重新画线,其实就是总是保持_canvasTop上个有一根直线,当再次点击鼠标的时候,确定了画线的结束点,在_canvasBottom上画下直线,由于_canvasTop是透明的,_canvasBottom上的才是最终想要的画图结果,在_canvasTop上的擦除操作不会影响到_canvasBottom的显示结果。用这种方法实现的效果还是很好的,画线过程中很流畅,也不会出现屏幕闪烁的现象。
本人也是刚开始接触ActionScript,对于Flex的机制还不甚了解,不知道这种做法是否妥当,如果大家有更好的实现办法,欢迎拍砖:-)
源代码:
1

/**/
/*
2
* Guojian.Lv
3
* 2008-12-04
4
* 跟随鼠标移动画直线
5
*/
6

package
{
7
//
8
import flash.display.Sprite;
9
import flash.events.ContextMenuEvent;
10
import flash.events.MouseEvent;
11
import flash.ui.ContextMenu;
12
//
13
[SWF(width="800",height="600",backgroundColor="0x000000")]
14
public class DrawLine extends Sprite
{
15
//画线开始点
16
private var _xStart:int = 0;
17
private var _yStart:int = 0;
18
//标志位,为true时开始画线、false不动作
19
private var _bFlag:Boolean = false;
20
//画布
21
private var _canvasTop:Sprite; //顶层画布(作为临时画布,透明背景)
22
private var _canvasBottom:Sprite; //底层画布(实际保存图像的画布,黑色背景)
23
//
24
public function DrawLine()
{
25
_canvasBottom = new Sprite();
26
addChild(_canvasBottom);
27
_canvasBottom.graphics.lineStyle(1, 0xFFFFFF, 1);
28
_canvasBottom.graphics.beginFill(0x000000);
29
_canvasBottom.graphics.drawRect(0, 0, 800, 600);
30
_canvasBottom.graphics.endFill();
31
//
32
_canvasTop = new Sprite();
33
_canvasBottom.addChild(_canvasTop);
34
_canvasTop.graphics.lineStyle(1, 0xFFFFFF, 1);
35
_canvasTop.graphics.beginFill(0xFFFFFF, 0);
36
_canvasTop.graphics.drawRect(0, 0, 800, 600);
37
_canvasTop.graphics.endFill();
38
//
39
_canvasTop.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
40
_canvasTop.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
41
//
42
_canvasTop.contextMenu = new ContextMenu();
43
_canvasTop.contextMenu.hideBuiltInItems();
44
_canvasTop.contextMenu.addEventListener(ContextMenuEvent.MENU_SELECT, onContextMenu);
45
}
46
47
//鼠标单击事件
48
private function onMouseDown(event:MouseEvent):void
{
49
if (_bFlag)
{
50
//true时在底层画布画线
51
_canvasBottom.graphics.moveTo(_xStart, _yStart);
52
_canvasBottom.graphics.lineTo(mouseX, mouseY);
53
}
54
else
{
55
_xStart = mouseX;
56
_yStart = mouseY;
57
}
58
_bFlag = !_bFlag;
59
}
60
61
//鼠标移动事件
62
private function onMouseMove(event:MouseEvent):void
{
63
if (_bFlag)
{
64
//当鼠标移动,擦除上次画的线,重新画线
65
_canvasTop.graphics.clear();
66
//
67
_canvasTop.graphics.beginFill(0xFFFFFF, 0);
68
_canvasTop.graphics.drawRect(0, 0, 800, 600);
69
_canvasTop.graphics.endFill();
70
//
71
_canvasTop.graphics.lineStyle(1, 0xFFFFFF, 1);
72
_canvasTop.graphics.moveTo(_xStart, _yStart);
73
_canvasTop.graphics.lineTo(mouseX, mouseY);
74
}
75
}
76
77
//右键终止画图动作
78
private function onContextMenu(event:ContextMenuEvent):void
{
79
_bFlag = false;
80
_canvasTop.graphics.clear();
81
_canvasTop.graphics.beginFill(0xFFFFFF, 0);
82
_canvasTop.graphics.drawRect(0, 0, 800, 600);
83
_canvasTop.graphics.endFill();
84
}
85
}
86
}
/Files/Guojianlv/DrawLine.rar