Home > 梅原 > Macでもマウスホイールを使う

Macでもマウスホイールを使う

20090611
Category:梅原 /Tags:

macmouseJavaScriptからActionScriptを動作させる仕組み、ExternalInterface.addCallbackの使い道の一つとして、「Macでもマウスホイールを使う」ってのがある。Windows版と異なりMac版FlashPlayerでは直接マウスホイールを認識できないので、ブラウザのJavaScriptを経由してaddcallbackを使い、Flash側にマウスホイールがどれくらい動いたかを伝えるのだ。

ライブラリとの組み合わせで解決する方法もあるが、まずは普通に作って理解してみよう。

ExternalInterface.addcallbackを知らない人は、まずは↓を読むこと。
http://www.mztm.jp/2009/06/10/externalinterfaceaddcallback/

↓できあがりはこれ。

ファイル一式 >>ダウンロード

ASのほうは、JSから値を受け取ってスクロールポジションに送っているだけ。
問題はJS側。マウスホイールの値はdelta(デルタ)と呼ばれているのだが、例えばマウスホイールが15度手前に回転した場合に、デルタ値がいくつなのか、マイナスなのかプラスなのかも統一されていないのでJS側でそれを吸収している。ブラウザのバージョンや目的によって、最適値が異なる場合があるので、必ず確認すること。

【参考】
http://adomas.org/javascript-mouse-wheel/
http://f-site.org/articles/2006/09/14175612.html
http://www.ficc.jp/labs/archives/ando/as3_mac/

▼ActionScript3

package {
	import flash.display.Sprite;
	import flash.text.TextField;
	import flash.external.ExternalInterface;
	import fl.containers.ScrollPane;

	public class Main extends Sprite{
		private var tfStatus:TextField = MakeUI.newTextField([,, 200,, "JSからの命令を待っています。"]);
		private var tfValue:TextField = MakeUI.newTextField([,20,200]);
		private var shikaku:Sprite = MakeUI.newSprite(null, [["rotation", 45],["mouseEnabled",false]], [["beginFill", [0x00FF00, 0.5]], ["drawRect", [0, 0, 200, 200]]]);
		private var sp:ScrollPane = MakeUI.newScrollPane([200, 0, 300, 100, shikaku]);

		public function Main():void {
			addChild(tfStatus);
			addChild(tfValue);
			addChild(sp);
			ExternalInterface.addCallback("JS2AS", fn);
		}
		/**
		 * JSからの命令はExternalInterface.addCallbackを経由して、
		 * 関数に引き渡されます。
		 */
		private function fn(myValue:Number):void {
			var vsp:Number = Math.max(0, Math.min(sp.verticalScrollPosition - myValue, shikaku.height));
			sp.verticalScrollPosition = vsp;
			tfStatus.text = "JSからの命令を受け取れました。";
			tfValue.text = String(vsp);
		}
	}
}

import flash.display.DisplayObject;
import fl.containers.ScrollPane;
import flash.display.Sprite;
import flash.text.TextField;
import flash.text.TextFormat;
class MakeUI {
	public static var defaultTextFormat:TextFormat = new TextFormat();
	public static function newScrollPane(x_y_w_h_source:Array = null, property:Array = null):ScrollPane {
		var i:int;
		var sp:ScrollPane = new ScrollPane();
		if (x_y_w_h_source) {
			if (!x_y_w_h_source[0]) { x_y_w_h_source[0] = 0 };
			if (!x_y_w_h_source[1]) { x_y_w_h_source[1] = 0 };
			sp.move(x_y_w_h_source[0], x_y_w_h_source[1]);
			if (x_y_w_h_source[2] && x_y_w_h_source[3]) { sp.setSize(x_y_w_h_source[2], x_y_w_h_source[3]) };
		}
		if(property){
			for (i = 0; i < property.length; i++) {
				if(property[i] && property[i].length > 1){ sp[property[i][0]] = property[i][1] };
			}
		}
		if (x_y_w_h_source.length == 5) {
			sp.source = x_y_w_h_source[4];
			sp.update();
		}
		return sp;
	}

	public static function newSprite(x_y_w_h_sp:Array = null,property:Array=null,graphics:Array=null,addChild:DisplayObject = null):Sprite{
		var i:int;
		var sp:Sprite;
		if(x_y_w_h_sp && x_y_w_h_sp[4]){
			sp = x_y_w_h_sp[4];
		}else{
			sp = new Sprite();
		}
		if(x_y_w_h_sp){
			if (x_y_w_h_sp[0]) { sp.x = x_y_w_h_sp[0] };
			if (x_y_w_h_sp[1]) { sp.y = x_y_w_h_sp[1] };
		}
		if(property){
			for (i = 0; i < property.length; i++) {
				if(property[i] && property[i].length > 1){sp[property[i][0]] = property[i][1] };
			}
		}
		if(graphics){
			for (i = 0; i < graphics.length; i++) {
				if(graphics[i] && graphics[i].length > 1){
					sp.graphics[graphics[i][0]].apply(graphics[i][2], graphics[i][1]);
				}
			}
		}
		if(addChild){ sp.addChild(addChild) };
		if(x_y_w_h_sp){
			if (x_y_w_h_sp[2]) { sp.width = x_y_w_h_sp[2] };
			if (x_y_w_h_sp[3]) { sp.height = x_y_w_h_sp[3] };
		}
		return sp;
	}

	public static function newTextField(x_y_w_h_txt_color_alpha:Array = null,property:Array=null,method:Array=null):TextField{
		var i:int;
		var ta:TextField = new TextField();
		ta.defaultTextFormat = defaultTextFormat;
		if(x_y_w_h_txt_color_alpha){
			if (x_y_w_h_txt_color_alpha[0]) { ta.x = x_y_w_h_txt_color_alpha[0] };
			if (x_y_w_h_txt_color_alpha[1]) { ta.y = x_y_w_h_txt_color_alpha[1] };
			if (x_y_w_h_txt_color_alpha[2]) { ta.width = x_y_w_h_txt_color_alpha[2] };
			if (x_y_w_h_txt_color_alpha[3]) { ta.height = x_y_w_h_txt_color_alpha[3] };
			if (x_y_w_h_txt_color_alpha[4]) { ta.text = x_y_w_h_txt_color_alpha[4] };
			if (x_y_w_h_txt_color_alpha[5]) { ta.textColor = x_y_w_h_txt_color_alpha[5] };
			if (x_y_w_h_txt_color_alpha[6]) { ta.alpha = x_y_w_h_txt_color_alpha[6] };
		}
		if(property){
			for (i = 0; i < property.length; i++) {
				if(property[i] && property[i].length > 1){ta[property[i][0]] = property[i][1] };
			}
		}
		if(method){
			for (i = 0; i < method.length; i++) {
				if(method[i] && method[i].length > 1){
					ta[i].apply(method[i][2], method[i][1]);
				}
			}
		}
		return ta;
	}
}

▼JavaScript

<script language="javascript">
	function wheel(event){
		var delta = 0;
		if (!event){/* For IE. */
			event = window.event;
		}
		if (event.wheelDelta) {/* IE/Opera. */
			delta = event.wheelDelta/120;
			/** In Opera 9, delta differs in sign as compared to IE.*/
			if (window.opera){
				//delta = -delta;
			}
			if(navigator.userAgent.indexOf("Safari") > -1){
				delta = delta/3;
			}
		} else if (event.detail) {/** Mozilla case. */
			delta = -event.detail/3;
		}
		if (delta){
			swfName("test").JS2AS(delta);
		}
	}
	if (window.addEventListener){
		 /** DOMMouseScroll is for mozilla. */
		window.addEventListener('DOMMouseScroll', wheel, false);
	}
	/** IE/Opera. */
	window.onmousewheel = document.onmousewheel = wheel;
	function swfName(str) {
		if (navigator.appName.indexOf("Microsoft") != -1) {
			return window[str]
		}else {
			return document[str]
		}
	}
</script>

関連記事:

Comments are closed.