JavaScriptをS式で(parenscript)
S式でJavaScriptを書けるライブラリ Parenscript。全部S式じゃないと嫌だっていう欲張りな貴方にピッタリ!ゆるふわ括弧な愛されWEBアプリが作れます!
実際のところ、letter: Parenscript で jQuery を使う場合は chain をで見かけて興味はあったけど今まで使わなかった。ので、Hackathonの時に書いたJavascriptをParenscriptで書き直してみたのでした。
Hackathonで書いていた JavaScriptはこんな有様。
var x = 0; var y = 0; var dx = 1; var dy = 1; var img = new Image(); img.src = 'http://www.lisperati.com/lisplogo_alien_128.png'; setInterval('draw()', 5); function draw() { var w = 128; var h = 75; var canvas = document.getElementById('alien-canvas'); if( !canvas || !canvas.getContext) { return false; } var ctx = canvas.getContext('2d'); ctx.fillRect(0, 0, 500, 500); if(x + dx + w <= 500 && 0 <= x + dx) { x += dx; } else { dx *= -1; } if(y + dy + h <= 500 && 0 <= y + dy) { y += dy; } else { dy *= -1; } ctx.drawImage(img, x, y); }
酷いですね。
やっていることは座標 x, y、移動量dx, dy、描画する画像を用意して 5ms間隔でdraw関数を呼び出し。draw関数は x座標に dx, y座標に dyを足して動かして描画する。画面から飛び出しそうになったら移動量の符号をを逆転させる。
以下がParenscriptで書いたコード
(ps (defvar x 0) (defvar y 0) (defvar dx 1) (defvar dy 1) (defvar img (new -image)) (setf (@ img src) "http://www.lisperati.com/lisplogo_alien_128.png") (set-interval "draw()" 5) (defun draw () (let ((w 128) (h 75) (canvas ((@ document get-element-by-id) "alien-canvas"))) (if (or (not canvas) (not (@ canvas get-context))) (return false)) (let ((ctx ((@ canvas get-context) "2d"))) ((@ ctx fill-rect) 0 0 500 500) (if (and (<= (+ x dx w) 500) (<= 0 (+ x dx))) (setf x (+ x dx)) (setf dx (* dx -1))) (if (and (<= (+ y dy h) 500) (<= 0 (+ y dy))) (setf y (+ y dy)) (setf dy (* dy -1))) ((@ ctx draw-image) img x y)))))
そして評価後
var x = 0; var y = 0; var dx = 1; var dy = 1; var img = new Image; img.src = 'http://www.lisperati.com/lisplogo_alien_128.png'; setInterval('draw()', 5); function draw() { var w = 128; var h = 75; var canvas = document.getElementById('alien-canvas'); if (!canvas || !canvas.getContext) { return false; }; var ctx = canvas.getContext('2d'); ctx.fillRect(0, 0, 500, 500); if (x + dx + w <= 500 && 0 <= x + dx) { x += dx; } else { dx *= -1; }; if (y + dy + h <= 500 && 0 <= y + dy) { y += dy; } else { dy *= -1; }; return ctx.drawImage(img, x, y); };
JavaScriptもCommon Lispで書けるなんて嬉しいですね。
- psの中がJavaScriptになる
- 大文字で出力すべき文字の前に "-"を置くと出力される識別子では大文字になる 例) get-element-by-id -> getElementById
- JavaScriptの関数呼び出しは、LISPの関数呼び出しと同じ
- let, let* などで局所変数を作れる
- setfで変数に代入
- @ は 第1引数.第2引数 という識別子として出力。これ単品ならプロパティ参照、もう一つ括弧で囲むとメソッド呼び出しになる