hasseg.org

Mac OS X Mouse Wheel Support for ActionScript 3 Flash Applications (v.2+)

Filed under ActionScript 3, Flex, Mac, Programming

AS3 Mouse Wheel support picture So I've finally updated the solution I've made earlier for enabling Mac OS X mouse wheel support in Flex applications to a second version. I didn't want to continue adding stuff into the original post, so I decided to write a separate post just for this new version. As you can see from the title, this version should work in any Flash project you're writing in ActionScript 3, as opposed to just in Flex projects. This change was contributed by Pavel Fljot, and all the other stuff I've added since have been added on top of that. Deployment should now be a lot easier and some features that were missing in the first version have also been added.

Changelog

First, here is an itemized list of what has changed:

Determining the InteractiveObject to dispatch the mouse wheel event

Like mentioned in the changelog above, I've added an another method for finding the InteractiveObject on stage and under the mouse cursor that should dispatch the mouse wheel event when one is sent from the JavaScript end. This is based on the solution to this same issue Gabriel Bucknall has come up with at pixelbreaker.com. My solution basically went through the whole display list hierarcy every time a mouse wheel event had to be dispatched, trying to find mouse-enabled InteractiveObjects that were under the mouse cursor, and then asked the topmost of these to dispatch the MouseEvent. Gabriel's solution was to attach a MouseEvent.MOUSE_MOVE event listener to the Stage and keep a reference to the object that was the target for the last such event, and then use that reference to ask this object to dispatch the mouse wheel event whenever required.

Now, the main difference between these two solutions, I've found, is that Gabriel's is faster but inaccurate in some border cases, while mine is slower but more accurate. The slowness of my solution is very clear if you understand the amount of processing that goes on whenever the user starts rolling the wheel: for each event, the application needs to go through the whole hierarchy of objects on the Stage, find InteractiveObjects that are under the mouse cursor, mouse-enabled and visible, and then find the one of those that is deepest in the display list. Gabriel's solution doesn't need to do any of this: it already has the InteractiveObject reference it wants to use at this point. The inaccuracy, on the other hand, stems from the fact that if the user doesn't move their mouse, the reference won't get updated. What this means is that if the InteractiveObjects on Stage have moved (in relation to the mouse cursor,) or been added to or removed from the display list while the cursor has stayed put, the reference will not be up to date, and probably incorrect.

As you've probably deduced from the last paragraph, there are upsides and downsides to both of these approaches, and I at least would like to be able to choose which one to use, based on the context of what I happen to be doing at the moment. This is why I've added this exact feature into the code in the form of a property the value of which you can set at will:

private var _mwSupport:ExternalMouseWheelSupport = ExternalMouseWheelSupport.getInstance(stage);

_mwSupport.dispatchingObjectDeterminationMethod = ExternalMouseWheelSupport.COPY_MOUSEMOVE_EVENTS; // or _mwSupport.dispatchingObjectDeterminationMethod = ExternalMouseWheelSupport.TRAVERSE_DISPLAY_LIST;

You can test the differences between these two options with the demo.

Deployment and use

So like I wrote before, the process of deploying and initializing this solution has changed a bit from the last version. This is how you do it now.

  1. Include the JavaScript file onto the page that embeds the Flash object(s)
  2. <script type="text/javascript" src="./extMouseWheel.js"></script>



  3. Make sure your embedded Flash objects have a parent div element
  4. <div style="width:600px;height:600px;" id="flashContainerDiv">
      <!-- add Flash object's <object> and <embed> tags here -->
    </div>



  5. In your AS3 code, get a reference to the singleton instance of ExternalMouseWheelSupport in at least one place
  6. As you can see, the singleton instance accessor is not a property anymore, but a method, so that you can pass a reference to the Stage to it. This change is because of the removal of dependencies to Flex libraries, which could be used to access the Stage instance in the previous version.
    import org.hasseg.externalMouseWheel.ExternalMouseWheelSupport;
    private var _mwSupport:ExternalMouseWheelSupport = ExternalMouseWheelSupport.getInstance(stage);
    
    I generally do this in the applicationComplete event handler, but you can of course call it wherever you want, as long as you make sure the Stage reference you're using is not null (an Error will be thrown if it is.)

...and that's it. :)

Downloads and demo

This code is licensed under the MIT License.

Other info

I've tested this solution with the following browsers (sadly, Opera on the Mac isn't supported since ExternalInterface doesn't seem to work in the latest version:)

If someone could please test this on the Mac OS version of Firefox 2 and the Windows versions of Firefox 3 beta and IE 6, I'd very much appreciate it.

75 Comments

Mousewheel support for Flex and AS3 Flash projects | The Flashchemist April 27, 2008 at 11:12 AM

[…] OSX (Tiger +) desktops for Flex projects. Flex doesn’t support it natively. Finally got this interesting post and a utility which will do it for not just Flex, but any projects which is made of AS3. […]

raf April 28, 2008 at 3:36 AM

works great, thanks for that. just need to find a way to make the wheel support work when i set wmode to transparent when using firefox then would be perfect!

Le blog de Vincent Battaglia » Flash et problèmes de compatibilité ! April 30, 2008 at 12:59 AM

[…] pas sur Mac ! Il a donc fallu utiliser un bon vieux hack ! L’explication du hack se trouve sur ce blog. En résumé, il faut, d’une part, importer une librairie dans le fichier Flash et […]

negro May 21, 2008 at 5:44 PM

thanks for your mousewheel class. could you please give an example on how to use it in flash as3 and not flex? the current embedding through a object tag isn’t that useful. what would it take to make it work with swfobect 2.0? thanks for your help.

Ali Rantakari May 21, 2008 at 7:01 PM

Hi negro,

I Don’t have Flash CS3 so I can’t be sure – maybe someone else who is reading this and who has the Flash authoring software could help you out better, but I’ll do my best:

The initialization of the mouse wheel support should work exactly the same as in step three of “deployment and use”. The only thing I can’t say is where to put this code in pure AS3 projects, though. It should be ran when the application initializes and the stage reference is available.

I’m currently using this with swfobject 2.0 in the main app I’m working with at work and no extra effort is required to make it work.

Just import the JavaScripts:

<script type="text/javascript" src="js/swfobject/swfobject.js"></script>
<script type="text/javascript" src="js/extMouseWheel.js"></script>

And then, when you use swfobject to embed your .swf, it runs, gets initialized, and if everything has been implemented on the Flash side (in this .swf you’re embedding,) it should work.

negro May 21, 2008 at 7:33 PM

thanks for your reply. i managed to make it work on an as3 file but there is a big problem to make it work with swfobject. as a test i changed the flash embedding syntax of your example.html to the dynamic swfobject embedding. sadly it doesn’t work. could you maybe look at the code and tell me what i’m doing wrong? thanks again.

in the head tag:

		var flashvars = {};
		var params = {};
		var attributes = {};
		swfobject.embedSWF("mwdemo.swf", "myAlternativeContent", "600", "600", "9.0.0", false, flashvars, params, attributes);

in the body tag:

		<a href="http://www.adobe.com/go/getflashplayer" rel="nofollow">
			
		</a>
negro May 21, 2008 at 7:34 PM

sorry it stripped away all the code. i will send it through email, or what’s the code tag in here?

Ali Rantakari May 22, 2008 at 12:04 AM

negro,

Make sure you have a parent DIV element for whichever temporary element you’re replacing with swfobject (id==“myAlternativeContent”). Like in point two under “deployment and use”.

Good point about the code tag – what an idiot I am, I’ve forgotten to add a note about that below the reply textarea. Well, I just added it there so see below for more info.

negro May 22, 2008 at 10:46 AM

ali, i really appreciate how quick you’re answering. please excuse my inabilty to make this work with swfobject. below you can see the code i’m using, could you pleasen tell me what i’m doing wrong? thanks.

in the header tag:

<script type="text/javascript" src="swfobject.js"></script>
<script type="text/javascript" src="extMouseWheel.js"></script>
<script type="text/javascript">
	var flashvars = {};
	var params = {};
	var attributes = {};
	swfobject.embedSWF("mwdemo.swf", "myAlternativeContent", "600", "600", "9.0.0", false, flashvars, params, attributes);
</script>

and in the body tag i have this:

<div id="wrapper">
	<div id="myAlternativeContent">
		<a href="http://www.adobe.com/go/getflashplayer">
			<img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif"  alt="Get Adobe Flash player"  />
		</a>
	</div>
</div>
negro May 22, 2008 at 10:49 AM

ali, i’m really sorry, i didn’ want to spam your comments! put it never displayed my answers until i’ve added this very last comment. please delete everything except comment 10. again sorry but it looks like there’s a small problem with the codecolorer plugin.

Ali Rantakari May 22, 2008 at 1:07 PM

I edited your comment to include the body tags you tried to post earlier as well – I hope that’s okay.

Everything there looks fine to me, I can’t see any obvious problems. I think we should continue this conversation via email – I’ll send you the wrapper HTML (with the relevant javascript) I’m using so you can check if any differences between the two will guide you to the right direction.

Kapil June 2, 2008 at 1:24 PM

Hi,

I started to use the solution, but was not able to deploy it successfully. This is what I had done:

  1. Put in the JS and also the location to the JS my HTML template

  2. I put a div around the object as:

  3. I put in the ActionScript in my main application MXML.

The wheel support does not work. When I started to debug the code, i noticed that in the function “initJSConnection”, i get a false for “_initialized = ExternalInterface.call(“extMouseWheel.initCaptureFor”, ExternalInterface.objectID);”.

Can you help me on this one.

Thanks in advance

Ali Rantakari June 2, 2008 at 1:53 PM

Hi Kapil,

A quote from the API docs of ExternalInterface:

“For local content running in a browser, calls to the ExternalInterface.call() method are permitted only if the SWF file and the containing web page (if there is one) are in the local-trusted security sandbox. Also, you can prevent a SWF file from using this method by setting the allowNetworking parameter of the object and embed tags in the HTML page that contains the SWF content."

from: http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/external/ExternalInterface.html#call()

So first I’d check if any security sandbox features are blocking the ExternalInterface calls. The best way to do this is to use the Debug version of Flash Player, enable logging, try it out, and then check the log: http://www.adobe.com/devnet/flex/articles/client_debug_print.html

Then I’d check the JavaScript log for errors. All modern browsers have this (develop > show error console in Safari, tools > error console in Firefox.)

Since extMouseWheel.initCaptureFor is returning false, though, instead of null, the problem is probably that the JavaScript can’t find your flash object’s parent div. Are you sure your flash object (the object and embed tags) has the “name” and “id” properties set (to the same value?) It has to, for this to work. Maybe I should add a mention of that into the post…

Let me know via email if it isn’t working.

Kapil June 2, 2008 at 4:54 PM

I finally got this working with the following tweaks:

  1. I was using the HTML template that Flex provides with support enabled for history. The template has a tag for and . That was leading to rendering the parent “div” incorrectly and hence the script was breaking. I have not yet looked what else could be breaking - have that planned over next few days.

  2. Also, I noticed that we need to write code to make scrolling working for individual controls like for a TextArea - we need to handle MouseEvent.MOUSE_WHEEL and then increment / decrement the “Vertical scroll”. This means that all over in my application, I will have write some snippets or override controls to provide this functionality. Is there not a better way of doing this? 2.1. I saw the version 1.x and found that there was a way to register controls that we needed to add to this. or is there a better way?

Ali Rantakari June 2, 2008 at 6:51 PM

Hi Kapil,

Good to hear it works for you now. I’ll try to answer the couple of questions you posed as best as I can:

2: Yes, that’s a known issue. The TextArea Flex class is a wrapper for an UITextField instance, which is a grandchild of TextField. TextField is a “native” (i.e. non-Flex) class (it’s in the package flash.text,) which makes its implementation of the mouse wheel functionality unknown (at least to me.) The ExternalMouseWheelSupport singleton will make the UITextFields wrapped by TextAreas dispatch MouseEvent.MOUSE_WHEEL events when you scroll the wheel on top of them but unfortunately it isn’t doing any good because apparently there’s no event listener listening for those evens and acting on them – the mouse wheel functionality seems to be implemented in some other (more native?) way in the TextArea class (or somewhere else.) If you look at the mx:TextArea source code, you’ll notice this:

/**
 *  @private
 *  Mouse wheel scroll handler.
 *  TextField scrolls automatically so we don't need to handle this.
 */
override protected function mouseWheelHandler(event:MouseEvent):void
{
    event.stopPropagation();
}

The solution I’d suggest for your situation, based on how it sounds from how you’re describing it, would be to create a subclass of mx:TextArea where you’d add your own mouse wheel handler and related functionality for initiating scrolling, and then use instances of this class instead of mx:TextArea within your app.

2.1: The concept of registering and unregistering objects for mouse wheel support is not relevant anymore in this version. Using these terms, you could say that all objects on stage are “registered”. So unless you’re using the older version, you can forget about this registration thingamabob entirely. :)

Kapil June 2, 2008 at 8:36 PM

2 & 2.1: So it seems that some controls i would need to subclass to make them work with mousewheel - simply because adobe has stopped propogation. I kind of understand, why would they want to stop propogation

1: Any updates on this one?

Ali Rantakari June 2, 2008 at 9:22 PM

Kapil:

I’m not sure what the question was for #1 ?

Also, it seems you had typed in some html tags, which were removed by the blogging software. You can use the cc tags described below to type in blocks of code, or you can type html tags inline into the comments like this:

&lt;tag&gt;hello&lt;/tag&gt;

(output: <tag>hello</tag>)

Anton Pieter van Grootel June 3, 2008 at 9:18 PM

Seems to work on my Mac with Firefox 2.0.0.7

Anton Pieter van Grootel June 4, 2008 at 1:07 PM

Hi Ali and Negro,

First of all, great work!

I have the exact same problem Negro has, using swfObject. Any insights on that?

Thanks.

Ali Rantakari June 4, 2008 at 10:12 PM

Hi Anton,

I Emailed Negro the example of how I’ve had this set up with swfobject 2.0 in a project of mine and he told me he got it working based on that. I’m not sure what the problem might be, but maybe it has something to do with the sizing of the flash object – I’ve been setting its width and height to 100% so that it would fill the whole container div, and it has worked for me without any problems so I haven’t investigated further. Here’s the example:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
	<title>example</title>
	
	<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
	
	<script type="text/javascript" src="js/swfobject/swfobject.js"></script>
	<script type="text/javascript" src="js/extMouseWheel.js"></script>
	
	<script type="text/javascript">
		
		var attributes = {
			id: "xxxFlash",
			name: "xxxFlash"
		};
		swfobject.embedSWF("xxx.swf", "myContent", "100%", "100%", 
							"9.0.0", null,null, attributes, attributes);
		
	</script>
	
</head>
<body>
	<div id="flashContainerDiv" style="width:100%;height:100%;">
		<div id="myContent" style="width:100%;height:100%;">
			<p>You need to install <a href="http://www.adobe.com/shockwave/download/download.cgi?P1_Prod_Version=ShockwaveFlash">Flash Player</a> (version 9 or later) in order to use xxx.</p>
		</div>
	</div>
</body>
</html>

If you figure out what the problem is and have any insights on how the JavaScript (and/or the ActionScript) could be modified to avoid it in the future, please do share.

Thomas June 5, 2008 at 3:05 AM

Has anyone successfully implemented this with a ListBase component or subclass thereof? I’m having a heck of a time trying to get this external mouse wheel functionality to work with a TileList. I subclassed the TileList and overrode the mouseWheelHandler like so:

		override protected function mouseWheelHandler( event : MouseEvent ) : void
		{
			//super.mouseWheelHandler( event );
	        if (verticalScrollBar && verticalScrollBar.visible)
	        {
	            var oldPosition:Number = verticalScrollPosition;
	            var newPos:int = verticalScrollPosition;
	            newPos -= event.delta * verticalScrollBar.lineScrollSize;
	            newPos = Math.max(0, Math.min(newPos, verticalScrollBar.maxScrollPosition));
	            verticalScrollPosition = newPos;
	
/* 	            if (oldPosition != verticalScrollPosition)
	            {
	                var scrollEvent:ScrollEvent = new ScrollEvent(ScrollEvent.SCROLL);
	                scrollEvent.direction = ScrollEventDirection.VERTICAL;
	                scrollEvent.position = verticalScrollPosition;
	                scrollEvent.delta = verticalScrollPosition - oldPosition;
	                dispatchEvent( event );
	            } */
	            
	            dispatchEvent( event );
	        }

No luck though so far. Anyone have any ideas?

Robert Wünsch July 4, 2008 at 2:31 PM

The behaviour in Internet Explorer 7 and Firefox is that while scrolling through some elements, the whole page will be scrolled, too.

Page scrolling happens when scrolling:

  • While mouse is above any flash content without flash in actual focus.
  • While mouse is above flash combobox or slider with flash in actual focus.
Pri August 26, 2008 at 6:04 PM

First of all, thanks for providing this tutorial, however I can’t get it to work. When I load the sample app from your site, it works well! However downloading the source code and running the program, I simply get no errors and see the following:

External mouse wheel support not initialized. This usually means that it is simply not needed (i.e. if running in Windows Flash Player in a browser other than Safari.)

Any help is appreciated. Thanks!

Pri August 26, 2008 at 6:05 PM

Ideally, i only want the global application to scroll. I dont’ mind if the internal components dont’ scroll with the mouse scrollwheel.

Thanks,

Ali Rantakari August 26, 2008 at 6:36 PM

Hi Pri,

The first thing I would check is whether the Flash Player security sandbox features are blocking the ExternalInterface calls: if you’re running the app from the local filesystem, try setting the path as trusted in the Flash Player global security settings, or alternatively try running the app on a web server (localhost or remote).

I found this by googling for “externalinterface local filesystem”: http://www.judahfrangipane.com/blog/?p=215

Taro September 29, 2008 at 9:13 PM

Hey Ali, after trying all day to get the mouse wheel to work with my flex application, at last it works!! Thank you very much for this solution. I had the same problem as Pri, I was using the standard html-template generated by Flex and it didn’t work until I deleted the AC_OETags.js -Script that is also embedded there that is used for Version-detection etc. There seems to be a conflict between those two scripts though I am not sure why. Do you have any idea? Cheers, Taro

Ali Rantakari September 29, 2008 at 11:54 PM

Hi Taro,

I Don’t use Flex Builder myself (I just use the Flex SDK and edit my code with jEdit), so I can’t debug that kind of a problem very easily. I’ll try to see if I can figure out what the problem might be if I happen to have time in the near future, but no promises :/

If anyone else has a solution for this that entails changing the AS3/JS code I’ve posted here, please let me know.

devon October 1, 2008 at 5:10 AM

so good, so easy, so grateful!

negro October 3, 2008 at 10:32 AM

hello to all flash users that want to implement this class. i found the solution to make this work since a long time now but i completely forgot to give that knowledge back to you .

in fact the solution is simple and logic. the class needs to be able to identify the flash object. this means you have to give your flash the same id and name attribute.

in swfobject 2 it looks like this:

var flashvars = {};
var params = {};
var attributes = {};
attributes.id = "myName";
attributes.name = "myName";
swfobject.embedSWF("flash.swf", "myFlashContent", "800", "600", "9.0.0", false, flashvars, params, attributes);

besides that just follow the instroctions of alis docs (container div, etc).

i hope this helps everybody

Van October 23, 2008 at 10:11 PM

Hi, I’ve been using this code and its worked great except it doesn’t seem to work in Firefox 3.0.3 on Windows XP SP2. If anyone has a fix for this please let me know

Ali Rantakari November 4, 2008 at 1:08 AM

Hi Van,

The Windows version of Flash Player supports mouse wheel events out of the box, so this code won’t get initialized there because it won’t be needed. Whatever problem you might be having in FF3 on Windows probably stems from some other issue.

Dan November 22, 2008 at 1:08 AM

I got to work with the file that is auto-generated by Flex Builder 3 (index.template.html).

The trick is as follows….don’t just put a DIV around the OBJECT tag, because the object tag is within a NOSCRIPT tag and does not even get called unless javascript is disabled. Instead, put your div around the SCRIPT tag that programmatically embeds your SWF file.

It’s the script tag that has this line just inside it: // Version check for the Flash Player …

You also have to be accessing your page via a web server, not as a local file, or you’ll get a security error.

Software Artist » Adobe MAX Europe, J-1 November 29, 2008 at 10:42 PM

[…] wonder why things like mouse wheel are not natively supported on the Mac. Fortunately there is a workaround but it’s still a […]

Sudhan December 3, 2008 at 3:36 AM

Dan - Do you have sample code which puts the div around the script tag (programmatically embeds swf).

Thanks,

Dan December 4, 2008 at 2:04 AM

@Sudhan: Just put a tag like this: <div id=“flashInit1”> above the lines in the index.template.html file that say: <script language=“JavaScript” type=“text/javascript”> <!– // Version check for the Flash Player that has the ability to start Player Product Install (6.0r65)

And put a closing: </div> tag after the end of the SCRIPT tag that starts as above.

I remembered that I also had to add the appropriate event listener for the objects that I wanted scrollable. In my case it’s an mx:TextArea called “console”. So I needed this code:

console.addEventListener(MouseEvent.MOUSE_WHEEL, function(event:MouseEvent):void { if (console.verticalScrollPosition-event.delta >= 0) console.verticalScrollPosition -= event.delta; });

For this you need to: import flash.events.MouseEvent;

HTH Dan

Seppe December 17, 2008 at 5:00 AM

Thank you. I was struggling for a while… but it’s working now, turned out to be an issue related to the use of swfobject. Thanks again!

Sudhan January 6, 2009 at 9:34 PM

Dan thanks for your post, but the issue i forgot to mentioned in my earlier post was that. We are using “AC_FL_RunContent” for dynamically embedding flash object. Here is the modification i performed, but does not work either.

document.write(’’); AC_FL_RunContent( “src”, “/swf/index”, “FlashVars”, var1, “width”, “100%”, “height”, “100%”, “align”, “middle”, “id”, “flexObject”, “quality”, “high”, “bgcolor”, “#dddcd6”, “name”, “flexObject”, “allowScriptAccess”,“sameDomain”, “type”, “application/x-shockwave-flash”, “wmode”,“opaque”, “pluginspage”, “http://www.adobe.com/go/getflashplayer" ); document.write(’’);


thanks once again

Sudhan

Kelso’s Corner » Blog Archive » Mac OS X Mouse Wheel Support for ActionScript 3 Flash Applications (v.2+) (Hasseg) January 9, 2009 at 7:46 AM

[…] Continue reading at Hasseg blog . . . SHARETHIS.addEntry({ title: “Mac OS X Mouse Wheel Support for ActionScript 3 Flash Applications (v.2+) (Hasseg)”, url: “http://kelsocartography.com/blog/?p=1427" }); […]

Tip of the Day - Mouse wheel scrolling on the mac | Nate Beck January 10, 2009 at 8:09 PM

[…] Luckily for us, Ali Rantakari has created a solution for this very problem. You can read up about the solution on his post. […]

Helmut February 12, 2009 at 4:10 AM

thanks for the code… I have a flex app which refused to send MOUSE_WHEEL events at all… nothing I did would convince the flash player (on windows xp and xp64) to send ANY mouseWheel events. nothing. then I downloaded your script, hacked the javascript to disable the platform check… and… voila: the flex app now sends mouse-wheel events everywhere (which over time in frantic attempts i had added this to all components to try to get any events)

i have tested other sample flex apps on my computer and mouse-wheel events were never an issue. just with this one a big nothing.

your code now fixed that thanks :)

Flash Mousewheel Scrolling on Mac OSX « shaun smith March 7, 2009 at 2:51 PM

[…] Mac OS X Mouse Wheel Support for ActionScript 3 Flash Applications […]

darscan March 10, 2009 at 2:19 AM

Be sure to cast a vote for the mousewheel bug itself in the Adobe bug tracker:

http://bugs.adobe.com/jira/browse/FP-503

Scrolling with mouse wheel in Flex application - even on Mac at Entrepreneur Geek April 14, 2009 at 3:51 PM

[…] Here’s a detailed blog post and solution to scrolling Flex components / application with mouse wheel - in all…. […]

Steve Kwan April 20, 2009 at 9:05 PM

Thanks a lot for this. I can’t believe Flex doesn’t have consistent mousewheel support across platforms - I thought consistency was one of the big benefits of Flex for RIAs!

Ian Wojtowicz May 1, 2009 at 2:02 AM

Hi.

I was wondering if anyone has successfully managed to modify this code to work with the 2-dimensional scroll wheel on the Apple Mighty Mouse. In many Apple applications you can scroll horizontally as well as vertically.

Has anyone solved this shortcoming of the Hasseg scroll wheel software?

Ian

Randall Doser May 8, 2009 at 11:08 PM

Works great! I actually couldn’t access the stage variable until the updateComplete event, so I’m setting _mwSupport in there, but no other hitches. Thanks for sharing.

Randall Doser May 13, 2009 at 11:48 PM

Just discovered something unexpected with Google Chrome as the browser. When putting the div tag around the flash movie, Chrome won’t fire a resize event when the browser window is resized VERTICALLY (still fires on horizontal resize). My Flex app consumes the entire browser window but the built in container scroll bars don’t adjust properly in this case. Is there a fix for this?

Randall Doser May 14, 2009 at 12:24 AM

Okay, looks like WebKit actually cares about the style=“height:100%;width=100%” attribute in the div tag. Now it is working as expected. Sorry to bother you.

Ian Wojtowicz May 15, 2009 at 7:00 AM

Why is it that this software will enable mouse scrolling on some scrollable panels, but not on others?

Ali Rantakari May 15, 2009 at 2:57 PM

Hi Ian,

That’s probably due to the fact that some components implement scrolling by listening for MouseEvent.MOUSE_WHEEL events (these should work since what this hack does is make the components under the mouse dispatch these events) but others use some unknown (and proprietary to Adobe) method of “tapping into” the Flash Player mouse API or something (these won’t work). See my answer to Kapil’s question (#15) above.

alQemist May 31, 2009 at 3:40 PM

I am evaluating whether to implement this mouse scroll solution and wondering about the impact on memory. Since my Flex app is a business app that is used all day optimizing and managing memory is imperative.

I would hesitate to add any more stress on our memory “battle” - any comments or experience to share on impact to memory.

jeep1024 June 2, 2009 at 11:22 PM

When using the default html wrapper from Flash CS4, adding <div>s around the embedded <object> tags, adding in the components for the Hasseg approach, and using Safari 3.2.3 (on XP), scrollwheel only works when the mouse isn’t over the browser? If the mouse is hovering anywhere within Safari, the scrollwheel doesn’t fire.

Anyone seen this?

Koofka June 16, 2009 at 11:40 PM

First, thanks for the great class.

I did find that the default behavior of the extMouseWheel.js didn’t fit to the progressive scrolling the piece we were working on needed (using tweening for scrolling and have a bit of inertial feel at the moment). This tracked to the setting in the js file var keepDeltaAtPlusMinusThree = true;

Once altered to false, I found that the delta would range as expected (at least in Safari 4 OS X) but for small moves often a delta of 0 would be returned to Flash. This would appear to be due to the rounding from the type conversion of the delta calculation for Safari and the integer values it is being passed as into Flash. Though I am sure this could be done more elegantly, we added a small alteration to the js file to ensure that small scrolling would not return as a 0 delta move:

if (event.wheelDelta)
{
	// Safari
	delta = event.wheelDelta/120;
	if (window.opera) delta = -delta;
}
else if (event.detail) // Firefox
	delta = -event.detail; //*3;

if (keepDeltaAtPlusMinusThree)
{
	if (delta > 0) delta = 3;
	else if (delta == 0) delta = 0;
	else delta = -3;
} else {
	if (delta < 1 && delta > 0) delta = 1;
	else if (delta > -1 && delta < 0) delta = -1;
}

Also Ali, thanks for the guidance on SWFObject, and if its any help this tested out and works under the latest 2.2 release.

Best, -Koof

marcus August 1, 2009 at 12:05 AM

First off, thanks for your contribution.

I have been able to implement this hack without any hitches, but an issue I am right off the bat is the speed at which the mouse wheel is actually scrolling. It scrolls significantly slower and it seems to be a problem with Flex 4 cause I am not having this issue with your example. Any thoughts?

Jon August 26, 2009 at 2:42 PM

Hi, I am having problems getting the mouse wheel event to work on mac in my Flex project, and came across this solution from a Google search.

When I view the solution from the link above, it seems to work perfectly, however I downloaded the source and ran it on my box and it does not work :(

Is there a reason to this, am I doing something wrong, do I need to check / change anything ???

Cheers, Jon.

Jan K October 17, 2009 at 2:56 PM

if you’re looking for a working solution using Flex and SWFObject have a look at this: http://alekkus.com/blog/2009/02/flex-tutorial-enabling-track-pad-or-mouse-wheel-scrolling-on-mac-os-x/

Tristan October 23, 2009 at 8:53 PM

For those wondering about swfobject support (again) here’s how I got it working.

You actually have to nest it in two DIVs, because for some reason SWFObject replaces the div you assign it to. Also, you have to name the swf in the attributes so it’s referencable by extMouseWheel.js.

Here’s the code: …

	<script type="text/javascript" src="swfobject.js"></script>
	<script type="text/javascript" src="extMouseWheel.js"></script>
	<script language="JavaScript" type="text/javascript">
		var flashvars = {};
		var params = {};
		var attributes = {
		    id: "myswf",
		    name: "myswf"
		};
			
		swfobject.embedSWF("${swf}.swf", "swfreplace", "${width}", "${height}", "10.0.0", "expressInstall.swf", flashvars, params, attributes);
	</script>

And the HTML (hope this works) …

<body scroll="no">
	<div id="swfcontainer" name="swfcontainer">
		<div id="swfreplace"></div>
		<p><a href="http://www.adobe.com/go/getflashplayer"><img src="http://www.adobe.com/images/shared/download_buttons/get_flash_player.gif"  alt="Get Adobe Flash player"  /></a></p>
	</div>
</body>
MIchael December 18, 2009 at 9:28 PM

Hello all! You guys are way better at this than me. Can anyone how I need to alter the HTML below to make it work?

      <!-- This param tag prompts users with Flash Player 6.0 r65 and higher to download the latest version of Flash Player. Delete it if you don’t want users to see the prompt. -->
      
      <!-- Next object tag is for non-IE browsers. So hide it from IE using IECC. -->
      <!--[if !IE]&gt;-->
      
        &lt;!--
        
        
        
        
        <!-- The browser displays the following alternative content for users with Flash Player 6.0 and older. -->
        
          Content on this page requires a newer version of Adobe Flash Player.
          <a href="http://www.adobe.com/go/getflashplayer" rel="nofollow"></a>
        
        <!--[if !IE]&gt;-->
      
      &lt;!--

var gaJsHost = ((“https:” == document.location.protocol) ? “https://ssl.” : “http://www.”); document.write(unescape("%3Cscript src=’” + gaJsHost + “google-analytics.com/ga.js’ type=‘text/javascript’%3E%3C/script%3E”));

try { var pageTracker = _gat._getTracker(“UA-10307333-1”); pageTracker._trackPageview(); } catch(err) {}

Ali Rantakari December 18, 2009 at 11:58 PM

Michael,

Use the cc tags (see below for an example) to post some HTML. Use “html” as the lang parameter.

Mikko February 2, 2010 at 11:49 PM

Hi,

Excellent work!! One question though: the scrolling speed is a bit slow. Is there a way to change the scroll amount/speed?

Mikko

Ali Rantakari February 3, 2010 at 12:34 AM

Moi Mikko,

You could set the keepDeltaAtPlusMinusThree boolean (in the javascript file) to false, maybe that’ll help. If not, you can play with the different multipliers that are applied to the delta value in the beginning of the onWheelHandler function.

creacog » Blog Archive » flash in the pan February 9, 2010 at 7:06 PM

[…] or ‘panning‘. There are JavaScript workarounds for in-browser Flash on a Mac such as this solution on hasseg.org or this SWFObject based pixelbreaker solution. Fortunately Flash applications delivered via the […]

Felipe February 25, 2010 at 4:56 PM

Thanks for this fix, you saved my day :D

Maechi March 9, 2010 at 6:32 PM

Hi there,

Im using AC_FL_RunContent() to embed the swf file. around this method i have a div. but eighter within the flex builder and within my page using AC_FL_RunContent it doesn’t work…

any ideas? Maechi

alekkus March 17, 2010 at 10:01 AM

I just put up a post on how to enable trackpad/wheel scrolling on mac os for flex4. Hope that’s useful : )

http://alekkus.com/blog/2010/03/flex-tutorial-enabling-track-pad-mouse-wheel-scrolling-on-mac-os-x-for-flex-4/

alekkus

Shawn March 22, 2010 at 6:48 PM

Anyone got this working with swfobject.js v2.2?

I’m using FlashBuilder and cannot get this to work with Firefox using swfobject 2.2.

Safari works when I add the second DIV around flashContent like so:

....

Firefox shows nothing….The outer div is showing (I’ve added content to show that). But the inner div seems to be set to nothing.

Flash Player Mouse Wheel not working « Flex / Flash RIAs April 15, 2010 at 11:37 PM

[…] Anybody who has programmed in flex or flash for any time is knowledgeable of the common Mouse Wheel problem in the mac flash player. For whatever reason, adobe has decided not to add MouseWheel Support in the flash player for Macintosh.  A good solution to this problem is found at: ://hasseg.org/blog/post/138/os-x-mouse-wheel-support-for-actionscript-3-flash-applications-v2/. […]

Keyboard modifiers and flash player for mac « Flex / Flash RIAs April 16, 2010 at 12:04 AM

[…] overcome this problem by implementing one of the more famous mouse wheel fixes found as hasseg.org (://hasseg.org/blog/post/138/os-x-mouse-wheel-support-for-actionscript-3-flash-applications-v2/).  Although the fix wasn’t meant to fix erratic behavior with keyboard modifiers, it […]

David May 26, 2010 at 5:04 PM

hi there, looks great but can’t get a simple test to work. i’m sure its something simple i’m misunderstanding about implementing or doing wrong. here is my code written in Flash CS3:

import org.hasseg.externalMouseWheel.ExternalMouseWheelSupport;
var _mwSupport:ExternalMouseWheelSupport = ExternalMouseWheelSupport.getInstance(stage);


_mwSupport.addEventListener(MouseEvent.MOUSE_WHEEL, mouseWheelListener);
stage.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveListener);

var output:TextField = new TextField();
addChild(output);


function mouseWheelListener(e:MouseEvent):void
{
	//
	output.text = "wheelie";
	trace("wheelie");
}

function mouseMoveListener(e:MouseEvent):void
{
	//
	output.text = "movie";
	trace("movie");
}

any help greatly appreciated! thanks

Marc May 30, 2010 at 2:22 PM

Hi, is there a way to modify the delta for a slide eg?

At the moment i have a delta form 3/-3 but i want it anytime to be 1/-1 Idea? Cheers Marc

76g7o6g July 6, 2010 at 6:39 PM

Does this work with FP 10.1 ? Is it even necessary, or is the bug fixed? Thanks

Marc July 7, 2010 at 5:02 PM

looks like that mousewheel is now working

http://wensauer.info/flex/ConstantDeltaSlider/ConstantDeltaSlider.html

At least in Chrome and havarie, in firefox not.

Scrollbars do NOT work at all even on windows.

bersy July 21, 2010 at 2:15 AM

what about mouse wheel supporting during dragging elements in container with scrollbar?

Ryan Andrews October 31, 2010 at 8:02 PM

Thanks for the great code! I have a quick question though. Is there anyway to kill off its support once initialized? On my project, I need normal mouse wheel functionality to occur everywhere except with 1 popup window in my flash app. I initialize it when the popup is displayed, but then want to restore normal mouse wheel support so the mouse wheel will scroll the browser window again once the popup is closed. Currently, once initialized, I can’t seem to restore normal browser scrolling when over the embed flash app.

Hope this makes sense. Thanks for any help!

Ryan

javascript to actionscript keypress passing utility? | Technical support, Computer, programming issue, issue tracking, quality assurance September 13, 2011 at 7:04 PM

[…] events in the browser (or certain divs) into flash? I am hoping there might be a library kind of like this one for mousewheel events […]

Categories