第1回: キャンバスに正方形を表示する

2012/03/03

前回は、CoffeeScriptとJQueryの学習を行うベースとなるRailsアプリケーションTorajaを作ってから、画面上のある領域をダブルクリックすると「Hello World!」というポップアップメッセージを表示する簡単なCoffeeScriptプログラムを作りました。

今回は、ダブルクリックというイベントが発生するたびに、その位置に正方形を表示するプログラムを作ります。

SCSSファイルの修正

はじめに準備作業です。

app/assets/stylesheets/top.css.scss を修正。

div#canvas {
  position: relative;
  width: 400px;
  height: 400px;
  background-color: silver;
  
  div.block {
    position: absolute;
    width: 78px;
    height: 78px;
    border: 2px solid black;
    background-color: pink;
  }
}

SCSSの説明は省略します。こんな風に「入れ子」にできる点がSCSSの特長です。

キャンバスに正方形を表示する

app/assets/javascripts/top.js.coffee を修正。

$ ->
  $("div#canvas").dblclick (e) ->
    canvas = $(e.target)
    x = e.pageX - canvas.position().left
    y = e.pageY - canvas.position().top
    canvas.append("<div class='block' style='left: #{x}px; top: #{y}px;' />")

前回の繰り返しになりますが、CoffeeScriptはインデント(字下げ)によってプログラムの構造を表現します。行頭のスペースの個数に注意してください。

ソースコードを解説します。

  $("div#canvas").dblclick (e) ->

修正前はこうでした:

  $("div#canvas").dblclick ->

CSSセレクタ div#canvas に該当する要素がダブルクリックされた時の振る舞いを -> 以下に書くんでしたね。

このように何らかのイベントに反応して動き出すコードのことをイベントハンドラと呼びます。イベントハンドラの正体は、無名の関数です。Rubyのブロックみたいなものだと考えてください。

括弧の中の e はイベントハンドラに渡す引数です。この引数にはイベントオブジェクトが格納されています。

    canvas = $(e.target)

ローカル変数 canvas に値をセットしています。CoffeeScriptのローカル変数は、Rubyのそれと同様に、変数が最初に現れたところで定義されます。純粋なJavaScriptではいちいち var で変数を宣言する必要がありますが、CoffeeScriptでは不要です。

e.target で、イベントの対象となった要素をオブジェクトとして取得できます。そして、それを $ メソッドでjQueryオブジェクトに変換しています。

単なる要素オブジェクトには、次の行で使用する position メソッドがありません。これはjQueryライブラリが提供するメソッドだからです。

    x = e.pageX - canvas.position().left
    y = e.pageY - canvas.position().top

e.pageX はイベントが発生した場所の画面上のX座標を返します。画面の左上が原点で、横軸がX軸です。

canvas.position().left で、キャンバス(薄い灰色の領域)の左上隅のX座標を取得できますので、ローカル変数 x にはイベントが発生した場所のキャンバス内におけるX座標がセットされます。同様に、ローカル変数 y にはY座標が格納されます。

    canvas.append("<div class='block' style='left: #{x}px; top: #{y}px;' />")

append は、DOM要素の中に別のDOM要素を追加するメソッドです。追加するDOM要素はHTMLコードで記述できます。

この例では、文字列の中に #{x}#{y} という形で変数の値が埋め込まれています。書き方はRubyと同じで、わかりやすいですね。この書き方ができるのはCoffeeScriptのおかげです。純粋なJavaScriptでは、次のように書かなければなりません。

    canvas.append("<div class='block' style='left: " + x + "px; top: " + y + "px;' />")

動作を確認しましょう。ブラウザを再読込して、ページ上の灰色の部分を3カ所ダブルクリックすると次のような表示になります。

coffee01-0