shimobayashi/cosm-graphs · GitHub
諦めていたグラフのオーバーレイ表示に対応しました。 いくつか有用な話題があったのでメモしておこうと思う。
canvasのsame origin policyをJSONPを経由して回避する
canvasで画像処理をする際にもsame origin policyが適用されます。 セキュリティ上の理由ということは理解できるのですが、実際のところ www.shimobayashi.name で cosm.com の画像を取得してピクセルデータを操作して表示するということができなくなるので、不便です。
この挙動を、指定したURLの内容をBase64で返すJSONP APIを経由することで回避することができます(id:hitode909 に教えてもらった)。
- Processing.jsでドメイン外の画像をPImageとして扱う #processing #javascriptグラフィックス #JavaScript #canvas - Qiita
- Canvas に Base64 の画像を差し込む時も image の onload を待つ必要がある - oogattaの勉強日記
この辺りを参考に、
function loadImage(klass) { var dfd = $.Deferred(); $.ajax({ type: 'GET', url: 'http://kjunurl.appspot.com/imgview', dataType: 'jsonp', jsonp: 'callback', data: { host: 'api.cosm.com', path: getImagePath(klass), }, }).done(function(data) { var image = new Image(); image.src = data.image; image.onload = function() { dfd.resolve(image); }; }); return dfd; }
このようなコードで実現できました。
jQuery Deferredで並列処理を綺麗に書いてみる
方方で散々既出かと思いますが、自分で書いてみて結構感動したのでメモしておく。
先述の関数と組み合わせて、
$.when( loadImage('temperature'), loadImage('humidity'), loadImage('pressure') ).done(function(temperature, humidity, pressure) { clear(room_graphs); draw(room_graphs, pressure, -32, 0); draw(room_graphs, humidity, 0, 0); draw(room_graphs, temperature, 0, 0); }); $.when( loadImage('tremor'), loadImage('sound-level') ).done(function(tremor, sound_level) { clear(bed_graphs); draw(bed_graphs, tremor, -10, 0); draw(bed_graphs, sound_level, 0, 0); });
こういう書き方ができる。 全ての並列処理の完了を待つ、という記述をこれだけ簡潔にできるのは、やはり良いと思う。