13
2016
09

鼠标光标管理

想要自定义鼠标光标的样式,一直都是用Mouse.hide()然后自定义一个图形,跟随鼠标的坐标来实现,没有用过Mouse.registerCursor。

借助于ROLL_OVER和ROLL_OUT可以很方便的切换鼠标样式,但是当我们有鼠标按下时拖动的功能需求时,拖动过程中,即使ROLL_OUT发生了,也不应该切换光标样式,而当鼠标弹起,拖动结束时,又要切换到正确的光标样式。

受到transformManager的启发,加了一个lock和unlock方法,很好的解决了上面的问题。

swf如下:

可以在矩形上按下鼠标,拖动鼠标,移出矩形之后,再松开鼠标。

获得 Adobe Flash Player

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怎么用。


源码打包下载

« 上一篇下一篇 »

相关文章:

闪电效果  (2017-11-28 15:4:19)

线段与椭圆的交点  (2017-1-6 14:43:41)

as3录制swf并保存flv视频  (2016-12-28 8:43:41)

解九连环  (2016-12-1 20:58:11)

as3实现setTimeout和trace  (2016-11-10 16:47:37)

registerCursor注册系统光标  (2016-9-14 9:49:40)

变形框(transform)实现  (2016-9-13 16:56:6)

flash文本消除锯齿不显示  (2016-8-25 11:43:31)

greenSock的easing曲线  (2016-8-24 18:30:11)

如何在Flash IDE里正确地对位图进行九切片(九宫格)缩放(转)  (2016-8-19 16:41:44)

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。