AS3.0 MouseWheel on Mac OS X
I’ve finally found the time to port my SWFObject add-on SWFMacMouseWheel (catchy I know) to ActionScript 3.0 and SWFObject 2.0
There’s now two examples in the zip, one for use with SWFObject 1.5, and a totally re-written version for use with SWFObject 2.0 (formerly SWFFix)
All you have to do in your main application class (or document class) is
[as]
import com.pixelbreaker.ui.osx.MacMouseWheel;
MacMouseWheel.setup( stage );
[/as]
You can then add listeners to TextFields, Sprites etc etc as you normally would any other MouseEvent.
Example JavaScript to be used with the dynamic embed method
[js]
var vars = {};
var params = { scale:’noScale’, salign:’lt’, menu:’false’ };
var attributes = { id:’testObject’, name:’testObject’ }; // give an id to the flash object
swfobject.embedSWF(“test_as3.swf”, “flashContent”, “100%”, “100%”, “9.0.0″, “js/expressInstall.swf”, vars, params, attributes );
swfmacmousewheel.registerObject(attributes.id);
[/js]
I have updated the SWFObject 2.0 version to be more compact, and it also falls inline with the code style of SWFObject2.0. see swfmacmousewheel_src.js for the uncompressed version, deploy swfmacmousewheel2.js on your site.
Download source and demo here or view the demo online
86 Comments so far
God bless you, your children, the children of your children for this wheel thing
Thanks so much for this solution to the mouseWheel on Macs. Now if I can just get the mouseWheel to work on Firefox 2 in Windows.
Just a note for those wondering how to get it to work in a Flex mxml application, use MacMouseWheel.setup(Application.application.stage). I had to put this line of code in the applicationComplete event handler rather than the initialize or creationComplete event handlers.
In my post above, I should have provided the detail that setting wmode=opaque breaks Flash’s MouseWheel in Firefox 2 on Windows. A javascript solution similar to your MacMouseWheel would probably be a work around until either Mozilla or Adobe fixes the problem.
You need to check out Chumby.com
With your mad flash skills, you’d have some fun with it.
MyridoM
Firefox with firebug gives a problem in the console:
swfmacmousewheel has no properties
http://blog.pixelbreaker.com/downloads/swfmacmousewheelas3demo/index_as3.html
Line 15
Any solution?
is that on windows? if so, i should clean that up, at present, if the OS is not a mac, it returns a null object as swfmacmousewheel.
davi: I’ll have a look into this…
Yep I just tried it on Safari for windows.. Doesn’t work :/ (Safari Ver 3.1)
I don’t understand, i have safari 3.1 on windows, and i can’t run the demo online ?
You code just made in onto a MOMA minro site
http://media.moma.org/subsites/2008/olafureliasson/#/intro/
Your code just made in onto a MOMA minro site
http://media.moma.org/subsites/2008/olafureliasson/#/intro/
I noticed something funny with the fullscreen mode.. on Mac Safari it works in normal mode but not in fullscreen mode and on Windows Safari it’s the opposite.. it doesn’t work in normal mode, but it DOES work in fullscreen mode. Pretty strange..
Note: I’m using the new JS but still the old AS 2.0 script.
This sounds good.
However I primarily had given up on Mac Scrollwheeling and was searching for a solution on another problem that could be solved by this if ported for Windows…
The thing is: to give a Flash App focus from the browser (to be able to start typing in a Flash Text Field directly after visiting the site), you need to give the Flash App focus from JavaScript myObject.focus(), and in Flash give the focus to the component needing to get focus by doing for example creationComplete=”myComponent.setFocus();” (Flex).
However, in FireFox, the javascript myObject.focus() will only work if the Flash object is loaded using wmode=”opaque”. And that again breaks scroll wheel functionality in Windows FireFox.
Question:
- Are there any known side-effects from this script by PixelBreaker?
- Is there any Windows Port (to be build by anyone) ?
Kind regards,
nl-x
Great work! I think you can simplify the API a bit though: ExternalInterface exposes the SWF’s id via its objectID property. Since you’re already requiring ExternalInterface, why not just have the SWF register itself? If you call swfmacmousewheel.registerObject(ExternalInterface.objectID) from your MacMouseWheel._setup method, you can completely eliminate the need for any additional javascript in your HTML.
Is this possible with AS2?
I am like the 2nd that commented: “God bless you, your children, the children of your children for this wheel thing
”
DIE HTML DIEEEE
)
Hey Pixelbreaker,
I like the fact that the macmousewheel allows me to utilize the scrollwheel in FireFox on a PC, and Safari on a Mac.
However, I have run into a couple issues with it:
1- On Firefox on a PC, if you use the parameter
so.addParam(‘wmode’, ‘transparent’);
the scrollwheel does not work. It works fine on IE on a PC though.
2- Although the macmousewheel makes the scroll wheel active on Safari for Mac, it completely disables the scroll wheel for the entire page that the Flash is embedded in. The scroll wheel works only in the Flash and nowhere else on the page.
Do you have any solutions to this?
With these issues unresolved, my best fix currently is to stop using macmousewheel so that I get the other functionality I am looking for.
I bow down… this is a very nice piece of work, thanx
great post for mac
import com.pixelbreaker.ui.osx.MacMouseWheel;
MacMouseWheel.setup( stage );
Bobby is right in (2) above – if your Flash embedding fails (e.g. the person does not have Flash installed) the Mousewheel is then broken for the alternative content!
What would be ideal is if the event handlers could only be attached on the first call of registerObject() so that mouse wheeling worked as normal for HTML if no call to the class was made.
G
Gabriel, Great work, thanks for putting it out there. My question is actually relating to your old version of the MouseWheel for AS2.
I had the AS3 version working, but due to some other elements of the site I’m working on, I am forced to use AS2. The problem occurs while loading SWFs that use MouseWheel into a container using LoadMovie… on the second load (whichever clip I choose to load second using the menu) the browser crashes once you try to scroll using the wheel.
This happens in firefox and safari (latest versions of both browsers and OSX) and no matter what order I load the clips in. Here’s an example…
http://www.designbus.com/debug
I’m hoping at some point you may have solved the issue in your own usage of the AS2 version.
I can only think that it has something to do with multiple loads of the class overloading the plugin? Or maybe a pile up of listeners. I don’t know. I’ve tried clearing the listener manually on each load, and tried looking for a way to clear the import prior to a new load, all to no avail.
Thanks for any info you, or anyone else here, may have.
Just brilliant, two lines added in my code and everything is working perfectly.
Great work, I love when it is quick and easy
great work, there’s one things I’d like to mention, I’ve also run the example on IE6 (XP) and the delta values are fairly different.
IE values are often -+3 or -+6 but on Mac with you fix the values are quite nice, they’re from -+1 to …
which is good but not consistent.
regards,
Viktor
DOESN’T WORK IN SAFARI 3.0.3 (win32)
Hi, AWESOME script, I’ve been using for a while already. THANKS
BUT I need for a new project to work with both browser and “in Flash” scroll wheel — so I need to toogle it ON and OFF – is that possible??
the project preview – http://www.anzuclub.com/preview/
When the javascript is loaded in the .html the browser scrollwhell don’t work — and when I remove it, i does. (also tried removing the setup call in .as but no difference)
(tested in safari 3.1.2 – mac osx 10.5.5)
THANKS
Juste a BIG THANKS DUDE
all of my website is about a big scroll (yes like html style…)
i first made it in as2 when i saw that the wheel mouse doesn’t work on mac !!!!!!
then i just spent 2 days to do it in as3 when i was just a shit in as2 …but it’s work !!!!
THANKS A LOT
I love the class, but it seems to crash my browser every now and then. Anyone else have this issue? Using FF3 on mac, loading swf with class into a container swf.
I can’t get it to work. I’m using SWFObject2.1 instead of 2.0 (and SWFAddress 2.1) are there known compatibility issues? I’m a newby at this, so I probably made a mistake somewhere, but you never know…
Please ignore my previous comment, I made a mistake in the path to the javaScript. Happy to report it works with SWFObject2.1
what the hell is that script ?!?!
it’s not working at all. i get errors each time i scroll in safari 3 and firefox 3 on mac.
“obj is null” on line 41.
Hi!
Thanks a bunch for the script!
Works fine for me in the following cases:
Windows XP IE 7.0.5730.13
Windows XP Firefox 3.0.3
Windows XP Opera 9.60
OSX Safari 3.1.2 (5525.20.1)
OSX Firefox 3.0
Not on OSX Opera 9.60 though. Too bad because that’s our main browser at home.
P.s. I’m using SWFaddress with SWFobject 1.5 because 2.1 doesn’t seem to work with the former.
Seems as if the hour ring isn’t right on windows xp …
the current time is 2pm (1400) but the ring is bearly 1/4 around.
Hey guys! I might not be getting this right, but..
Turning on this mousewheel hook captures mouse wheel events on the whole page. A small fix can make a check on the event target and filter only events above the Flash instances that were set up. Here it is:
diff swfmacmousewheel_src.js swfmacmousewheel_src.js.orig
12c12
var swfmacmousewheel = function()
39,42d38
Works with Safari and Firefox on the mac. And I’ve just noticed Opera generates mouse wheel deltas upside down.
Strip_tags thing in Wordpress cut all my pretty diff lines. Anyhow, you should add this into the beginning of the deltaDispatcher function:
for(var i=0; i
This is getting ridiculous
I’ll try one last time:
for(var i=0; i < regObjArr.length; i++ )
{
if(event.target.id != regObjArr[i]) return;
}
Hi there.
I’m using the plugin, and keep having the same event fire twice. Has anyone else had this problem?
HI, I’ve got a problem. If the js, the html and swf are in the same folder there’s no problem but if the html and the swf are in different folders your script doesn’t work. ;(
In my case:
swfobject.embedSWF(“http://engine.controlweb.me/flash/3041.versionadv.com/template.kreativo/3041/layout.swf”, “flashcontent”, “1000″, “700″, “9.0.0″, “”, flashvars, params, attributes);
The html is http://3041.versionadv.com/
Can you help me?
i wasnt able to get this to work with safari on windows so i cobbled this straightforward example from various different sources on the net:
[code]
//goes in your head tag:
function handle(delta) {
swfobject.getObjectById(swf's id
').flashScroll(delta);
}
function wheel(event){
var delta = 0;
if (!event) event = window.event;
if (event.wheelDelta) {
delta = event.wheelDelta/120;
if (window.opera) delta = -delta;
} else if (event.detail) {
delta = -event.detail/3;
}
if ( delta != 0 ) handle(delta);
}
//alert("window.addEventListener: "+window.addEventListener);
if (window.addEventListener){
window.addEventListener('DOMMouseScroll',wheel, false);
window.onmousewheel = document.onmousewheel = wheel;
}
//the as3:
package {
import flash.external.ExternalInterface;
import flash.events.*;
import flash.display.InteractiveObject;
public class MouseWheelReceiver {
private var _target;
public var successful:Boolean;
private var currentScroll:Number;
private var currentItem;
private var clonedEvent;
public function MouseWheelReceiver( __target=null ){
_target= __target;
successful = ExternalInterface.available;
if( successful ){
ExternalInterface.addCallback("flashScroll", setScroll );
target.stage.addEventListener( MouseEvent.MOUSE_MOVE , getItemUnderCursor );
}
}//fn
private function getItemUnderCursor( evt ) {
var thisItem= evt.target;
if( thisItem !== currentItem ){
currentItem= InteractiveObject( thisItem );
clonedEvent = MouseEvent( evt );
}
}//fn
private function setScroll( delta:Number ):void{
var wheelEvent:MouseEvent = new MouseEvent(
MouseEvent.MOUSE_WHEEL,
true,
false,
clonedEvent.localX,
clonedEvent.localY,
clonedEvent.relatedObject,
clonedEvent.ctrlKey,
clonedEvent.altKey,
clonedEvent.shiftKey,
clonedEvent.buttonDown,
int( delta )
);
currentItem.dispatchEvent( wheelEvent );
if( currentItem.hasOwnProperty( 'scrollV' ) ){
currentItem.scrollV += -delta;
}
}//fn
public function get target() { return _target; }//fn
}//cls
}//pkg
[/code]
Still doesn’t work in Safari 3.0.3 under win32
Does not work on Win Vista Safari 3.2.1
If someone receives errors I’d recommend to wrap the code inside the _externalMouseEvent function as follows:
if ( _clonedEvent != null && _currItem != null )
{
…
}
If you have a blank background in your swf those variables may be null.
Dead set easiest method to implement – nice work!
A gotcha I came across recently with using swfmacmousewheel with swfaddress is you must load the scripts in a specific order or one or the other may not function:
Also, when working in Flex, I found that it’s safer to do a project clean whenever you modify the html wrapper otherwise you may drive yourself slightly nuts.
And finally a question for you all – I have a TextArea within a Canvas within a ViewStack. The ViewStack doesn’t scroll with the mousewheel if the cursor is over the Canvas (I’ve set vericalScrollPolicy=off on both Canvas & TextArea).
If I set mouseChildren=false on the Canvas, the ViewStack scrolls fine. But this disables the ability for people to select the text in the TextArea which I’d like to retain.
Any suggestions?
bugger – forgot the code markup:
and just in case I got that markup wrong…
1) swfobject.js
2) swfmacmousewheel2.js
3) swfaddress.js
solved it.
FYI: added a mousewheel event handler to the TextArea – this.dispatchEvent(event)
Hi, thanks for sharing this, its a very cool project.
Once issue I seem to have is that it breaks mouse wheel support on the browser window, so you can’t scroll up and down the browser when your cursor is over flash content, all the mouse events are passed to flash. Is there any way to fix this? For instance once the display list has been traversed and if no mouse wheel events need passing through could the javascript be temporarily disabled to check the main browser window so it can scroll if it needs to?
-T.
Hi all – thanks for the great bit of code – been using it for a while – and ran across a couple other threads, and implementations of mousewheel support for Flash on Macs. I had started using this a while back and have added several tweaks to fix most of the issues people have had with it. Specifically if you register multiple SWFobject ID’s on a page my changes only dispatch the mousewheel event to the items that were registered, and only the current id being actively scrolled. It also prevents the null object on PC’s without having to put an explicit check on the page when you attach it, as well as checking for Safari on PC’s and making that work. Those seemed to be the biggest issues.
Feel free to grab it from here: http://www.impossibilities.com/v4/publications/downloads/
Robert>> Since you’re relying on the modified version i made some time ago (see my post somewhere up in the comments), for the PC safari fix to work, you need to provide the modified .as and put a flash var as explained in the readme.txt of my rar file, otherwise it’ll not work with just the .js modification.
Be sure to cast a vote for the bug itself in the Adobe bug tracker:
http://bugs.adobe.com/jira/browse/FP-503
I just wanted to point out that if you are trying to use the AS2 version, you will have to develop this on a Windows machine to be able to test the scrolling “in Flash”. If you are on a Mac you have to test it in a browser.
You’re a genius. Works great!
Found one teeny tiny bug. If you try to use the mouse wheel before the flash object grabs focus an error is thrown.
It can be fixed by checking in function _externalMouseEvent
if(_clonedEvent == null) return void;
There’s probably a more elegant fix, but that was a quick one I found.
This was the error:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at com.pixelbreaker.ui.osx::MacMouseWheel/_externalMouseEvent()
at Function/http://adobe.com/AS3/2006/builtin::apply()
at flash.external::ExternalInterface$/_callIn()
at ()
I noticed others have the problem with the mouse wheel feature being disable on the browser level when using this plugin. This little piece of code should fix that.
Replace the for loop inside deltaDispatcher to:
for(var i=0; i
Hi. I have a problem here. When I import the MacMouseWheel class nothing shows when i view my site in my browser (Safari 4b and Firefox 3.0.7 both os x). Anyone knows why that is?
When I use safari 4 and scroll there seems to be some kind of extra acceleration when compared to Firefox and Internet Explorer?
Do you have this issue too? And how can it be solved?
Never test local. A whole day of trying to fix my problem only to find out that it works perfect online.
Same problem here dedser, only your comment saved me 3/4th of my day. Publishing to Safari, Firefox, etc with the class imported and implemented caused the SWF to not play. I could see that the SWF and javascript were loaded via the activity monitor, but nothing was being displayed in the player.
Could someone explain why we cannot test the class/javascript locally? I understand why the class won’t work in the local Flash Player…no javascript needed to play the SWF, but why not the local browser?
Other than that…life saver. Great utility class, so easy to use on the AS3 side. Anyone heard any Adobe plans to remedy the oversight?
…it’s a security setting in the flash player. I did not receive the normal security warning about the “Flash Player has stopped a potentially unsafe operation”, but my colleague did.
Get to your Global Security Settings for Flash Player (http://www.macromedia.com/support/documentation/en/flashplayer/help/settings_manager04.html OR just right click on your browser flash player and click Privacy>Advanced) Make sure that the location you are testing from is ‘trusted.’ This has to be done to make sure that your HTML and js can communicate correctly.
Thanks again for the mouse wheel class. Great stuff!
man… this thread is getting loooong. Anybody else finding conflict w/ ’swffit’? I can only seem to get one two work at a time.
hi, there!
great work, but are there any news on the subject of scrolling the rest of the page:
Tadhg: “Once issue I seem to have is that it breaks mouse wheel support on the browser window, so you can’t scroll up and down the browser when your cursor is over flash content, all the mouse events are passed to flash. Is there any way to fix this? For instance once the display list has been traversed and if no mouse wheel events need passing through could the javascript be temporarily disabled to check the main browser window so it can scroll if it needs to?”
@Michael
Hey there. I managed to get this working with an AS2 website.
Try this:
var flashvars = {};
var params = {};
params.scale = “noscale”;
params.wmode = “window”;
params.allowfullscreen = “true”;
var attributes = {};
attributes.id = “coop”;
swfobject.embedSWF(“FLUID.swf”, “myContent”, “100%”, “100%”, “9.0.0″, “expressInstall.swf”, flashvars, params, attributes );
swfmacmousewheel.registerObject(attributes.id);
Then modify your Flash as described in the older AS2 version of macMouseWheel.
Drop me a mail if you need help. chewydragee44 [at] yahoo.co.uk
Hello! Could you please confirm that SWFMacMouseWheel is licensed under the MIT license?
Thanks!
Claire
It seems that there is a problem getting the right values for the crtlKey, altKey and shiftKey properties in the event dispatched by MacMouseWheel. If you press e.g the alt key while not moving the mouse and then start scrolling (still not moving the mouse) the altKey property on the mouse event is not correct.
Looking at the code this makes perfect since MacMouseWheel captures the _clonedEvent (which is effect is the event that is received by the application) on mouse moves only. I fixed the problem by adding key down and up event listeners to MacMouseWheel and letting the event handlers modify the current _clonedEvent.
See the source code below.
Feel free to add these fixes to your code.
Thanks,
Jimmi
private function _keyDownHandler(event:KeyboardEvent):void {
switch(event.keyCode) {
case Keyboard.CONTROL:
_clonedEvent.ctrlKey = true;
break;
case Keyboard.SHIFT:
_clonedEvent.shiftKey = true;
break;
case 18:
_clonedEvent.altKey = true;
break;
}
}
private function _keyUpHandler(event:KeyboardEvent):void {
switch(event.keyCode) {
case Keyboard.CONTROL:
_clonedEvent.ctrlKey = false;
break;
case Keyboard.SHIFT:
_clonedEvent.shiftKey = false;
break;
case 18:
_clonedEvent.altKey = false;
break;
}
}
Hi!
Thanks for this great add on!
Do you think it is possible to add support for the two finger scroll feature? So that one can do diagonal scroll?
That would be awsome.
Best Regards..
Gabriel, you rock!!
Am I missing something that this solution does not dispatch MOUSE_WHEEL events for the stage?
Hi, I have a fix to the scroll wheel disabling all the mouse wheel events. I tried posting it here a couple of months ago, but it looks like it never made it into the comments. Click on my name for the link to my site.
Sandro
Hi,
Just noticed that the new safari 4 (not the beta) doesn work well with macMouseWheel.
I get little or no delta action when scrolling.
Just so you know, great work.
if (swfmacmousewheel) { swfmacmousewheel.registerObject(attributes.id); }
as swfmacmousewheel returns null if !mac, there is no .registerObject function. so check if swfmacmousewheel is != null before.
This works well in firefox, but on safari 4 on a mac the delta value is less than normal. For example the delta value range is only -1 – 1. Not any higher? I’m using the lastest swfobject. But your test doesn’t work very well in safari 4.
Any ideas?
yep, safari 4 is wonky.
yes i believe, its ok …..
Oh noes. My pixels. They’re going to break :[
As far as I know Firefox 3.5 introduced some changes in the javascript engine, that could cause the problem. Don’t know if that’s the same for Safari 4.0?
Does anyone know the what licensing there is for this code, and where I could find documentation of it? I would like to use it in a commercial application, but need to know if it’s open source and if it’s under the MIT license (same as SWFObject) or any other license that states that this use of it is permitted.
Thanks!
As far as I know Firefox 3.5 introduced some changes in the javascript engine, that could cause the problem. Don’t know if that’s the same for Safari 4.0?
Hello! Could you please confirm that SWFMacMouseWheel is licensed under the MIT license?
Thanks!
I am like the 2nd that commented: “God bless you, your children, the children of your children for this wheel thing
”
DIE HTML DIEEEE
)
Hi – it’s been asked several times already but can you please confirm the licence for this code. I assume as it’s an addon for SWFObject that it is also MIT licenced but I need to know for sure in order to be watertight legally.
Thanks very much
I would like to use it in a commercial application, but need to know if it’s open source and if it’s under the MIT license (same as SWFObject) or any other license that states that this use of it is permitted.
It is very interesting post. I got lot of information here.
is that on windows? if so, i should clean that up, at present, if the OS is not a mac, it returns a null object as swfmacmousewheel.
I’ve been trying to implement your script on my site, but it doesn’t seem to work very well on an Intel Mac in both Safari and Firefox using Flash player 10. (It might be problematic in other browsers, player versions, and OSes too. I don’t know).
The problem is two-fold:
1. It takes a LOT of scrolling to get it to fire any delta value. More so than should be required. I need to practically finger-flick the wheel as hard as I can before it responds.
2. The delta value never goes back to zero when I stop scrolling. (i.e.: If I scroll down, then the delta will always remain -2, -3, etc… It will never stop scrolling).
I’ve tried with two separate mice and the trackpad on my laptop.
I’m using SWFObject 2.0 and the same exact code you’re using in your examples. I would love to hear back from anyone who might have a solution.
Thanks,
Darren
It takes a LOT of scrolling to get it to fire any delta value. More so than should be required. I need to practically finger-flick the wheel as hard as I can before it responds.
So I solve the mousewheel prob with your great work and a few tricks, because I use Flex 3. I took your zip and put the com-package in the src and the js-package to the html-templates, then I open index.template.html and configure the following lines:
Code:
after the style declaration
then:
Code:
if (navigator.appVersion.indexOf(“Mac”)!=-1) {
var flashVars = {};
var params = { play: “true”,
loop: “false”,
quality: “high”,
wmode: “window”,
allowscriptaccess: “sameDomain” };
var attributes = { id: “${application}” };
swfobject.embedSWF( “${swf}.swf”,
“divContent”,
“100%”, “100%”,
“9.0.0″,
“expressInstall.swf”,
flashVars,
params,
attributes );
swfmacmousewheel.registerObject( attributes.id );
}
for the right OS and the in the main app:
Code:
xmlns:local=”*”
…
addedToStage=”onAddedToStage()”
>
Looks like it is breaking in the beta Flash Player 10.1
’swfmacmousewheel’ is null or not an object