下林明正のブログ

個人的かつ雑多なブログです。

Cosm Graphsを更新した際に知ったJavaScriptの小ネタ

Cosm Graphs

shimobayashi/cosm-graphs · GitHub

諦めていたグラフのオーバーレイ表示に対応しました。 いくつか有用な話題があったのでメモしておこうと思う。

canvasのsame origin policyをJSONPを経由して回避する

canvasで画像処理をする際にもsame origin policyが適用されます。 セキュリティ上の理由ということは理解できるのですが、実際のところ www.shimobayashi.name で cosm.com の画像を取得してピクセルデータを操作して表示するということができなくなるので、不便です。

この挙動を、指定したURLの内容をBase64で返すJSONP APIを経由することで回避することができます(id:hitode909 に教えてもらった)。

この辺りを参考に、

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);
    });

こういう書き方ができる。 全ての並列処理の完了を待つ、という記述をこれだけ簡潔にできるのは、やはり良いと思う。