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 :)

The iTunes clutter and users perception

Sometimes companies let technical considerations affect their product strategy in a bad way, allowing “practical” point of view override the “user” point of view. Startups often say “our technology does X, this can be interpreted into several actions, let’s wrap them together to make a bigger offering while keeping small resources and requirements on our side”.
They forget that each product is accepted by users perception under a contextual category, a definition, a purpose. for instance, for me Cyberduck is a ftp client, it’s a utility, it’s used for my professional productive activities. VLC is a video player, it’s for seeing movies, for fun. I see no point in mixing those together into one application, even if the core technology was the same. I said IF. Another point is using terms for ‘normal’ people, correct, understandable, don’t exaggerate. Don’t call your service ‘GPS’ if it only provides numeral coordinates, for me, and probably most users, GPS is something else, it has maps and gives directions, 3D view, etc. your marketing may look more effective but the truth will be revealed eventually and you will never gain my trust again.

Interesting bad example would be iTunes. yes, I love my mac, after 12 years I can’t see my self going back to windows, but still, Apple made some arrogant mistakes in this area, iTunes is one of them. It’s the best music player in the market, I never used the itunes store to buy movies or TV shows, because for me itunes is for music, I would expect to find movies and such in Quicktime, but it didn’t really bother me. Then I got an iPod. syncing music from itunes forced apple to use an interface originally designed for playlists and songs for file system & disk utilities actions, this added a new kind of screen with new set of controls to the ones I already knew in iTunes, which immediately made the entire app a bit more scary.
itunesClutter
And then I got an iPhone, and the AppStore, and then came Ping, and over and over again the whole iTunes experience was stretched to new areas. Why?
Wouldn’t it be easier for us users and you Apple to split this clutter into several existing applications? let iTunes play tunes, let iSync do sync and backup, let Quicktime play movies?

The dark side of the moon

Started working on a new & interesting project for Microsoft’s Innovation Lab, can’t disclose any details, but I can say it’s pretty exciting.
So now I can play with all the coolest gadgets scattered around the lab, drink as much coke as I want, and best, show-off the shiny blue apple on my Mac to all the poor guys here with their industrial-black-plastic-laptops.. :)
Microsoft Innovation Lab

Mysterious voodoo phenomenon with eclipse line numbers

Working with a second monitor in Flashbuilder4 on MacOS 10.6 Snow Leopard, I noticed that the line numbers weren’t scrolling along with the page, after a quick googling I found it is a known bug (here) and that there is a patch (here) that fixes it.
So I tried it – replaced the existing .jar file with the patched one I downloaded, run Flashbuilder in “clean” but it didn’t start, reported some error. after few attempts I decided to leave this for now as I am in the middle of a project. Sadly I rolled back to the original .jar and restarted Flashbuilder just to find out that now it works!

Could it have to do with the song I was listening to (‘Voodoo child’ by Jimi Hendrix)??

Update: Nope. stopped scrolling again :(

Tips on connecting blogs to Facebook

I just finished connecting my blog and few other pages on my site to Facebook, to enjoy some sharing goodness of the social community, as well as Facebook’s ‘insight’ statistics – why not enjoy what is given for free right?

I had some setbacks and strugles along the way, thought it might save you some time (and wasted ‘Likes’ too) to write few tips down. It will not be a full tutorial, instead I will focus on some oddities on the Facebook side:

First tip will be: Do not implement until you REALLY understand what your options are and what exactly you want to do. Facebook offers two main options for adding a ‘Like’ button to your page/site/blog, one is IFRAME, second is XFBML. The iframe option is as simple as adding a line in your html source, and will get you going in seconds. The xfbml is based on their Javascript SDK, and sports the Facebook ‘insight’ statistics via open graph, but requires few preliminary steps which are kinda tricky as the documentation is fairly sparse. Obviously we would prefer the xfbml option.

In order to use xfbml you will need an AppID, which require you to set up an application, to do that you will have to add the Developer application to your Facebook Profile.

Then, you have to activate you developer account – you have to give you cell number, after which you will receive a code via sms to submit.

Then you can create an application in Facebook here.
* This page has a strange behavior, you will define your application name, pass a captcha and receive an Error page:
“Sorry, an error has occurred.
We’re working on getting this fixed as soon as we can.”

Creating Facebook application error
But if you look at the column on the right in the developers page, you will see that the application was actually created:
Facebook applications list (Facebook, are you serious about that? is this some kind of a test?) I ended up creating about 10 applications, read countless forums threads until I found it by mistake!

After that you can start implementing, follow the instruction here which are pretty simple.

Since I thought Facebook application creation service is down, I started with the iframe version, obviously a mistake as all the ‘Likes’ I got were dumped once I connected the xfbml. damn.

Good luck and may the force be with you..

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 : )