Flash MouseWheel event on ALL browsers

Cut a long story short – took me a long time to find a solution to support Flash MouseWheel on all browsers, Windows AND Mac.

You can see this live here: http://www.pairhaps.com

This solution is a combination of two technics, and as of today (March 2013) supports ALL browsers on Windows and Mac:
First, loading an AS2 SWF from internal byteArray (that version still supports mouseWheel), this works for IE. download the class here: http://etcs.ru/blog/as3/mousewheel_v11_update/
Second, adding JS function that listens to mouseWheel event and passes it to Flash via ExternalInterface (DOM).Each browser needs its own function because of the differences in the event object.

For efficiency my implementation is testing the browser user agent on the server (PHP) and writing the correct JS function to support the mouseWheel event on that browser.

The JS functions are as follows:

Windows:Firefox:

window.addEventListener("DOMMouseScroll", handleWheel, false);
function handleWheel(event)
{
var app = swfobject.getObjectById("FLASH_OBJECT_ID");
var _x = event.clientX;
var _y = event.clientY;
var _delta = event.detail;

if (app) {
var o = {x: _x, y: _y, delta: _delta, ctrlKey: event.ctrlKey, altKey: event.altKey, shiftKey: event.shiftKey};
app.handleWheel(o);
}
event.preventDefault();

}

Windows:Chrome:

window.addEventListener ("mousewheel", handleWheel, false);
function handleWheel(event)
{
var app = window.document["${application}"];
var _x = event.screenX;
var _y = event.screenY;
var _delta = event.wheelDelta * 4;
if (app) {
var o = {x: _x, y: _y, delta: _delta, ctrlKey: event.ctrlKey, altKey: event.altKey, shiftKey: event.shiftKey};
app.handleWheel(o);
}
}

Mac:Safari:

window.onmousewheel = deltaDispatcher;
function deltaDispatcher(event)
{
var app = swfobject.getObjectById("FLASH_OBJECT_ID");
var _delta = event.wheelDelta/60;
var _x = event.screenX;
var _y = event.screenY;
if (app) {
var o = {x: _x, y: _y, delta: _delta, ctrlKey: event.ctrlKey, altKey: event.altKey, shiftKey: event.shiftKey};
app.handleWheel(o);
}
if(event.preventDefault)event.preventDefault();
}

And in Flash AS main class:

import utils.MouseWheel;

After added to stage add these:

ExternalInterface.addCallback("handleWheel", handleWheel);
stage.addEventListener(Event.ACTIVATE, flashActive);
stage.addEventListener(Event.DEACTIVATE, flashDeactive);

And finally, add these fundtions:

private function handleWheel(event:Object) : void
{
var obj : InteractiveObject = null;
var mousePoint : Point = new Point(stage.mouseX, stage.mouseY);
var objects : Array = stage.getObjectsUnderPoint(mousePoint);

for (var i : int = objects.length - 1; i >= 0; i--) {
if (objects[i] is InteractiveObject) {
obj = objects[i] as InteractiveObject;
break;
}
else {
if (objects[i] is Shape && (objects[i] as Shape).parent) {
obj = (objects[i] as Shape).parent;
break;
}
}
}

if (obj) {
var mEvent : MouseEvent = new MouseEvent(MouseEvent.MOUSE_WHEEL, true, false,
mousePoint.x, mousePoint.y, obj,
event.ctrlKey, event.altKey, event.shiftKey,
false, Number(event.delta));
obj.dispatchEvent(mEvent);
}
}
private function flashActive(event:Event):void
{
MouseWheel.capture();
}
private function flashDeactive(event:Event):void
{
MouseWheel.release();
}

Injecting and calling JS functions from within flash using external

JS injection

I recently encountered a unique requirement in one of my projects, triggering the loading of a page in the background (outside of flash, using Ajax) from within flash.
Often you cannot rely on JS functions to be available, you could load public libraries (Jquery or equivalent) or inject your own functions to the DOM, I chose to inject my own.

This is how you do it:

1) import the external class.

import flash.external.ExternalInterface;

2) declare a constant variable with all the JS functions:

private const script_js :XML =
<script>
<![CDATA[
function() {
AJXFNC = {
ajaxFunction:function(_url){

var ajaxRequest;
try{
// Opera 8.0+, Firefox, Safari, Chrome
ajaxRequest = new XMLHttpRequest();
ajaxRequest.open("GET", _url, true);
ajaxRequest.send(null);

} catch (e){
// Internet Explorer Browsers
try{
ajaxRequest = new ActiveXObject("Msxml2.XMLHTTP");
ajaxRequest.open("GET", _url, true);
ajaxRequest.send();

} catch (e) {
try{
ajaxRequest = new ActiveXObject("Microsoft.XMLHTTP");
ajaxRequest.open("GET", _url, true);
ajaxRequest.send();

} catch (e){
// Something went wrong
return false;
}
}
}
}

}
}
]]>
</script>;

3) inject the JS to DOM:

try {
if( ExternalInterface.available )ExternalInterface.call( script_js );
} catch( error:Error ) {
trace("ExternalInterface is not available");
}

4) call a function:

ExternalInterface.call( "AJXFNC.ajaxFunction", "http://www.google.com" );

Sweet isn’t it?

Random number without repeat as3

We’re using the random object for many things, by its nature it may repeat a number, but sometimes we don’t want to get the same number more than once, for example when showing a random image out of an array of images, or jumping to a random frame in a MovieClip. Currently there is no ‘unique’ function in Actionscript, you have to write your own solution.

Here is my class for generating random numbers:

randomPlus



Download: RandomPlus.as.

Usage:
Create an instance of RandomPlus, defining the numbers scope (start & end numbers), including negative values. in case only one parameter is passed the RandomPlus object will assume it is the end number and that the start number is zero:
var rp:RandomPlus = new RandomPlus( end:Number, start:Number = 0 );

After that you can use ‘getNum’ public function that will return a random number within the scope:
rp.getNum(); // returns a Number

You can use public var ‘len’ to retrieve the length of the scope in case you want to use it for your function:
rp.len; // returns a Number

*The object will return unlimited amount of numbers, each time the entire scope was returned it will reshuffle the items so it will continue to return random numbers within the scope, in an ever-changing order.

Let me know if you liked it (or if you have suggestions), enjoy :)

Profyler – profile image creation app

Many people are having troubles resizing and processing pictures into a profile image (say for Facebook?), there are countless free utilities and apps out there (most of them look pretty shitty..), and also several online services, and now there is another one – mine :)

profyler



It’s a flash application that enables you to scale and process an image from your computer, and when you’re happy with it, you can save it to your computer. The application does not communicate with external servers and does not save or send any data anywhere.

As always, it’s a work in progress, I will be adding features and effects as time allows me, but it is fully functional right now. So go a head, give it a shot and create your own profile image, it’s really easy and fast.
Don’t forget to let me know if you liked it!
enjoy :)

This is the public link of this application, in case you want to share it:
http://www.todepoint.com/profyler

* I will be writing some more soon, describing several aspects of making this application, stay tuned.
 

Pure code AS3 spinning loading animation

While working on the video player, I wanted to show spinning loading animation while buffering, and since I decided that the whole thing will be pure code, with no library assets, I had to code this animation – just the kind of things I like.
It didn’t take long, and I decided to share it – why not?

So here it is:

loader animation with action script 3 code

What you need to do in order to use it is add two functions:


import LoadAnim;
...
private var myAnim :LoadAnim;
...

public function showAnim():void
{
myAnim = new LoadAnim(0x333333); // animation color
myAnim.x = stage.stageWidth / 2;
myAnim.y = stage.stageHeight / 2;
addChild(myAnim);
}

public function hideAnim():void
{
myAnim.stopAnim();
removeChildAt(1);
}

Download the class here, enjoy : )

The ultimate video player – as3

There are many video players in flash out there, lots of them are open too, I’ve found few tutorials out there giving everything you need to know to code a video player. few of them work really nice and heavily distributed (JW Player), others have cool UI, few considered proper integration of keyboard control, most of them don’t. yet none of them has it all. none of the player I saw had the right touch.

So I decided to take the challenge and make a code only (no library assets), lightweight video player, with elegant UI that works as you would expect it to, with keyboard control (starting with play/pause, forward/backwards jumps, the fundamentals, the musts). also fullscreen mode and moving between the screen modes by double clicking a la VLC (which is my favorite video player on the Mac), and of-course buffering.

At the moment the features are:
• Keyboard control: play/pause (space bar); jump backwards/forward (left/right);
• Volume control affecting the volume while pressing and moving cursor;
• Fullscreen-normal by double-clicking the video or dedicated button;
• Single click on the video toggles play/pause;
• Display of position and total duration;
• Clickable progress bar, a click will jump video to position.
• Control bar will hide when mouse leaves stage.
• File size is 20.8k (!!)

Credits:
The architecture was inspired by Mr.doob’s player, but I replaced his video controller with the excellent FLVPlayer by Martin Legris, and added my own touch and flavor :)

Suggestions are more than welcome, tell me what you think!

Update: I was working on improving the player behavior across platforms and browsers, discovering that events behavior is different on IE from the ret of the browsers. Surprising ha? MouseEvent.MOUSE_OUT added to the stage is not firing on IE, you have to add Event.MOUSE_LEAVE, it still works for the rest of the browsers. This actually solved several oddities on IE, people are still using it? really?!

Update 2: I added spinning loading animation when video is buffering, and moved the duration text to be next to the position text, I guess it is easier for the eye this way.

How to stroke several sprites as one

If you’re trying to create a single stroke (outline, contour) over several sprites or movieClips, you can simply create a parent object to hold them and apply a glow filter to it. In this example (yeah, it’s an old and basic as2 thing, a test I did ages ago) I applied a glow filter of 2 pixels Blur to the comic balloon background.

The background is made of two movieClips, each has it’s own behavior, if you click the horn you can adjust its size and direction, if you click the text area you can scale the textField and the balloon background along with it.

This trick can be really handy if you’re making animations of moving silhouettes. In this flash I used GreenSock’s TransformManager to make the textField and horn controlable.

Glossy buttons in pure as3 code


I’ve been playing with the drawing classes, experimenting gradients and blending modes, and so I put together a small (basic) as3 class that generates a glossy button with pure code – no library assets.

You can download the class here.

The class constructor expects only 3 parameters:
@param rad = Width of button
@param darkColor = The color in top area, more dominant
@param lightColor = The color in the bottom area

* you can then place it anywhere, and use method setCaption(cap:String) to place a label on the button, though this is a very basic implementation of text handling, I focused on drawing..

Let me know if you liked it : )

ResizeManager – simple scaling engine for MovieClips

Flash objects (SWF) can fill the entire Html body, and scale along with browser window as you resize it (it’s done by setting width and height attributes to 100% in the embed tags). However unless scaleMode is properly defined as well, the outcome may look surprisingly bad, the flash content may loose proportions and distort, images quality drops and texts loose readability.. oh man.

Only specific contents should be scaled when the stage is resized, the same way apps handles resizing: an app will redistribute its panels without scaling them, will scale panel background but not the buttons and the controls in it. When the entire stage is simply scaled, the interface balance is disturbed.. and we don’t want that.

So I decided to share: ResizeManager (download) is a very simple scaling engine, a single AS2 class that can easily be modified or extended for your needs.
The manger can control scaling and some basic align options of MovieClips you register to it, so you can scale a background MovieClip to cover the entire stage, and keep another MovieClip centered without scaling. It also adds default definitions for the Stage behavior (scaleMode: noScale, stageAlign: TL), though you can change those.
In order to use it, simply import the class and create an instance of the ResizeManager:

import com.adifeiwel.custom_ui.ResizeManager;

var rm = new ResizeManager();

Then, use method registerMC() to register each MovieClip you want to control (including MovieClips nested within MovieClips, make sure parent MC is x:0, y:0), the registerMC method expects the following parameters:
_parentName:MovieClip (the name of the MoviClip)
_widthUpdate:Number (scaling in percentage from Stage.width, 0 for no-scale)
_heightUpdate:Number (scaling in percentage from Stage.height, 0 for no-scale)
_centerUpdate:Boolean (align MovieClip to center of stage)
_middleUpdate:Boolean (vertical-align MovieClip to middle of stage)

for example (see it here):

rm.registerMC(portMC.mainBG, 100, 100, false, false);
// will scale to cover all Stage

rm.registerMC(portMC.middleMC.middleBG, 100, 0, false, false);
// will scale to take 100% of Stage.width

rm.registerMC(portMC.middleMC.middleContentMC, 0, 0, true, false);
// aligned to center

rm.registerMC(portMC.transMC, 0, 0, true, true);
// aligned to center, vertical-align to middle.

rm.registerMC(portMC.vClip, 0, 80, false, false);
// will scale to take 80% of Stage.height

enjoy : )

Update: You can download the example FLA here.