mozilla
Vos résultats de recherche

    Dessiner avec Canvas

     

    Introduction

    Depuis Firefox 1.5, Firefox comprend un nouvel élément HTML servant à dessiner programmatiquement. L'élément <canvas> est basé sur la spécification canvas du WHATWG, elle-même basée sur la balise <canvas> d'Apple implémentée dans Safari. Celui-ci peut être utilisé pour afficher des graphes, des élements d'interface, et d'autres éléments graphiques personnalisés sur le client.

    <canvas> crée une surface de dessin de taille fixe, ou canevas, exposant un ou plusieurs contextes de rendu. Nous nous concentrerons sur le contexte de rendu 2D (c'est d'ailleurs le seul contexte de rendu actuellement défini). Dans le futur, d'autres contextes peuvent fournir différents types de rendu. Par exemple, il est probable qu'un contexte 3D basé sur OpenGL ES sera ajouté à la spécification <canvas>.

    Le contexte de rendu 2D

    Un exemple simple

    Pour commencer, voici un exemple simple qui dessine deux rectangles ayant une intersection, l'un d'entre-eux possédant une transparence alpha :

    Exemple 1.

    <html>
     <head>
      <script type="application/x-javascript">
    function draw() {
     var canvas = document.getElementById("canvas");
     var ctx = canvas.getContext("2d");
    
     ctx.fillStyle = "rgb(200,0,0)";
     ctx.fillRect (10, 10, 55, 50);
    
     ctx.fillStyle = "rgba(0, 0, 200, 0.5)";
     ctx.fillRect (30, 30, 55, 50);
    }
      </script>
     </head>
     <body onload="draw()">
       <canvas id="canvas" width="300" height="300"></canvas>
     </body>
    </html>
    

    La fonction draw récupère l'élément canvas, et ensuite son contexte 2d. L'objet ctx peut ensuite être utilisé pour dessiner réellement vers le canevas. L'exemple remplit simplement les deux rectangles, en positionnant fillStyle à deux couleurs différentes à l'aide des spécifications de couleur CSS et d'un appel à fillRect. Le second appel à fillStyle utilise rgba() pour spécifier une valeur alpha parmi les informations de couleur.

    Les appels à fillRect, strokeRect et clearRect affichent un rectangle plein, surligné ou vide. Pour afficher des formes plus complexes, on utilise des chemins.

    Utilisation de chemins

    La fonction beginPath commence un nouveau chemin, et moveTo, lineTo, arcTo, arc et des méthodes similaires sont utilisées pour ajouter des segments au chemin. Le chemin peut être fermé à l'aide de closePath. Une fois que le chemin est créé, vous pouvez utiliser fill ou stroke pour afficher celui-ci sur le canevas.

    Exemple 2.

    <html>
     <head>
      <script type="application/x-javascript">
    function draw() {
      var canvas = document.getElementById("canvas");
      var ctx = canvas.getContext("2d");
    
      ctx.fillStyle = "red";
    
      ctx.beginPath();
      ctx.moveTo(30, 30);
      ctx.lineTo(150, 150);
      ctx.bezierCurveTo(60, 70, 60, 70, 70, 150);
      ctx.lineTo(30, 30);
      ctx.fill();
    }
       </script>
     </head>
     <body onload="draw()">
       <canvas id="canvas" width="300" height="300"></canvas>
     </body>
    </html>
    

    L'appel à fill() ou stroke() provoque l'utilisation du chemin. Pour être rempli ou dessiné à nouveau, le chemin devra être recréé.

    État graphique

    Les attributs du contexte comme fillStyle, strokeStyle, lineWidth et lineJoin font partie de l'état graphique courant. Le contexte fournit deux méthodes, save() et restore(), qui peuvent être utilisées pour déplacer l'état courant vers et depuis la pile d'états.

    Un exemple plus compliqué

    Voici un exemple un petit peu plus compliqué, qui utilise des chemins, des états et introduit également la matrice de transformation courante. Les méthodes du contexte translate(), scale() et rotate() transforment toutes la matrice courante. Tous les points affichés sont au préalable transformés par cette matrice.

    Exemple 3.

     <html>
      <head>
       <script type="application/x-javascript">
     function dessineNoeudPap(ctx, fillStyle) {
     
       ctx.fillStyle = "rgba(200,200,200,0.3)";
       ctx.fillRect(-30, -30, 60, 60);
     
       ctx.fillStyle = fillStyle;
       ctx.globalAlpha = 1.0;
       ctx.beginPath();
       ctx.moveTo(25, 25);
       ctx.lineTo(-25, -25);
       ctx.lineTo(25, -25);
       ctx.lineTo(-25, 25);
       ctx.closePath();
       ctx.fill();
     }
     
     function point(ctx) {
       ctx.save();
       ctx.fillStyle = "black";
       ctx.fillRect(-2, -2, 4, 4);
       ctx.restore();
     }
     
     function dessine() {
       var canvas = document.getElementById("canvas");
       var ctx = canvas.getContext("2d");
    
       // notez que toutes les autres translations sont relatives à
       // celle-ci
       ctx.translate(45, 45);
    
       ctx.save();
       //ctx.translate(0, 0); // non nécessaire
       dessineNoeudPap(ctx, "red");
       point(ctx);
       ctx.restore();
     
       ctx.save();
       ctx.translate(85, 0);
       ctx.rotate(45 * Math.PI / 180);
       dessineNoeudPap(ctx, "green");
       point(ctx);
       ctx.restore();
     
       ctx.save();
       ctx.translate(0, 85);
       ctx.rotate(135 * Math.PI / 180);
       dessineNoeudPap(ctx, "blue");
       point(ctx);
       ctx.restore();
     
       ctx.save();
       ctx.translate(85, 85);
       ctx.rotate(90 * Math.PI / 180);
       dessineNoeudPap(ctx, "yellow");
       point(ctx);
       ctx.restore();
     }
        </script>
      </head>
      <body onload="dessine()">
        <canvas id="canvas" width="300" height="300"></canvas>
      </body>
     </html>
    

    Ceci définit deux méthodes dessineNoeudPap et point, qui sont appelées 4 fois. Avant chaque appel, translate() et rotate() sont utilisées pour définir la matrice de transformation courante, qui à son tour positionne le point et le nœud papillon. point affiche un petit carré noir centré sur (0, 0). Ce point est déplacé par la matrice de transformation. dessineNoeudPap affiche un chemin simple en forme de nœud papillon en utilisant le style de remplissage fourni en paramètre.

    Comme les opérations de matrices sont cumulatives, save() et restore() sont utilisées autour de chaque jeu d'appels afin de restaurer l'état initial du canevas. Une chose à surveiller est que la rotation se passe toujours autour de l'origine courante ; donc une séquence translate() rotate() translate() donnera des résultats différents d'une série d'appels translate() translate() rotate().

    Compatibilité avec le <canvas> d'Apple

    Pour la plus grande partie, le <canvas> de Mozilla est compatible avec celui d'Apple et d'autres implémentations. Il convient cependant d'être averti de quelques problèmes, décrits ci-dessous.

    Balise </canvas> requise

    Dans l'implémentation d'Apple Safari, <canvas> est un élément fortement semblable à l'élément <img> ; il ne doit pas forcément avoir de balise de fermeture. Cependant, pour que <canvas> puisse être utilisé à grande échelle sur le Web, il est important de pouvoir fournir facilement du contenu alternatif. C'est pourquoi l'implémentation de Mozilla a une balise de fin requise.

    Si aucun contenu alternatif n'est nécessaire, un simple <canvas id="foo" ...></canvas> sera entièrement compatible avec Safari et Mozilla -- Safari ignorera simplement la balise de fermeture.

    Si un contenu alternatif est désiré, certaines astuces CSS doivent être utilisées pour masquer le contenu alternatif à Safari (qui doit seulement afficher le canevas), et masquer ces mêmes astuces à Internet Explorer (qui doit afficher le contenu alternatif). À faire : les commandes CSS exactes doivent être fournies par hixie.

    Fonctionnalités supplémentaires

    Affichage de contenu Web dans un canevas

    Cette fonctionnalité est uniquement disponible pour le code exécuté avec des privilèges Chrome. Son utilisation n'est pas permise dans des pages HTML normales.

    L'élément canvas de Mozilla a été étendu avec la méthode drawWindow. Celle-ci dessine une capture du contenu d'un élément DOM window dans le canevas. Par exemple,

    ctx.drawWindow(window, 0, 0, 100, 200, "rgb(0,0,0)");
    

    affichera le contenu de la fenêtre courante dans le rectangle (0,0,100,200) défini en pixels relatifs au coin en haut à gauche de la fenêtre d'affichage, sur un fond noir, dans le canevas. En spécifiant "rgba(0,0,0,0)" comme couleur, le contenu sera dessiné avec un fond transparent (ce qui sera plus lent).

    Avec cette méthode, il est possible de remplir un IFRAME caché avec du contenu arbitraire (par exemple, du texte HTML stylé avec CSS, ou du SVG) et de le dessiner dans un canevas. Celui-ci sera redimensionné, tourné, etc. suivant la transformation courante.

    L'extension tab preview de Ted Mielczarek utilise cette technique dans le chrome pour fournir des miniatures de pages Web, et sa source est disponible pour référence.

    Voir aussi

    Étiquettes et contributeurs liés au document

    Étiquettes : 
    Dernière mise à jour par : emersion,