想要自定义鼠标光标的样式,一直都是用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怎么用。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。