edo1z blog

プログラミングなどに関するブログです

HTML5 Canvas のIE8対応

最初ExplorerCanvasを使ってしまって、全然動かなかった。

参考:Internet Explorer 8でCanvasを動かす時のメモ

VMLCanvasを使うとよかったです。 https://code.google.com/p/mofmof-js/wiki/VMLCanvas

VMLCanvas.js は uuCanvas.js から Silverlight と Flash バックエンドを省略し、 コンパクトにパッケージしなおした JavaScript ライブラリです。mofmof.js に依存せず単体でも動作します。 ExplorerCanvas に比べ、より多くの機能をサポートしています。

canvasでグラフを表示してマウスオーバーでポップアップするようなものでしたが、結果的には全てIE10や、chromeなどと同じように表示することができました。

IEだけVML Canvasを読み込みます。

<!--[if IE]>
<?php echo $this->Html->script('VMLCanvas-1.1.1.min')?>
<![endif]-->

ie8かチェックする関数をつくります。

function check_ie8(){
    var userAgent = window.navigator.userAgent.toLowerCase();

    if (userAgent.indexOf('msie') != -1) {
        var appVersion=window.navigator.appVersion.toLowerCase();

        if (appVersion.indexOf("msie 6.") != -1) {
            return true;
        } else if (appVersion.indexOf("msie 7.") != -1) {
            return true;
        } else if (appVersion.indexOf("msie 8.") != -1) {
            return true;
        }else{
            false;
        }
    }else{
        return false;
    }
}

ie8以外の場合は、$(window).loadを使い、ie8の場合は、window.oncanvasreadyを使います。

$(window).load(function () {
    if(check_ie8()) return;

    canvas = document.getElementById("hoge_canvas");
    C = canvas.getContext("2d");
    init();
    images[num].onload = function(){
        draw();
        timerID = setInterval ('check_on_mouse()', 33);
    }
});

window.oncanvasready = function(canvasNodeList) {
    if(!check_ie8()) return;
    ie8 = true;

    canvas = document.getElementById("hoge_canvas");
    C = canvasNodeList[0].getContext("2d");

    init();
    draw();
    timerID = setInterval ('check_on_mouse()', 33);
};

これで全部表示されました。スクリプト分けるとメンテが大変なので一つにしようと思って上記のようにしました。images.onloadを使うとie8で動かなかったのでとりあえず外しました。

マウスオーバーチェックは、下記のようになりました。

function check_on_mouse(){
    canvas.onmousemove = getMousePoint;

    function getMousePoint (e) {
        if(ie8){
            e = event;
            mouse_x = e.x;
            mouse_y = e.y;
        }else{
            var rect = e.target.getBoundingClientRect();
            mouse_x = e.clientX - rect.left;
            mouse_y = e.clientY - rect.top;
        }

        //mouse_xとmouse_yがプロットされてるアイテムに重なってればポップアップする処理など
    }
}

ie8の場合、e.targetというのが使えないので、その変わりにsrcElementというのを使うのですが、それでやってもrectの値がおかしくて使えませんでした。e.xがmouse_xとほぼ同じになるので、上記のようにしました。