想要自定义鼠标光标的样式,一直都是用Mouse.hide()然后自定义一个图形,跟随鼠标的坐标来实现,没有用过Mouse.registerCursor。
借助于ROLL_OVER和ROLL_OUT可以很方便的切换鼠标样式,但是当我们有鼠标按下时拖动的功能需求时,拖动过程中,即使ROLL_OUT发生了,也不应该切换光标样式,而当鼠标弹起,拖动结束时,又要切换到正确的光标样式。
受到transformManager的启发,加了一个lock和unlock方法,很好的解决了上面的问题。

swf如下:
可以在矩形上按下鼠标,拖动鼠标,移出矩形之后,再松开鼠标。
Main.as
package {
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.MouseEvent;
public class Main extends MovieClip {
public var mc:MovieClip;
public function Main() {
// constructor code
CursorManager.getInstance().setSatge(stage);
mc.addEventListener(MouseEvent.ROLL_OVER, rollOverHandler);
mc.addEventListener(MouseEvent.ROLL_OUT, rollOutHandler);
mc.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
}
private function mouseDownHandler(e:MouseEvent):void
{
CursorManager.getInstance().lock();
stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
stage.addEventListener(Event.MOUSE_LEAVE, mouseUpHandler);
}
private function mouseUpHandler(e:Event):void
{
CursorManager.getInstance().unlock();
stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
stage.removeEventListener(Event.MOUSE_LEAVE, mouseUpHandler);
}
private function rollOutHandler(e:MouseEvent):void
{
CursorManager.getInstance().showCursor(CursorManager.NORMAL);
}
private function rollOverHandler(e:MouseEvent):void
{
CursorManager.getInstance().showCursor(CursorManager.MOVE);
}
}
}CursorManager.as
package
{
import flash.display.Graphics;
import flash.display.Shape;
import flash.display.Sprite;
import flash.display.Stage;
import flash.events.Event;
import flash.ui.Mouse;
import flash.ui.MouseCursor;
/**
* ...
* @author hanyeah
* @date 2016/9/13 11:04
*/
public class CursorManager
{
private var _stage:Stage;
private var _curCursor:Shape = null;
private var _isLock:Boolean = false;
private var _curType:String;
private var _moveCursor:Shape = createMoveCursor();
private var _scaleCursor:Shape = createScaleCursor();
private var _rotationCursor:Shape = createRotationCursor();
private var _crossCursor:Shape = createCrossCursor();
private static const _cursorManager:CursorManager = new CursorManager();
/**正常状态光标,系统默认**/
public static const NORMAL:String = "normal";
/**缩放光标:上下**/
public static const SCALE_U_D:String = "scaleUpDown";
/**缩放光标:左右**/
public static const SCALE_L_R:String = "scaleLeftRight";
/**缩放光标:左上右下**/
public static const SCALE_UL_DR:String = "scaleUpLeftDownRight";
/**缩放光标:右上左下**/
public static const SCALE_UR_DL:String = "scaleUpRightDownLeft";
/**拖动光标**/
public static const MOVE:String = "move";
/**旋转光标**/
public static const ROTATE:String = "rotate";
/**十字光标**/
public static const CROSS:String = "cross";
public function CursorManager()
{
if (_cursorManager)
{
throw(new Error("单例模式,请使用CursorManager.getInstance()获取实例。"));
}
}
public static function getInstance():CursorManager
{
return _cursorManager;
}
/**
* 设置stage,必须要设置
* @param stage
*/
public function setSatge(stage:Stage):void
{
_stage = stage;
}
/**
* 锁定光标样式
*/
public function lock():void {
_isLock = true;
}
/**
* 解除锁定光标样式
*/
public function unlock():void {
_isLock = false;
showCursor(_curType);
}
/**
* 显示光标
* @param type
*/
public function showCursor(type:String):void
{
_curType = type;
if (_isLock) {
return;
}
if (_curCursor&&_curCursor.parent) {
_curCursor.parent.removeChild(_curCursor);
}
switch (type)
{
case SCALE_U_D:
_curCursor = _scaleCursor;
_curCursor.rotation = 90;
break;
case SCALE_L_R:
_curCursor = _scaleCursor;
_curCursor.rotation = 0;
break;
case SCALE_UL_DR:
_curCursor = _scaleCursor;
_curCursor.rotation = 45;
break;
case SCALE_UR_DL:
_curCursor = _scaleCursor;
_curCursor.rotation = -45;
break;
case MOVE:
_curCursor = _moveCursor;
break;
case ROTATE:
_curCursor = _rotationCursor;
break;
case CROSS:
_curCursor = _crossCursor;
break;
case NORMAL:
default:
_curCursor = null;
Mouse.show();
_stage.removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
break;
}
if (_curCursor!=null) {
Mouse.hide();
_stage.addChild(_curCursor);
_stage.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
}
}
private function enterFrameHandler(e:Event):void
{
if (_stage.getChildIndex(_curCursor)!=_stage.numChildren-1) {
_stage.setChildIndex(_curCursor, _stage.numChildren - 1);
}
_curCursor.x = _stage.mouseX;
_curCursor.y = _stage.mouseY;
}
//--------------------光标Shape----------------------
private function createMoveCursor():Shape
{
var ln:Number = 10; //length
var moveCursor:Shape = new Shape();
var s:Graphics = moveCursor.graphics;
var clr:uint, lw:uint, i:uint;
for (i = 0; i < 2; i++)
{
if (i == 0)
{
clr = 0xFFFFFF;
lw = 5;
}
else
{
clr = 0x000000;
lw = 2;
}
s.lineStyle(lw, clr, 1, false, null, "square", "miter", 3);
s.beginFill(clr, 1);
s.moveTo(-ln, 0);
s.lineTo(2 - ln, -1.5);
s.lineTo(2 - ln, 1.5);
s.lineTo(-ln, 0);
s.endFill();
s.beginFill(clr, 1);
s.moveTo(2 - ln, 0);
s.lineTo(ln, 0);
s.moveTo(ln, 0);
s.lineTo(ln - 2, -1.5);
s.lineTo(ln - 2, 1.5);
s.lineTo(ln, 0);
s.endFill();
s.beginFill(clr, 1);
s.moveTo(0, -ln);
s.lineTo(-1.5, 2 - ln);
s.lineTo(1.5, 2 - ln);
s.lineTo(0, -ln);
s.endFill();
s.beginFill(clr, 1);
s.moveTo(0, 2 - ln);
s.lineTo(0, ln);
s.moveTo(0, ln);
s.lineTo(-1.5, ln - 2);
s.lineTo(1.5, ln - 2);
s.lineTo(0, ln);
s.endFill();
}
return moveCursor;
}
/**
* 用于旋转的光标
* @return
*/
private function createRotationCursor():Shape
{
var aw:Number = 2; //arrow width
var sb:Number = 6; //space between arrows
var rotationCursor:Shape = new Shape();
var r:Graphics = rotationCursor.graphics;
var clr:uint, lw:uint;
for (var i:uint = 0; i < 2; i++)
{
if (i == 0)
{
clr = 0xFFFFFF;
lw = 5;
}
else
{
clr = 0x000000;
lw = 2;
}
r.lineStyle(lw, clr, 1, false, null, "square", "miter", 3);
r.beginFill(clr, 1);
r.moveTo(0, -sb);
r.lineTo(0, -sb - aw);
r.lineTo(aw, -sb - aw);
r.lineTo(0, -sb);
r.endFill();
r.beginFill(clr, 1);
r.moveTo(0, sb);
r.lineTo(0, sb + aw);
r.lineTo(aw, sb + aw);
r.lineTo(0, sb);
r.endFill();
r.lineStyle(lw, clr, 1, false, null, "none", "miter", 3);
r.moveTo(aw / 2, -sb - aw / 2);
r.curveTo(aw * 4.5, 0, aw / 2, sb + aw / 2);
r.moveTo(0, 0);
}
return rotationCursor;
}
/**
* 创建用于缩放的光标
* @return
*/
private function createScaleCursor():Shape
{
var ln:Number = 9; //length
var scaleCursor:Shape = new Shape();
var s:Graphics = scaleCursor.graphics;
var clr:uint, lw:uint;
for (var i:uint = 0; i < 2; i++)
{
if (i == 0)
{
clr = 0xFFFFFF;
lw = 5;
}
else
{
clr = 0x000000;
lw = 2;
}
s.lineStyle(lw, clr, 1, false, null, "square", "miter", 3);
s.beginFill(clr, 1);
s.moveTo(-ln, 0);
s.lineTo(2 - ln, -1.5);
s.lineTo(2 - ln, 1.5);
s.lineTo(-ln, 0);
s.endFill();
s.moveTo(2 - ln, 0);
s.lineTo(-3, 0);
s.moveTo(-ln, 0);
s.beginFill(clr, 1);
s.moveTo(ln, 0);
s.lineTo(ln - 2, -1.5);
s.lineTo(ln - 2, 1.5);
s.lineTo(ln, 0);
s.endFill();
s.moveTo(3, 0);
s.lineTo(ln - 2, 0);
s.moveTo(3, 0);
}
return scaleCursor;
}
/**
* 创建用于画线的光标(十字)
* @return
*/
private function createCrossCursor():Shape
{
var ln:Number = 12; //length
var crossCursor:Shape = new Shape();
var r:Graphics = crossCursor.graphics;
var clr:uint, lw:uint;
for (var i:uint = 0; i < 2; i++)
{
if (i == 0)
{
clr = 0xFFFFFF;
lw = 4;
}
else
{
clr = 0x000000;
lw = 2;
}
r.lineStyle(lw, clr, 1, false, null, "square", "miter", 3);
r.moveTo( -ln, 0);
r.lineTo(ln, 0);
r.moveTo(0, -ln);
r.lineTo(0, ln);
}
return crossCursor;
}
//end
}
}使用的时候很简单,首先需要传入一个stage,使用CursorManager.getInstance().setSatge(stage);
然后在ROLL_OVER事件中设置光标样式,如CursorManager.getInstance().showCursor(CursorManager.MOVE);
ROLL_OUT事件中永远都是恢复正常状态,CursorManager.getInstance().showCursor(CursorManager.NORMAL);
MOUSE_DOWN开始拖动的时候CursorManager.getInstance().lock();
MOUSE_UP拖动结束的时候CursorManager.getInstance().unlock();
每个要自定义光标样式的对象都是这个模式,互不影响。当然,如果父显示对象和子显示对象都定义了光标样式,适当的阻止事件的冒泡还是需要自己来做的。
有空研究一下Mouse.registerCursor怎么用。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。