[HTML5] CreateJS を利用した線表アプリの部品づくり ( 実装編 )

連載 URL

前回は、複数ボタンを保持する「タスクボタン」の構造、および、各ボタンのイベントについて解説しました。今回は、この「タスクボタン」を使用して簡易日付範囲選択機能を実装する方法について解説します。

サンプル

こちら
http://176.34.48.254/html5-sample/canvas_demo/cjsschedulersample/Main.html

座標、幅の移動量制限

任意の移動量を設定して、「タスクボタン」の座標やサイズがグリッドにスナップするかのように増減するように制限します。下記コードはマウスの移動量を元に 50 の倍数の近似値を返すコードです。(Haxe)

private function getAdjustmentMoveX(nx:Float):Float {
    var gridWidth:Int = 50;
    var ghw:Int = Std.int( gridWidth * 0.5 );
    var div:Int = Std.int( nx / gridWidth );
    var odd:Int = Std.int( nx % gridWidth );
    if(nx > 0) {
        if(odd > ghw) {
            div++;
        }
    }
    else if(odd < -ghw) {
        div--;
    }
    return gridWidth * div;
}[/javascript]

<h2 id="toc-2">各ボタンのイベントハンドリングを行う前に</h2>
<p>タスクボタンが保持する各ボタンの "pressmove", "pressup" をハンドリングして座標や幅を操作したいとき、以下のような制限を設けたい場合があります。</p>
<ul>
<li>左ボタンドラッグ時、負の方向に移動する場合 X 座標を減算しつつ幅を増やす</li>
<li>左ボタンドラッグ時、正の方向に移動する場合 X 座標を加算しつつ幅を減らす、このとき右ボタンを超えてはならない</li>
<li>右ボタンドラッグ時、負の方向に移動する場合 X 座標は固定たまま幅を減らす、このとき左ボタンを超えてはならない</li>
<li>右ボタンドラッグ時、正の方向に移動する場合 X 座標は固定たまま幅を増やす、このとき左ボタンを超えてはならない</li>
</ul>

<p>次のように直前のタスクボタンの座標や幅を保持することによって、移動量に制限を掛けることが容易にできます。(Haxe)</p>


<h2 id="toc--">右ボタンドラッグ処理 ( 幅伸縮 )</h2>


<h2 id="toc-3">「タスクボタン」と日付の関連付け</h2>
<p>配置するグリッドの 1 マスを任意の時間に定義した上で、タスクボタンの X 座標と幅を基に日付を算出します。以下のサンプルコードでは、<strong>「 1 マス = 50px = 6 時間」</strong>というルールに基づいて日付を算出しています。</p>
private function getStartDay(tx:Float):Int {
    var dx:Float = tx - backgroundStartX; //backgroundStartX はサンプル背景の左端座標
    return Std.int(dx / gridWidth);
}
private function updateTaskDate(target:TaskButton):Void {

    var rect      :Rectangle = target.getBounds();
    var taskX     :Float = target.x;
    var taskWidth :Float = rect.width;

    var y:Int = currentStartDay.getFullYear();
    var m:Int = currentStartDay.getMonth();
    var d:Int = currentStartDay.getDate();
    var h:Int = currentStartDay.getHours();

    var sdc:Int;
    var div:Int;
    var odd:Int;

    sdc = getStartDay(taskX);
    div = Std.int(sdc / 4);//0,6,12,18
    odd = Std.int(sdc % 4);

    var nsd:Int;
    var nsh:Int;

    nsd = d + div;
    nsh = h + (odd * 6);

    sdc = getStartDay(taskX + taskWidth);
    div = Std.int(sdc / 4);//0,6,12,18
    odd = Std.int(sdc % 4);

    var ned:Int;
    var neh:Int;

    ned = d + div;
    neh = h + (odd * 6);

    var startDate : Date = new Date(y, m, nsd, nsh, 0, 0);
    var endDate   : Date = new Date(y, m, ned, neh, 0, 0);

    var sy:Int = startDate.getFullYear();
    var sm:Int = startDate.getMonth();
    var sd:Int = startDate.getDate();
    var sh:Int = startDate.getHours();

    var ey:Int = endDate.getFullYear();
    var em:Int = endDate.getMonth();
    var ed:Int = endDate.getDate();
    var eh:Int = endDate.getHours();

    Browser.document.getElementById("hoge").innerHTML
    = Std.string(
        sy + " 年 " +
        (sm + 1) + " 月 " +
        sd + " 日 " +
        sh + " 時 ~ " +
        ey + " 年 " +
        (em + 1) + " 月 " +
        ed + " 日 " +
        eh + " 時"
    );

}

以上です。お疲れさまでした。