L'objet Canvas qui fait partie des spécifications du HTML5 permet de faire des dessins 2D enrichis et avec une vitesse raisonnable. Cet objet est disponible à partir de Internet Explorer 9 et de presque toutes les versions de Firefox et Chrome.

Néanmoins, leur implémentation diffère. En particulier, il semble que sous Windows 7 certains navigateurs reposent sur GDI+ alors que d'autres navigateurs reposent sur l'API plus récente, Direct2D. Il y a 2 conséquences :

  1. GDI+ étant plus lent que Direct2D, les navigateurs basés sur GDI+ dessineront plus lentement que ceux basés sur Direct2D
  2. GDI+ est un GDI 24 bits alors que Direct2D est un GDI 32 bits. C'est ce que j'expliquais dans cet article : Direct2D, un GDI 32 bits intéressant.

Du coup, pour déterminer quel navigateur utilise quel GDI, rien de tel qu'un canvas en html5 consistant à dessiner une ligne inclinée dont au moins une extrémité est en dehors du domaine [-223;-223]x [223-1;223-1].

Pour simplifier le dessin, on applique au canvas une transformation d'échelle et de translation afin que le coin inférieur gauche soit le point de coordonnées (-1; -1) et le coin supérieur droit le point de coordonnées (1; 1).

Créons un canvas :

    <canvas id="canvas" width="600" height="600">
</canvas>

Puis dessinons dans le canvas :

    var canvas = $('#canvas')[0];
    if (canvas.getContext)
    {
        // Init
        var ctxw = canvas.width;
        var ctxh = canvas.height;
        ctx = canvas.getContext("2d");
        ctx.save();
        ctx.fillStyle = "rgb(5,10,50)";
        ctx.fillRect(0, 0, ctxw, ctxh);
        ctx.beginPath();
        l1px = 2.0/ctxw;
        ctx.translate(ctxw/2, ctxh/2);
        ctx.scale(ctxw/2, ctxh/2);
       
// Draw line
        ctx.beginPath();
        ctx.lineWidth = l1px;
        ctx.strokeStyle = "blue";
        ctx.moveTo(-27965,-27965);
        ctx.lineTo(1,1);
        ctx.closePath();
        ctx.stroke();
       
        // Final
        ctx.restore();
    }

Le nombre "-27965" n'est pas un nombre magique. On verra à quoi il correspond ultérieurement. Voyons le résultat sur quelques navigateurs :

Internet Explorer 10 sous Windows 7 :

Dessin d'une ligne avec l'objet canvas sous Internet Explorer 10

Opera 12 sous Windows 7 :

Dessin d'une ligne avec l'objet canvas sous Opera 12

Firefox 20 sous Windows 7 :

Dessin d'une ligne avec l'objet canvas sous Firefox 20

Chrome canary 29 sous Windows 7 :

Dessin d'une ligne avec l'objet canvas sous Chrome canary 29

Chrome 26 sous Android 4.1.2 :

Dessin d'une ligne avec l'objet canvas sous Chrome 26 avec Android 4.2.1

On observe donc que tous les navigateurs précédents réussissent à dessiner la fameuse ligne, à l'exception notable de Firefox.

Revenons maintenant sur le nombre "-27965". On a vu que l'on a mis le dessin à l'échelle en divisant les dimensions par 600. Or, -27965*600=-16779000. Soit un nombre un peu inférieur à -223. C'est ce qui explique que l'on dessine en dehors du domaine 24 bits.

Remplaçons dans le code html le nombre "-27965" par "-27960". Alors, Firefox dessine parfaitement la ligne comme tous les autres navigateurs. Ça fonctionne aussi évidemment avec toutes les valeurs plus grandes (plus proches de 0).

En conclusion, il semble que Firefox soit le seul navigateur moderne à ne pas être basé sur l'API moderne Direct2D, mais sur GDI+. Cela signifie aussi que Firefox dispose d'une marge de progression.

Mais au fait, pourquoi vouloir dessiner des lignes dans un objet Canvas ? Par exemple pour implémenter un planétarium virtuel en html5 :

Dessin d'une d'une carte du ciel basique avec l'objet canvas sous Internet Explorer 10