A day or two ago polyGeek has revived an old and challenging idea that one could make use of custom right-click functionality in Flash (AS3 + Javascript).
Why would anyone want to do this? Well, there are several very important reasons:
1) Games – the power of AS3 has brought Flash to the world of digital entertainment. At last it is possible to focus on the idea of your game rather than on how to improve the laggy experience. One thing that is still missing – right click functionality. We had this forever in desktop games, now it is time to let your casual RTS, RPG and FPS creations conquer the web.
2) User Experience – 2 buttons are better than 1. Every experimentalist's dream is to be able to have more input options, not just one button. I can bet someone would soon create a stunning interface using this new functionality and we would see that on no less than FWA.
3) RIA – Rich Internet Applications. My clients are often asking if it is possible to remove embeded Flash Player menus from their applications and replace them with their company’s branding stuff.
***
AND THE ANSWER IS – YES! It is now possible to use custom right-click functionality in Flash and even Flex.
After long hours of searching through Microsoft’s documentation I came up with a universal solution that works nicely at least on 3 major browsers – Firefox 2, IE 7 and Safari. (IE6 has not been tested but I can bet it works OK).
***
Here you can see the * DEMO of right click * functionality (click the grey area to draw transparent dots)
Javascript source code looks like this:
JAVASCRIPT:
-
/**
-
*
-
* Copyright 2007
-
*
-
* Paulius Uza
-
* http://www.uza.lt
-
*
-
* Dan Florio
-
* http://www.polygeek.com
-
*
-
* Project website:
-
* http://code.google.com/p/custom-context-menu/
-
*
-
* --
-
* RightClick for Flash Player.
-
* Version 0.6.2
-
*
-
*/
-
-
var RightClick =
{
-
/**
-
* Constructor
-
*/
-
init:
function
(
)
{
-
this.
FlashObjectID =
"customRightClick";
-
this.
FlashContainerID =
"flashcontent";
-
this.
Cache =
this.
FlashObjectID;
-
if
(window.
addEventListener
)
{
-
window.
addEventListener
(
"mousedown",
this.
onGeckoMouse
(
),
true
);
-
}
else
{
-
document.
getElementById
(
this.
FlashContainerID
).
onmouseup =
function
(
)
{ document.
getElementById
(RightClick.
FlashContainerID
).
releaseCapture
(
);
}
-
document.
oncontextmenu =
function
(
)
{
if
(window.
event.
srcElement.
id == RightClick.
FlashObjectID
)
{
return
false;
}
else
{ RightClick.
Cache =
"nan";
}
}
-
document.
getElementById
(
this.
FlashContainerID
).
onmousedown = RightClick.
onIEMouse;
-
}
-
},
-
/**
-
* GECKO / WEBKIT event overkill
-
* @param {Object} eventObject
-
*/
-
killEvents:
function
(eventObject
)
{
-
if
(eventObject
)
{
-
if
(eventObject.
stopPropagation
) eventObject.
stopPropagation
(
);
-
if
(eventObject.
preventDefault
) eventObject.
preventDefault
(
);
-
if
(eventObject.
preventCapture
) eventObject.
preventCapture
(
);
-
if
(eventObject.
preventBubble
) eventObject.
preventBubble
(
);
-
}
-
},
-
/**
-
* GECKO / WEBKIT call right click
-
* @param {Object} ev
-
*/
-
onGeckoMouse:
function
(ev
)
{
-
return
function
(ev
)
{
-
if
(ev.
button !=
0
)
{
-
RightClick.
killEvents
(ev
);
-
if
(ev.
target.
id == RightClick.
FlashObjectID && RightClick.
Cache == RightClick.
FlashObjectID
)
{
-
RightClick.
call
(
);
-
}
-
RightClick.
Cache = ev.
target.
id;
-
}
-
}
-
},
-
/**
-
* IE call right click
-
* @param {Object} ev
-
*/
-
onIEMouse:
function
(
)
{
-
if
(event.
button>
1
)
{
-
if
(window.
event.
srcElement.
id == RightClick.
FlashObjectID && RightClick.
Cache == RightClick.
FlashObjectID
)
{
-
RightClick.
call
(
);
-
}
-
document.
getElementById
(RightClick.
FlashContainerID
).
setCapture
(
);
-
if
(window.
event.
srcElement.
id
)
-
RightClick.
Cache = window.
event.
srcElement.
id;
-
}
-
},
-
/**
-
* Main call to Flash External Interface
-
*/
-
call:
function
(
)
{
-
document.
getElementById
(
this.
FlashObjectID
).
rightClick
(
);
-
}
-
}
On the Flash side is as simple as this code (AS3):
Actionscript:
-
package
{
-
-
import flash.
display.*;
-
import flash.
external.
ExternalInterface;
-
-
public
class RightClick
extends Sprite
-
{
-
-
public
function RightClick
(
)
-
{
-
stage.
scaleMode = StageScaleMode.
NO_SCALE;
-
stage.
align = StageAlign.
TOP_LEFT;
-
-
var methodName:
String =
"rightClick";
-
var method:
Function = onRightClick;
-
ExternalInterface.
addCallback
(methodName, method
);
-
}
-
-
private
function onRightClick
(
):
void
{
-
-
var mx:
int =
stage.
mouseX;
-
var my:
int =
stage.
mouseY;
-
-
if
(my>
0 && my <stage.
stageHeight && mx>
0 && mx <stage.
stageWidth
)
{
-
// YOUR CODE HERE
-
}
-
}
-
}
-
}
This demo has been tested and confirmed working on:
WINDOWS VISTA
- Internet Explorer 7.0.6001 (16549)
- Firefox 2.0.0.6 (with mouse gestures disabled)
- Maxthon 2 (with mouse gestures disabled)
- Safari 3.0.3 (522.15.5)
Windows XP SP2
- Internet Explorer 6
- Internet Explorer 7
- Maxthon 2 (with mouse gestures disabled)
- FireFox 2 (with mouse gestures disabled)
- Safari 3
- Netscape 8
Mac OSX 10.4.10 (Intel)
Thank you all for testing!
Opera will not work, the browser forces the context menu to appear and blocks mouse events by default.
If you manage to get the demo working, please post the OS and Browser build number in the comments. Please also leave a comment if you experience any problems with the demo.
.