Grab Cursor Native Mouse AS3
Since flash player 10.2 you can make custom mouse cursors for your applications. Today I'll show you how to use a class I made for a simple but really useful custom grab cursor. First of all, many of you may think that it would be easier to hide the cursor and make a movie clip follow the mouse. The problem with this approach is that on graphic intensive scenarios, the cursor can get really unresponsive or have a delay. With this tip the mouse response is practically as fast as the native one.
What you'll need is to download this pack of files that contains:
-Fla file with the necesary graphics.
-An Empty Main class.
-The Grab Cursor class.
Important: In order for this to work you must export at least to flash player version 11.2 (check your publish settings).
Now lets open our fla file, if you check the library you'll notice a pair of graphics that we are going to use. In order to use them they must be linked to action script like this:
Now lets see how the GrabCursor class works.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 | package com.ederdiaz.utils { import flash.ui.MouseCursor; import flash.ui.MouseCursorData; import flash.geom.Point; import flash.display.Bitmap; import flash.display.BitmapData; import flash.events.Event; import flash.events.MouseEvent; import flash.ui.Mouse; /** * @author Eder */ public class GrabCursor { private var isOpen: Boolean = true ; private var isHidden: Boolean = true ; public function GrabCursor() { //function that initially takes the graphics for the cursor setupBitmapData(); } private function setupBitmapData(): void { //we create instances of the hands bitmapData var openedBmd:BitmapData = new HandOpened(); var closedBmd:BitmapData = new HandClosed(); //we must create the mouse cursor data first var cursorDataOpen:MouseCursorData = new MouseCursorData(); //we have to center the bitmap so it corresponds to the mouse position cursorDataOpen.hotSpot = new Point( 9 , 9 ); //each cursor data must have a vector of bitmapdata (in case you need an animated one) var bitmapDatasOpen:Vector.<BitmapData> = new Vector.<BitmapData>( 1 , true ); //here we just assign 1 so it won't be animated bitmapDatasOpen[ 0 ] = openedBmd; cursorDataOpen.data = bitmapDatasOpen; //now we register it with an id Mouse.registerCursor( "open_grab_cursor" , cursorDataOpen); //we repeat the process for closed hand cursor var cursorDataClosed:MouseCursorData = new MouseCursorData(); cursorDataClosed.hotSpot = new Point( 9 , 9 ); var bitmapDatasClosed:Vector.<BitmapData> = new Vector.<BitmapData>( 1 , true ); bitmapDatasClosed[ 0 ] = closedBmd; cursorDataClosed.data = bitmapDatasClosed; Mouse.registerCursor( "closed_grab_cursor" , cursorDataClosed); } public function show(): void { if (!isHidden) return ; if (isOpen) Mouse.cursor = "open_grab_cursor" ; else Mouse.cursor = "closed_grab_cursor" ; isHidden = false ; } public function hide(): void { if (isHidden) return ; Mouse.cursor = MouseCursor.AUTO; isHidden = true ; } public function open(e:MouseEvent = null ): void { isOpen = true ; if (!isHidden) Mouse.cursor = "open_grab_cursor" ; } public function close(e:MouseEvent = null ): void { isOpen = false ; if (!isHidden) Mouse.cursor = "closed_grab_cursor" ; } } } |
It's actually really straight forward, the only complicated thing is the setup of the bitmap data.
Now in order to use it in our Main class, we can add something like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | package { import flash.display.MovieClip; import com.ederdiaz.utils.GrabCursor; import flash.events.MouseEvent; public class Main extends MovieClip { private var gc:GrabCursor = new GrabCursor(); public function Main() { gc.show(); stage.addEventListener(MouseEvent.MOUSE_DOWN,closeHand); stage.addEventListener(MouseEvent.MOUSE_UP,showHand); } private function closeHand(e:MouseEvent): void { gc.close(); } private function showHand(e:MouseEvent): void { gc.open(); } } } |
Now if you test it you must be able to see the custom hand cursor, and when you press your left mouse button the hand should close.
In case that it didn't work for you here are the final source files.
3 Comments
Leave a comment
Files
- January 2013 (2)
- October 2012 (1)
- July 2012 (2)
- June 2012 (2)
- May 2012 (2)
- February 2012 (4)
- December 2011 (4)
- September 2011 (4)
- May 2011 (4)
- April 2011 (1)
- March 2011 (2)
- January 2011 (1)
- December 2010 (13)
- September 2010 (1)
- June 2010 (2)
- May 2010 (1)
- April 2010 (11)
- March 2010 (10)
- February 2010 (1)
Hello,
Thanks for the tutorial. I have two questions.
1. I notice I can not make my hand PNG larger than 18×18 without getting errors. Anyway around this?
2. I notice this will run animated cursors. How do I get started? I tried to link a MovieClip but the linkage seems to require a png?
*** I wasn’t able to update my comment. I assume the cursor must be animated via a sprite sheet.
The API says that the cursor maximum size is 32×32 pixels.
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/ui/MouseCursorData.html
For animated cursors you must fill the vector object with as many frames as you need, in my example I just used 1 frame:
var bitmapDatasClosed:Vector. = new Vector. (1, true);
bitmapDatasClosed[0] = closedBmd;
//if you wanted to add animation just do something like this
bitmapDatasClosed[1] = otheBmd1;
bitmapDatasClosed[2] = otheBmd2;
bitmapDatasClosed[3] = otheBmd3;
Also you can check a more detailed post here