東京NODE学園祭2011に行ってきた
体調悪くてぼやっとしてたんだけど、Guillermo Rauchさんのライブコーディングになって目が覚めた。Twitterでも驚きの声多数って感じだったんだけど、アレはすごいわ。タイピングの速さも異常だけど(最初本当に今やってるのか疑ってしまったよ)、見てて飽きない題材で(canvasを使ってブラウザ上で絵を描いて、最終的にはそのデータをサーバに送って動画にする)複雑にならないように極力シンプルなコードをその場で説明しながら書いて行く様は、本当にびっくりした。
ということで、そのときのコードを思い出しながら書いてみたが、サーバ側はちょっと手を抜いてブラウザで書いた絵をそのままtest.pngとして出力しているだけ。あと、本当はSocket.IOとか使ってごにょごにょという話だったきもするけど、忘れちゃった。
<html> <style> body { margin: 0; padding: 0; background-color: #eee; } #c { background-color: #fff; border-bottom: solid #999 1px; } </style> <script> window.onload = function() { var canvas = document.getElementById('c') , ctx = canvas.getContext('2d') , noop = function() {} , result = null , history = []; ctx.strokeStyle = 'red'; window.onmousedown = function() { console.log('down'); ctx.beginPath(); result = []; result[0] = ctx.strokeStyle; result[1] = []; window.onmousemove = function(e) { move(e.clientX, e.clientY); } } window.onmouseup = function() { history.push(result); ctx.stroke(); window.onmousemove = noop; } function move(x, y) { result[1].push([x, y]); ctx.lineTo(x, y); ctx.stroke(); } var color = document.getElementById('color'); color.onclick = function() { var c = prompt('Stroke color'); ctx.strokeStyle = c; } var send = document.getElementById('send'); send.onclick = function() { console.log(history); xhr = new XMLHttpRequest(); xhr.open('POST', '/', true); xhr.setRequestHeader('Content-Type', 'application/json'); xhr.send(JSON.stringify(history)); } } </script> <body> <canvas id="c" width="600" height="400"></canvas><br /> <input type="button" id="color" value="color"></input> <input type="button" id="send" value="send"></input> </body> </html>
Node.js側のコード
var express = require('express') , fs = require('fs') , Canvas = require('canvas') , canvas = new Canvas(600, 400) , ctx = canvas.getContext('2d'); var app = express.createServer(); app.use(express.bodyParser()); app.get('/', function(req, res) { fs.readFile(__dirname + '/public/index.html', 'utf8', function(err, text){ res.send(text); }); }); app.post('/', function(req, res) { console.log(req.body); ctx.fillStyle = '#fff'; ctx.fillRect(0,0,600,400); var history = req.body; for (var i in history) { var result = history[i]; ctx.beginPath(); ctx.strokeStyle = result[0]; for (var j in result[1]) { var pos = result[1][j]; ctx.lineTo(pos[0], pos[1]); } ctx.stroke(); } var out = fs.createWriteStream(__dirname + '/test.png') , stream = canvas.createPNGStream(); stream.on('data', function(chunk) { out.write(chunk); }); canvas.toBuffer(); }); app.listen(3000);
いや、もっと奇麗なコードだったと思うんだけど。
インストールしたとは以下の通り。expressはnode.jsのwebフレームワーク。canvasってのがサーバサイドでHTML5のcanvas?を使えるようにするやつ。cairoってのはcanvasをインストールするのに必要だった。なぜかこれのインストールではまった。はじめbrewで入れようとしたんだけどうまく行かなくて、この前削除したMac portで試してたんだけどそれでもうまくいかなかったんだけど、portをselfupdateしたあとにもう一回インストールしたらなんとかうまくいった。
$ npm install express $ sudo port install cairo $ npm install canvas