Grab Cursor Native Mouse AS3

Jan 25, 2013   //   by EderChrono   //   Blog {en}  //  3 Comments

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

  • 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

Leave a comment