- 2006-11-10 (金)
- action script
従来、Macではマウスホイールの回転は取得できませんでしたが、Flash8のExternalInterfaceを使ってJavascriptのホイールイベントを取得することで、Flashでのマウスホイールスクロールが可能です。
国内でも、以前から「Back At One.」さんや「F-site」さんでも紹介されていますが、最近、海外のBlog「pixelbreaker」で、SWFObjectにアドオンさせる形で、簡単に導入できる「SWFMacMouseWheel」が公開されていたので、これを使わせてもらって、以下のようなサンプルを作ってみました。
動作確認も兼ねて、下書きですがアップします。コードもちょくちょく修正をかけていきます。いずれは全部まとめたzipファイルを配布いたしますのでよろしくです。
Macの場合、ブラウザのフォーカスをswfに渡したまま戻らなくなるので、以降のブラウザのホイールが効かなくなる現象があります。対応策を勉強中ですが、とりあえず現状はページのリロードなどで対応してください。
以前作ったスクロールバーを見直し、ゼロから作り直しました。ExternalInterfaceを使うため、Flash Player 8が必要です。ですが、ここで朗報です!この「SWFMacMouseWheel」はSWFObjectをアドオン(拡張みたいなもん)したものなので、ExpressInstallにも簡単に対応できます。
「SWFMacMouseWheel」サイトから、関連クラス&Javascriptをダウンロード後、好きなように拡張していきます。僕は外部カスタムクラス"WheelScrollBar.as"を作りました。
//WheelScrollBarクラス:11/29 update import com.pixelbreaker.ui.MouseWheel; class com.trick7.ui.WheelScrollBar { //SETTINGS-------------------------------- public var wSpeed:Number = 3; public var cSpeed:Number = 3; //PROPERTIES------------------------------ public var content:MovieClip; public var mask:MovieClip; public var bar:MovieClip; public var slider:MovieClip; public var cursorUp:MovieClip; public var cursorDown:MovieClip; private var mPc:Number; private var mPs:Number; private var yMin:Number; private var yMax:Number; //CONSTRUCTOR----------------------------- function WheelScrollBar(c:MovieClip, m:MovieClip, b:MovieClip, s:MovieClip, u:MovieClip, d:MovieClip) { content = c; mask = m; bar = b; slider = s; if (u) { cursorUp = u; } if (d) { cursorDown = d; } focusWheel(); content.setMask(mask); mPc = mask._height/content._height; init(); } //PUBLIC---------------------------------- function init():Void { slider._height = bar._height*mPc; mPs = mask._height/slider._height; yMin = bar._y; yMax = bar._y+bar._height-slider._height; //if (content._height <= mask._height), scrollBar's parts are invisible. if (mPc>=1) { bar._visible = false; slider._visible = false; cursorUp._visible = false; cursorDown._visible = false; }else{ bar._visible = true; slider._visible = true; cursorUp._visible = true; cursorDown._visible = true; } dragScroll(); //if coursorButtons are used, cursorScroll method is activated. if (cursorUp || cursorDown) { cursorScroll(); } } function onMouseWheel(delta:Number):Void { if (slider._y>=yMin && yMax && mPc<1) { slider._y -= delta*wSpeed; if (slider._y<yMin) { slider._y = yMin; } else if (slider._y>yMax) { slider._y = yMax; } } setPosition(slider._y); } //CONTROLLER------------------------------ public function setPosition(sliderPos:Number):Void { slider._y=sliderPos; content._y = -1*((sliderPos-yMin)*mPs)+mask._y; } //GETTER/SETTER METHOD-------------------- public function get top():Number{ return yMin; } public function get bottom():Number{ return yMax; } public function set bottom(newBottom:Number){ mPc = mask._height/newBottom; init() } public function set wheelSpeed(newWheelSpeed:Number){ wSpeed=newWheelSpeed init() } public function set cursorSpeed(newCursorSpeed:Number){ cSpeed=newCursorSpeed cursorScroll() } public function focusWheel():Void { MouseWheel.addListener(this); } public function unFocusWheel():Void { MouseWheel.removeListener(this); } public function windowResize(h:Number):Void{//for FULLSCREEN scrollbar mPc = mask._height/h; init(); var home:Object = this; slider._y=-1*(content._y/mPs)+bar._y;//リサイズ時の調整 trace(content._y) if(((slider._y-bar._y)+slider._height)*mPs>=h){ if(content._y<mask._y){ slider._y=yMax; home.setPosition(slider._y); }else{ content._y=mask._y } } } //PLIVATE--------------------------------- private function dragScroll():Void { var home = this; var min:Number = yMin; var max:Number = yMax; slider.onPress = function() { this.startDrag(false, this._x, min, this._x, max); this.onEnterFrame = function() { home.setPosition(this._y); }; }; slider.onRelease = slider.onReleaseOutside=function () { this.stopDrag(); this.onEnterFrame = null; }; } private function cursorScroll():Void { var home:Object = this; var speed:Number = cSpeed; var slider:MovieClip = home.slider; var min:Number = yMin; var max:Number = yMax; cursorUp.onPress = function() { this.onEnterFrame = function() { if (slider._y>min) { slider._y -= speed; if (slider._y<min) { slider._y = min; } home.setPosition(slider._y); } }; }; cursorUp.onRelease = cursorUp.onReleaseOutside=function ():Void { this.onEnterFrame = null; }; cursorDown.onPress = function():Void { this.onEnterFrame = function() { if (slider._y<max) { slider._y += speed; if (slider._y>max) { slider._y = max; } home.setPosition(slider._y); } }; }; cursorDown.onRelease = cursorDown.onReleaseOutside=function ():Void { this.onEnterFrame = null; }; } }
あとは、新規flaファイルを作成し、任意の階層に、"content_mc", "mask_mc", "bar_mc", "slider_mc"を置き、パラメータとして渡せば動くので、結構簡単かなと思います。マスクよりコンテンツの方が短い場合は、スクロールバーは表示されないようにしています。
//flaファイルのフレームスクリプト import com.trick7.ui.WheelScrollBar; var wsb:WheelScrollBar=new WheelScrollBar(content_mc,mask_mc,bar_mc,slider_mc);
で、埋め込む側のHTMLファイルは、いつものようにSWFObjectを使い、ホイールイベント用のJavascriptへのリンクとパラメーターの設定をするだけです。ちなみにこのエントリでのソースは、
: <head> <script type="text/javascript" src="/js/swfobject.js"></script> <script type="text/javascript" src="/js/swfmacmousewheel.js"></script> </head> : <div id="wheelScrollBar" style="width:350px;text-align:center;margin-bottom:5px">wheelScrollBar.swf</div> <script type="text/javascript"> var so = new SWFObject("http://www.trick7.com/blog/swf/wheelScrollBar.swf", "wheelScrollBar", "350", "250", "8", "#FFFFFF"); so.write("wheelScrollBar"); var macmousewheel = new SWFMacMouseWheel( so ); </script>
FlashPlayerのセキュリティ設定のために、ローカルではホイールの確認ができない場合があります。その時は、html, swfファイルをサーバー上にアップロードし、ご確認下さい。
「Back At One.」さんがおっしゃられていましたが、Mac版Firefoxのスクロールスピードが一番遅く、Mac版Safari,Win版Firefox, Win版IE6の順にホイールスクロールが速くなるのですが、Flashに限らず、普通にブラウジングしている時も速度が違うので、どうもブラウザの仕様かなと思い、今のところ対応はしていませんが、ブラウザごとの条件分岐も簡単にできると思います。
11/16追記:
WheelScrollBarクラスを更新。追加機能はこちらをご覧下さい。
11/21追記:
wheelSpeedとcursorSpeedをセッターとして追加、各スクロールバーの移動量を個別に設定できるようになりました。
bottomセッター追加、「WheelScrollBarインスタンス名.bottom = 500」みたいに設定できます。通常は必要ないのですが、スクロールバーを入れ子にした時や、テキストフィールドの不具合(下記参照)などの際、役立つプロパティです。
11/29追記:
swf内に複数個のWheelScrollBarインスタンスを設置した際、ホイールスクロールのフォーカスの切替えができる、focusWheel(), unForcusWheel() メソッドを追加。
また、全画面Flashの画面全体にスクロールバーを付けた際、ブラウザのウィンドウリサイズに対応するための、windowResize(h:Number)メソッドを追加。
備考:「スクロール対象のMCにテキストフィールドを内包させる時の注意点」
スクロール対象となるムービークリップ(content_mc)の中に、テキストフィールドを下端ぎりぎりに配置する場合、テキストフィールドの高さがおかしくなる症状のために、予期しない部分までスクロールしてしまう事があります。
その場合は、flaファイル内でのインスタンス生成文、
var wsb:WheelScrollBar=new WheelScrollBar(.....);
の直後に、
wsb.bottom=(スクロール下端にしたい数値);
と追加して、数値を直接入力してください。その数値までしかスクロールしないようにできます。
- Newer: Javascriptを基礎から勉強する
- Older: Stomp Stamp
Comment:16
- Saqoosha 2006-11-11 (土) 18:54
-
swfmacmousewheel.js をのぞいてみましたけどいちおうブラウザ毎のホイール量の調整はやってるみたいですねぇ。
bodyのonwheeleventじゃなくてembed要素のonwheeleventならHTML側のスクロールも残るんじゃないかと思ったりでも試してる時間がなかったり。 - tera 2006-11-12 (日) 01:06
-
>>Saqoosha様
はじめまして。コメントありがとうございます。
どうやら作者の方はWindows環境のIEとFireFoxが同じホイール量になるように調整しているのでしょうか。MacFF用には別途"delta = -event.detail/1.5;"ぐらいで別途条件分岐させれば同じぐらいかなと。
あと、このへんのパラメータを少しいじってみましたが、IE/Opera用の条件設定がSafariに影響している気もします。フォーカスの件の情報もありがとうございます。
embed要素レベルでonmousewheelを取得できるのですか!知りませんでした。
でも、このライブラリが、おそらくフルフラッシュサイトでの使用を想定して作られている気もするので、この仕様のまま、ロード後に強制的にwindow及びbodyのonmousewheelを奪ってしまうのが最善かもという気もします。なにぶん、僕がJavascript素人なので、とたんに開発スピードが激遅になるのがもどかしいです。頑張ります。
- Adam 2007-04-12 (木) 19:35
-
Hi,
I really like your scrollbar (http://www.trick7.com/blog/2006/08/08-112615.php) but I couldn't get it to work with your custom class for Mac scrollwheels. Do you have a version of it you could share?
PS I don't speak Japanese :(
Thanks!
- tera 2007-04-12 (木) 21:58
-
Hi Adam
They are not compatible.Scrollbar in this article:
- For Flash8 or later.(need ExternalInterface)
- Need SWFMacMouseWheel(http://blog.pixelbreaker.com/2006/11/08/flash/swfmacmousewheel/)
- There is a problem about Wheel Focus between FlashPlayer and Browser.Scrollbar (http://www.trick7.com/blog/2006/08/08-112615.php):
- For FlashPlayer7Please improve them as you wish if you like.
Thank you. - Adam 2007-04-13 (金) 02:21
-
Hi tera,
Thanks for the reply!
I have been experimenting with SWFMacMouseWheel but haven't found an implementation of it that I'm happy with.
Do you have a version of this scrollbar you could share? I didn't see the source for the scrollbar anywhere on the article. I'm not very advanced at actionscript and would really appreciate the help.
I found this other example:
http://chakramedia.com/blog/2006/11/20/swfmacmousewheel-real-world-example/. But I think your implementation is a lot smoother and more reliable.Btw, I couldn't find any contact info for you on your site.
Thanks!
- Adam 2007-04-13 (金) 10:00
-
Hi,
I figured it out. I wasn't importing all the classes. Thanks for the great custom class! - tera 2007-04-13 (金) 13:06
-
Congratulation! I'm happy to hear that.
There is a point to pay attention.
If you set TextField near the bottom of the scroll area, TextField's height is too long as we expected. Because of it, scrolling to extra area.
So we have to fix:
- Make the TextField "Outlined".
or
- Set the height to the bottom manually. (suggested)
Fix the code in FLA file:
var wsb:WheelScrollBar=new WheelScrollBar(.....);
wsb.bottom=(Height number that you want to set);Sorry for my poor English. Please have a fun with my Scrollbar.
Thank you. - yoshidam 2007-05-14 (月) 19:04
-
はじめまして!
うまくスクロールすることができました。
どうもありがとうございます。
他の記事も参考にさせていただきます。
今は Fuse kit に挑戦しています! - tera 2007-05-16 (水) 01:15
-
>yoshidam様
コメントありがとうございます。
お役に立てて、僕も嬉しいです。
だいぶ昔のエントリなので、実は内容うろ覚えですw。
僕も復習しないといけませんね。 - spice 2007-08-05 (日) 20:40
-
いつもいつも参考にさせていただいています。
WheelScrollBarクラス、すごいです。ほんと便利です。
ちょっとMACの環境で問題にぶつかったのでご報告させていただこうかと思います。
FLAのコンテンツを作るときは私は通常メインのSWF(index.swf)があって、その下のコンテンツはそのメインに読み込む形で制作するのですが、どうもその場合問題がでるようです。具体的に言うと、index.swf のstage_mcにscroll_1.swfを読み込みます。その場合は普通に動作するのですが、続けてstage_mcに(別のコンテンツを見る)scroll_2.swfを読み込みます。そこでマウスホイールを動かすと必ず落ちます。また、scroll_1>HOMEに戻り再度同じscroll_1.swfを読み込んでも落ちました。
実際にここで使わせていただいています。
http://www.milligram.ne.jp/
NEWSをみて、スクロールしてその次にPUBLICATIONを見てスクロールしてみてください。
色々調べてみたのですが、解決策はまだ見つかっていません。ちなみにFireFox でもSafariでも同じく必ず落ちます。
これはJavascriptの問題かもしれないのですが・・。
もし何か原因が分かればご教授いただけると大変ありがたいです! - tera 2007-08-06 (月) 22:43
-
>spice様
コメントありがとうございます。
サイトを拝見させていただきました。格好いいです!大学が建築だったこともあり、羨ましく思いつつ拝見しました。
ブラウザ、本当に落ちますね。
flashでここまで完璧に落ちるということはそんなに見ないので、やはりswfmacmousewheel.js側に原因があるのではと疑ってしまいますが、なにぶん僕はJavaScript素人(いまだに言ってる。。)ですので、jsソースを見て原因を見つけるというのは至難の業っぽいです。
でも時間をみつけて探してみたいとは思います。
ご報告ありがとうございました。引き続き何か分かりましたらご連絡いただけると嬉しいです。
今後ともよろしくお願いいたします。 - spice 2007-08-08 (水) 16:29
-
tera様
コメントありがとうございます。たぶんjsの問題だとは思うのですが・・・。pixel breakerさんに直接質問しようとしたんですが、コメントの書き込みが出来なくなっちゃってました・・・。残念。今は読み込み側のswfにWheelScrollBarクラスを埋め込んでいるのですが、これをどうにかメインのswfに入れて、それを読み込み側から呼び出す形にするとどうなるか(メインのswfのみにクラスを読み込む)試してみようと思います。ばたついているのでしばらく後になるかとは思いますが・・・。
またご報告いたしますね。これからも価値あるBLOGの提供期待して応援しています! - spice 2007-09-06 (木) 20:50
-
やっとテストが出来ましたのでご報告いたします!テストの結果、_root(メインのSWF)にWheelScrollBarクラスを埋め込み、読み込んだSWFから_rootのWheelScrollBarを呼び出すことで落ちなくなりましたー。読み込むSWFにそれぞれWheelScrollBarクラスが書いてあると落ちるようですね・・。原因は分かりませんが、解決策として・・。ご参考になればと思います。
ではでは。 - tera 2007-09-07 (金) 15:40
-
>spice様
貴重なご連絡ありがとうございます!
僕を含め、同じ症状に遭遇した皆さんにとって大変有益な情報、ありがとうございました!
今後ともよろしくお願いいたします。 - TOBY 2008-01-20 (日) 18:45
-
エントリーの趣旨とは違うので軽く流してください。
> Mac版Firefoxのスクロールスピードが一番遅く、Mac版Safari,Win版Firefox,
> Win版IE6の順にホイールスクロールが速くなるのですが、Flashに限らず、
> 普通にブラウジングしている時も速度が違うので、どうもブラウザの仕様かなと思いブラウザの仕様よりは、マウスドライバの影響が強いかな?と思います。
Windowsでの環境依存かもしれませんが、
標準のドライバと、Logicoolと、IntelliPoint(Microsoft製)では全くスクロール速度が異なる上に、さらに速度設定でも変わってしまいます。
例えば、IntelliPointではスクロールに加速がつき(?)、一度にホイールを動かした時に一気にスクロールするなどといった仕様もあります(上記のサンプルFlashでもそのように動作しました)
一方、Logicoolのドライバでは、加速がつきません。(以前の情報なので今はついているかも)上記の状態は、IE7.0、IE 6.0、Firefox2.0(どれもWindows)でも共通で言えることのようです。
別でFirefox2.0ではスクロール速度を変更できたはずですので、それも関係するのかも・・・(私は、デフォルトでは遅いので速くしてます)
とはいえ、うちの環境では、サンプルのFlashは、Firefox2.0、IE7.0で特にスクロール速度は変わりませんでした。
関係ないですが、IntelliPointの加速スクロールは便利なので、MSでないマウスでも入れて使ってます^^;
- dee 2008-07-04 (金) 13:58
-
先日はSWFForcesizeについてお教えいただきありがとうございました。
大変詳しく解説して頂いたので、 問題なく使用することができました。
本当に感謝しております。たびたびの質問で申し訳ないのですが。
今回は、SWFMacMouseWheelについての質問です。SWFMacMouseWheelの使用方法については、このページを参考にして導入することができたのですが、
一つだけ問題があったので(報告を兼ねての?)質問です。実は、SWFMacMouseWheelを使用したサイトをOperaで見てみると、
Mac(FlashPlayerのバージョンは9です)の場合だけホイールの回転が逆に取得されてしまったのです。
http://www.rinpa2008.jp
<↑参考URL>
Winの場合はOperaでも問題はありませんでした。
Mac+Operaのユーザーは少ないとは思うのですが、何となく気になったのでコメントを送ることにしました。
Trackback:0
- TrackBack URL for this entry
- http://www.trick7.com/blog/mt-tb.cgi/379
- Listed below are links to weblogs that reference
- Macでもマウスホイールできるスクロールバーのサンプル from trick7.com blog



