Mach3.laBlog

はじめてのRaphael (2) : イベント編

この記事は賞味期限切れです。(更新から1年が経過しています)

Raphaelチュートリアルの第二回です。
今回は、描画された図のマウスイベントを操作する方法を紹介します。

はじめてのRaphael (2) : イベント編

シンプルな例

まずはシンプルな例から。
紙に円を描き、マウスでクリックされた時になんらかの処理を行います。

(function(){
    var paper, myCircle, onClick ;

    /**
     * 紙に円を描きます。
     * myCircleには、Elementオブジェクトが格納されます。
     */
    paper = new Raphael( "paper", 640, 480 );
    myCircle = paper.circle( 100, 100, 32 )
        .attr( { fill : "#345", stroke : "none" } );

    /**
     * Element.click() で
     * マウスクリックイベントのハンドラを設定できます。
     * ハンドラ内のthisはElementオブジェクトです。
     */
    myCircle.click( function(){
        console.log( this.type ); // => "circle"
        alert( "さわんな!" );
    });

})();

Element.click() メソッドの引数に関数を渡すだけなので、とても簡単。

円に限らず、ほとんどのシェイプ描画メソッドはElementオブジェクトを返します。
イベントやアニメーションをいじりたい場合は、
この例での変数「myCircle」のように返り値を格納しておくと良いですね。
勿論、メソッドチェーンで一気に書いてしまう事もできます。

paper.circle( 100, 100, 32 )
    .attr( { fill : "#345", stroke : "none" } )
    .click( function(){
        alert( "さわんな!" );
    });

イベントハンドラの登録解除

設定したイベントハンドラを解除するのは、
そのメソッドに接頭辞「un」をつけたメソッドを使います。
例えばclick() で登録したハンドラの登録解除は、unclick() を使用します。

/**
 * click() で登録
 */
var onClick = function(){ alert("さわんな!"); };
myCircle.click( onClick );

/**
 * unclick() で登録解除
 */
myCircle.unclick( onClick ); // もうさわっても怒られません。

イベントの色々

clickの他にも様々なマウスイベント用のメソッドが用意されています。

おなじみのイベント

まず、これらのおなじみの方々。
恐らく名前を見るだけで、どんな役割なのかすぐに分かることでしょう。

  • click (クリック)
  • dblclick (ダブルクリック)
  • mousedown (マウスダウン)
  • mousemove (マウスムーブ)
  • mosueout (マウスアウト)
  • mouseover (マウスオーバー)
  • mouseup (マウスアップ)

タッチ関係のイベント

スマートフォン向けの、タッチイベントも実装されています。

  • touchcancel (タッチキャンセル)
  • touchend (タッチエンド)
  • touchmove (タッチムーブ)
  • touchstart (タッチスタート)

jQueryのような、hover()

jQuery.hover() は、マウスが入ってきた時と離れていく時のハンドラを
同時に設定する事が出来る便利なメソッドですが、
それとほぼ同じ役割をし、名前も同じ hover() メソッドが用意されています。

Element.hover( f_in, f_out );
f_in (Function) マウスが入ってきた時の処理
f_out (Function) マウスが離れていく時の処理
/**
 * マウスオーバーで塗り色を変えるサンプル。
 */
myCircle.hover(
    function(){
        console.log( "くんな!" );
        this.attr( "fill", "#c00" );
    },
    function(){
        console.log( "にげんな!" );
        this.attr( "fill", "#345" );
    }
);

drag() で要素のドラッグを実装する

Element.drag() を使う事で、要素のドラッグに必要な
マウスダウン時、マウスムーブ時、マウスアップ時のイベントをまとめて設定できます。
ただし、ActionScriptのstartDrag()のように要素の移動まで面倒みてくれるわけではないので、
各イベントハンドラにそれらを実装してあげる必要があります。

Element.drag()

Element.drag( onmove, onstart, onend );
onmove (Function) マウスムーブ時の処理
onstart (Function) ドラッグ開始時の処理(マウスダウン)
onend (Function) ドラッグ終了時の処理(マウスアップ)

これらのコールバックは全て渡される引数が違うので注意が必要です。
特におさえておくべきは、第一引数のonmoveです。

onmove

onmove : function( dx, dy, x, y, event )
dx : ドラッグ開始位置からの相対的座標(x)
dy : ドラッグ開始位置からの相対的座標(y)
x : 現在のx座標
y : 現在のy座標
event : イベントオブジェクト

わざわざ相対的座標を渡しているのは、
マウス座標をそのまま要素のx,y座標に代入してしまうと
予想と違う位置に要素が移動してしまう為。
どの部分をクリックしてドラッグしても、
要素はマウスの右下にぶらさがる形になってしまいますね。

つまり、こんなかんじになるでしょう。

  1. onstartでドラッグ前の要素の座標を記録しておく
  2. onmoveで、1.で記録した座標と相対的座標をあわせて計算
(function(){
    var paper, myRect;

    paper = new Raphael( "paper", 640, 480 );
    myRect = paper.rect( 100, 100, 32, 32 )
        .attr( { fill : "#345", stroke : "none" } );
   
    myRect.drag(
        /**
         * マウスムーブ時の処理
         */
        function( dx, dy, x, y, e ){
            /**
             * Element.data() で初期の座標を取り出して
             * dx, dyを加算して移動
             */
            this.attr({
                x : this.data("x") + dx,
                y : this.data("y") + dy
            });
        },
        /**
         * ドラッグ開始時の処理
         */
        function( x, y, e ){
            /**
             * 要素の座標をElement.data()で記録
             */
            this.data( "x", this.attr("x") );
            this.data( "y", this.attr("y") );
            this.attr( "fill", "#c00" );
        },
        /**
         * ドラッグ終了時の処理
         */
        function( e ){
            this.attr( "fill", "#345" );
        }
    );
})();

jQueryのようなdata()が便利

RaphaelのElementオブジェクトには
jQuery.data() と似たような機能が同名のメソッドで実装されていて、
上記のコールバック内で使われているように
情報を保持しておくのに便利です。

// 値の設定
myElement.data( "foo", "bar" );
// 値の取得
console.log( my.Element.data( "foo" ) ); // => bar

デモ

デモをこちらにまとめました。

» はじめてのRaphael(2) : イベント編 via jsFiddle

まとめ

Raphaelは、意外とjQueryのメソッドと共通点があり、
導入にあまり苦労しなさそうで助かります。
描画とイベントが操れれば、簡単なRUIを実現できてしまいますね。

コメント

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

*