HTML5 Canvas

John Samuel
CPE Lyon

Année: 2022-2023
Courriel: john(dot)samuel(at)cpe(dot)fr

Creative Commons License

1.1. Objectifs

Objectifs

1.2. HTML5 Canvas: Histoire

Histoire

Remarque: Vérifiez la compatibilité de votre navigateur https://caniuse.com/?search=Canvas

1.3. Fonctionnement

canvas

<body>
...
 <canvas id="moncanvas" width="300" height="400">
 </canvas>
...
</body>

1.3. Fonctionnement

canvas

 <canvas id="moncanvas" width="300" height="400">
 </canvas>

1.3. Fonctionnement

canvas

 <canvas id="moncanvas" width="300" height="400">
 </canvas>

1.3. Fonctionnement

getContext(...)

<body>
...
 <canvas id="moncanvas" width="300" height="400">
 </canvas>
 <script>
  var id = document.getElementById("moncanvas");
  var context = id.getContext("2d");
 </script>
...
</body>

1.3. Fonctionnement

canvas

Dans le body d'un fichier HTML

 <canvas id="moncanvas" width="300" height="400">
 </canvas>

1.3. Fonctionnement

canvas

Dans un fichier Javascript ou dans <script>...</script>

 <script>
  var id = document.getElementById("moncanvas");
  var context = id.getContext("2d");
 </script>

1.3. Fonctionnement

style.backgroundColor

Changer la couleur du fond

  id.style.backgroundColor = "green";

1.3. Fonctionnement

width, height

Changer l'hauteur et la largeur d'un canvas

  var id = document.getElementById("moncanvas");
  id.setAttribute("width", 500);
  id.setAttribute("height", 600);

1.3. Fonctionnement

3D en utilisant le contexte WebGL

<body>
...
 <canvas id="moncanvas3D" width="300" height="400">
 </canvas>
 <script>
  var id = document.getElementById("moncanvas3D");
  var context = id.getContext("webgl");
 </script>
...
</body>

1.4. Grille

1.5. Ligne

lineTo(...)

<body>
...
 <canvas id="ligne" width="300" height="400">
 </canvas>
 <script>
  var id = document.getElementById("ligne");
  var context = id.getContext("2d");

  context.strokeStyle = "#00b33c";
  context.lineWidth = 10;
  context.moveTo(0,0);
  context.lineTo(300,400);
  context.stroke();
 </script>
...
</body>

1.5. Ligne

lineTo(...)

 <canvas id="ligne" width="300" height="400">
 </canvas>
 <script>
  var id = document.getElementById("ligne");
  var context = id.getContext("2d");

  context.strokeStyle = "#00b33c";
  context.lineWidth = 10;
  context.moveTo(0,0);
  context.lineTo(300,400);
 </script>
...

1.5. Ligne

lineTo(...)

<body>
...
 <canvas id="ligne" width="300" height="400">
 </canvas>
 <script>
  var id = document.getElementById("ligne");
  var context = id.getContext("2d");

  context.strokeStyle = "#00b33c";
  context.lineWidth = 10;
  context.moveTo(300,0);
  context.lineTo(0,400);
  context.stroke();
 </script>
...
</body>

1.5. Ligne

beginPath()

  context.beginPath();
  context.strokeStyle = "#00b33c";
  context.moveTo(0,0);
  context.lineTo(300,400);
  context.stroke();

1.5. Lignes

beginPath()

  context.beginPath();
  context.strokeStyle = "#00b33c";
  context.moveTo(0,0);
  context.lineTo(300,400);

  context.strokeStyle = "red";
  context.moveTo(0,400);
  context.lineTo(300,0);
  context.stroke();

1.5. Lignes

beginPath()

  context.beginPath();
  context.strokeStyle = "#00b33c";
  context.moveTo(0,0);
  context.lineTo(300,400);
  context.stroke();

  context.beginPath();
  context.strokeStyle = "red";
  context.moveTo(0,400);
  context.lineTo(300,0);
  context.stroke();

1.6. Arc

arc(...)

  context.beginPath();
  context.arc(200, 150, 100, Math.PI, 1.5 * Math.PI);
  context.stroke();

1.6. Arc

arc(...)

  context.beginPath();
  context.arc(200, 150, 100, Math.PI, 1.5 * Math.PI, true);
  context.stroke();

1.6. Arc

arc(...)

  context.beginPath();
  context.arc(x, y, rayon, angleInitial, angleFinal, antihoraire);
  context.stroke();

Remarque: Les angles dans la fonction arc sont mesurés en radians.
Rappel: 1 radian = 360 / (2π)

1.6. Arc

arcTo(...)

  context.beginPath();
  context.moveTo(0,70);
  context.lineTo(140,70);
  context.arcTo(200, 70, 200, 270, 50);
  context.lineTo(200, 270);
  context.stroke();

1.6. Arc

arcTo(...)

  context.beginPath();
  context.fillStyle = "#00b33c";
  context.moveTo(0,70);
  context.lineTo(140,70);
  context.arcTo(200, 70, 200, 270, 50);
  context.lineTo(200, 270);
  context.fill();

1.6. Arc

arcTo(...)

  context.beginPath();
  context.arcTo(x1, y1, x2, y2, rayon);
  context.stroke();

Exemple

  context.arcTo(350, y, 710, 20, 150);

1.7. Lignes et Arcs

sans moveTo()

  context.beginPath();
  context.strokeStyle = "#00b33c";
  context.moveTo(0,0);
  context.lineTo(250,400);

  context.arc(100,150, 50, 0, 2*Math.PI);
  context.stroke();

1.7. Lignes et Arcs

avec moveTo()

  context.beginPath();
  context.strokeStyle = "#00b33c";
  context.moveTo(0,0);
  context.lineTo(250,400);

  context.moveTo(150,150);
  context.arc(100,150, 50, 0, 2*Math.PI);
  context.stroke();

1.8. Courbe

Courbe de Bézier quadratique

quadraticCurveTo(...)

  context.beginPath();
  quadraticCurveTo(cp1x, cp1y, x, y);
  context.stroke();

1.8. Courbe

quadraticCurveTo(...)

  context.beginPath();
  context.moveTo(0,70);
  context.lineTo(120,70);
  context.quadraticCurveTo(280, 120, 200, 270);
  context.stroke();

1.8. Courbe

Courbe de Bézier cubique: quadraticCurveTo(...)

  context.beginPath();
  quadraticCurveTo(cp1x, cp1y, x, y);
  context.stroke();

1.8. Courbe

Courbe de Bézier cubique: bezierCurveTo(...)

  context.beginPath();
  bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);
  context.stroke();

1.8. Courbe

Courbe de Bézier cubique: bezierCurveTo(...)

  context.beginPath();
  context.moveTo(0,70);
  context.lineTo(120,70);
  context.bezierCurveTo(280, 120, 240, 220, 150, 270);
  context.stroke();

1.8. Courbe

Courbe de Bézier cubique: bezierCurveTo(...)

  context.beginPath();
  bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y);
  context.stroke();

1.9. Cercle

Cercle en utilisant arc(...)

  context.beginPath();
  context.arc(150, 150, 100, 0, 2 * Math.PI);
  context.stroke();

1.10. Ellipse

ellipse(...)

  context.beginPath();
  context.ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle [, anticlockwise]);
  context.stroke();

1.11. Ellipse

ellipse(...)

  context.beginPath();
  context.ellipse(150, 180, 100, 150, Math.PI/4, 0, 2 * Math.PI);
  context.stroke();

1.12. Path2D

Path2D(...)

1. Crée un objet chemin vide

  Path2D();

2. Copie d'un autre objet Path2D

  Path2D(chemin);

3. Crée le chemin à partir des données de chemin SVG

  Path2D(cheminsvg);

1.12. Path2D

Path2D(...)

  var id = document.getElementById("moncanvas");
  var context = id.getContext("2d");
  var cercle = new Path2D();
  cercle.arc(150, 150, 100, 0, 2 * Math.PI);
  context.stroke(cercle);

1.12. Path2D

Path2D(...)

  var id = document.getElementById("moncanvas");
  var context = id.getContext("2d");
  var cercle = new Path2D();
  cercle.arc(150, 150, 100, 0, 2 * Math.PI);
  context.fillStyle = "#00b33c";
  context.fill(cercle);

1.13. Rectangle

rect(...)

  context.lineWidth = 10;
  context.rect(10, 10, 280, 280);
  context.stroke();

1.13. Rectangle

rect(...)

  context.strokeStyle = "#00b33c";
  context.rect(x, y, largeur, hauteur);
  context.stroke();

  context.strokeStyle = "#00b33c";
  context.strokeRect(x, y, largeur, hauteur);

  context.fillStyle = "#00b33c";
  context.fillRect(x, y, largeur, hauteur);

1.13. Rectangle

fillRect(...)

  context.fillStyle = "#00b33c";
  context.fillRect(10, 10, 280, 280);

1.14. Les couleurs: style et transparence

fillStyle

  context.fillStyle = "green";
  context.fillRect(10, 10, 140,140);
  context.fillStyle = "#00b33c";
  context.fillRect(150, 10, 140,140);
  context.fillStyle = "rgb(100,255,100)";
  context.fillRect(10, 150, 140, 140);
  context.fillStyle = "rgba(100,255,100,0.4)";
  context.fillRect(150, 150, 140, 140);

1.14. Les couleurs: style et transparence

fillStyle

  context.fillStyle = "red";
  context.arc(150, 150, 100, 0, 2 * Math.PI);
  context.fill();
  context.fillStyle = "rgba(100,255,100,1)";
  context.fillRect(10, 10, 140,140);
  context.fillStyle = "rgba(100,255,100,0.7)";
  context.fillRect(150, 10, 140,140);
  context.fillStyle = "rgba(100,255,100,0.5)";
  context.fillRect(10, 150, 140, 140);
  context.fillStyle = "rgba(100,255,100,0.3)";
  context.fillRect(150, 150, 140, 140);

1.15. Les couleurs: gradients

fillStyle

  var lingradient = context.createLinearGradient(10, 10, 10, 340);
  lingradient.addColorStop(0, "blue");
  lingradient.addColorStop(0.5, "#ff0000");
  lingradient.addColorStop(1, "#ffffff");
  context.fillStyle = lingradient;
  context.fillRect(10, 10, 240,340);

1.15. Les couleurs: gradients

fillStyle

  var radialgradient = context.createRadialGradient(140, 140, 10, 140, 140, 100);
  radialgradient.addColorStop(0, "blue");
  radialgradient.addColorStop(0.5, "green");
  radialgradient.addColorStop(1, "#ffffff");
  context.fillStyle = radialgradient;
  context.fillRect(10, 10, 240,340);

1.16. Polygone

Polygone en utilisant lineTo()

  context.beginPath();
  context.strokeStyle = "#00b33c";
  context.moveTo(10, 10);
  context.lineTo(150, 380);
  context.lineTo(280, 10);
  context.closePath();
  context.stroke();

1.16. Polygone

Polygone en utilisant lineTo()

  context.beginPath();
  context.fillStyle = "#00b33c";
  context.moveTo(10, 10);
  context.lineTo(150, 380);
  context.lineTo(280, 10);
  context.closePath();
  context.fill();

1.16. Polygone

Polygone en utilisant lineTo()

  context.beginPath();
  context.strokeStyle = "#00b33c";
  context.moveTo(10, 200);
  context.lineTo(80, 10);
  context.lineTo(200, 10);
  context.lineTo(270, 200);
  context.lineTo(200, 380);
  context.lineTo(80, 380);
  context.closePath();
  context.stroke();

1.16. Polygone

Polygone en utilisant lineTo()

  context.beginPath();
  context.fillStyle = "#00b33c";
  context.moveTo(10, 200);
  context.lineTo(80, 10);
  context.lineTo(200, 10);
  context.lineTo(270, 200);
  context.lineTo(200, 380);
  context.lineTo(80, 380);
  context.lineTo(80, 380);
  context.closePath();
  context.fill();

1.17. Effacer une zone

clearRect()

  context.clearRect(90, 140, 100, 100);

1.18. Texte

strokeText()

  context.font = "40px Arial";
  context.strokeText("Bonjour!", 100, 100);

1.18. Texte

fillText()

  context.font = "40px Arial";
  context.fillText("Bonjour!", 100, 100);

1.18. Texte

strokeText()

  context.font = "40px Arial";
  context.strokeText("Bonjour!", 100, 100);

1.19. L'alignement du texte

textAlign()

context.font = "30px Arial";
context.textAlign = "start";
context.fillText("début", 250, 20);

context.textAlign = "end";
context.fillText("fin1 fin2 fin3 fin4 fin5 fin6", 250, 100);

context.textAlign = "left";
context.fillText("gauche1 gauche2 gauche3 gauche4", 250, 180);

context.textAlign = "right";
context.fillText("droite1 droite2 droite3 droite4", 250, 260);

context.textAlign = "center";
context.fillText("centre", 250, 340);

1.20. L'alignement de base

textBaseline()

context.font = "20px Arial";
context.textBaseline = "top";
context.fillText("haut", 0, 200);

context.textBaseline = "middle";
context.fillText("moyen", 150, 200);

context.textBaseline = "alphabetic";
context.fillText("alphabetique", 250, 200);

context.textBaseline = "bottom";
context.fillText("en bas", 420, 200);

1.21. Images

drawImage()

context.drawImage(image, dx, dy);
context.drawImage(image, dx, dy, dLargeur, dHauteur);
context.drawImage(image, sx, sy, sLargeur, sHauteur, dx, dy, dLargeur, dHauteur);

1.21. Images

drawImage()

 var img = new Image();
 img.src = "img.png";
 img.onload = function() {
  context.drawImage(img, 0, 0);
}

1.21.1. Images: Mise à l'échelle

drawImage()

 var img = new Image();
 img.src = "img.png";
 img.onload = function() {
  context.drawImage(img, 0, 0, 500, 400);
}

1.21.1. Images: Mise à l'échelle

drawImage(...)

 var img = new Image();
 img.src = "img.png";
 img.onload = function() {
  context.drawImage(img, 0, 0, 250, 200);
  context.drawImage(img, 250, 0, 250, 200);
  context.drawImage(img, 0, 200, 250, 200);
  context.drawImage(img, 250, 200, 250, 200);
}

1.21.1. Images: Mise à l'échelle

scale(...)

 var img = new Image();
 img.src = "img.png";
 img.onload = function() {
  context.scale(0.5, 0.5);
  context.drawImage(img, 200, 0, 200, 200);
}

1.21.2. Images: Découpage

drawImage(...)

 var img = new Image();
 img.src = "img.png";
 img.onload = function() {
  context.drawImage(img, 100, 100, 500, 400, 250, 250, 150, 150);
}

1.21.3. Images: Rotation

rotate(...)

 var img = new Image();
 img.src = "img.png";
 img.onload = function() {
  context.rotate(10*Math.PI/180);
  context.drawImage(img, 200, 0, 200, 200);
}

1.21.4. Image: Déplacement

translate(...)

 var img = new Image();
 img.src = "img.png";
 img.onload = function() {
  context.drawImage(img, 0, 0, 200, 200);
  context.translate(200, 200);
  context.drawImage(img, 0, 0, 400, 400);
}

1.21.5. Images: Transformation

transform(...)

  context.transform(hs, vsk, hsk, vs, dx, dy);

correspondant à la matrice de transformation:

hs: mise à l'échelle horizontale hsk: inclinaison horizontale dx: translation horizontale
vsk: inclinaison verticale vs: mise à l'échelle verticale dy: translation verticale
0 0 1

Remarque: Si hs ou vs est égal à 1, il n'y aura pas de changement d'échelle dans le sens horizontal ou vertical respectivement. Si dx ou dy est égal à 0, il n'y aura aucun déplacement horizontal ou vertical.

1.21.5. Images: Transformation

transform(...)

 var img = new Image();
 img.src = "img.png";
 img.onload = function() {
  context.drawImage(img, 0, 0, 200, 200);
  context.transform(0.5, 0.5, -0.5, 0.5, 300,10);
  context.drawImage(img, 0, 0, 400, 400);
}

1.22.1. Interaction: Clavier

keyCode

 document.onkeydown = function(event) {
  event = event || window.event;
  event.preventDefault();

  if (event.keyCode == '37') {
   // gauche
  }
  else if (event.keyCode == '38') {
   // haut
  }
  else if (event.keyCode == '39') {
   // droite
  }
  else if (event.keyCode == '40') {
   // bas
  }
 }

1.22.1. Interaction: Clavier

key

 document.onkeydown = function(event) {
  event = event || window.event;
  event.preventDefault();

  if (event.key === "ArrowLeft") {
   // gauche
  }
  else if (event.key === "ArrowUp") {
   // haut
  }
  else if (event.key === "ArrowRight") {
   // droite
  }
  else if (event.key === "ArrowDown") {
   // bas
  }
 }

1.22.2. Interaction: Souris

pageX, pageY, offsetLeft, offsetTop

 document.getElementById("moncanvas").onmousedown = function(event) {
  event = event || window.event;
  event.preventDefault();

  var posX = event.pageX - canvas.offsetLeft;
  var posY = event.pageY - canvas.offsetTop;
}

1.22.2. Interaction: Souris

pageX, pageY, offsetLeft, offsetTop

 document.getElementById("moncanvas").onmousedown = function(event) {
  event = event || window.event;
  event.preventDefault();

  var posX = event.clientX - canvas.getBoundingClientRect().x;
  var posY = event.clientY - canvas.getBoundingClientRect().y;
}

1.22.2. Interaction: Souris

onmouseup

document.body.onmouseup = function(event) {
  event = event || window.event;
  event.preventDefault();
}

1.23. Animation

window.requestAnimationFrame(..)

var y = 0;
function courbequadratique() {
  var id = document.getElementById("courbequadratiqueanimated");
  var context = id.getContext("2d");
  ...
  // Modification du variable y
  context.quadraticCurveTo(350, y, 710, 20);
  ...
  window.requestAnimationFrame(courbequadratique);
}

window.requestAnimationFrame(courbequadratique);

1.23. Animation

window.requestAnimationFrame(..)

var y = 0, x1 = 10, x2 = 710;

# Animation de la courbe de bézier
function courbebezieranimated() {
  var id = document.getElementById("courbebezieranimated");
  var context = id.getContext("2d");
  ...
  // Modification des variables x1, x2
  context.bezierCurveTo(x1, y, x2, y, 710, 20);
  window.requestAnimationFrame(courbebezieranimated);
}
window.requestAnimationFrame(courbebezieranimated);

2.1. HTML5 Canvas et SVG

Canvas et SVG

SVG Canvas
Pour les images vectorielles Pour les images matricielles
XML Javascript
Manipulation facile des événements du DOM Correspondence des coordonnées du pointeur et d'image

2.2. SVG

svg

<svg width="200" height="200"
  xmlns="http://www.w3.org/2000/svg">
  ...
</svg>

2.3. SVG: Rectangle

rect

<svg width="200" height="200"
  xmlns="http://www.w3.org/2000/svg">
  <rect height=200 width=200 fill="green">
</svg>

2.4. SVG: Cercle

circle

<svg width="200" height="200"
  xmlns="http://www.w3.org/2000/svg">
  <circle cx=100 cy=100 r=50 fill="red">
</svg>

2.5. SVG: Ellipse

ellipse

                  <svg width="200" height="200"
                     xmlns="http://www.w3.org/2000/svg">
                     <ellipse cx=100 cy=100 rx=80 ry=40 fill="red">
                  </svg>

2.6. SVG: Lignes

line

                  <svg width="200" height="200"
                     xmlns="http://www.w3.org/2000/svg">
                     <line x1=0 y1=0 x2=200 y2=200 stroke="red" stroke-width=10>
                  </svg>

2.7. SVG: Polylignes

polyline

                  <svg width="200" height="200"
                     xmlns="http://www.w3.org/2000/svg">
                     <polyline points="0 0 180 180 0 180"
                       fill="none"
                       stroke="red" stroke-width=10 />
                  </svg>

2.8. SVG: Polygon

polygon

                  <svg width="200" height="200"
                     xmlns="http://www.w3.org/2000/svg">
                     <polygon points="30 30 180 180 30 180"
                       fill="none"
                       stroke="red" stroke-width=10 />
                  </svg>

2.9. SVG: Chemin

path

                  <svg width="200" height="200"
                     xmlns="http://www.w3.org/2000/svg">
                     <path d="M30 30 L 180 180 L 30 180"
                       fill="none"
                       stroke="red" stroke-width=10 />
                  </svg>

2.9. SVG: Chemin

path

                  <svg width="200" height="200"
                     xmlns="http://www.w3.org/2000/svg">
                     <path d="M30 30 L 180 180 L 30 180"
                       fill="none"
                       stroke="red" stroke-width=10 />
                  </svg>

2.10. SVG: Textes

text

Bonjour
                  <svg width="200" height="200"
                     xmlns="http://www.w3.org/2000/svg">
                     <text x="40" y="40" stroke="red" fill="red">Bonjour</text>
                  </svg>

2.11. SVG: Textes et Chemin

textPath

Bonjour le Monde! Canvas
                  <svg width="200" height="200"
                     xmlns="http://www.w3.org/2000/svg">
                     <path d="M30 30 L 180 180 L 30 180"
                       fill="transparent"
                       id="tpath"
                       stroke-width=10 />
                     <text stroke="red" fill="red">
                       <textPath xmlns:xlink="http://www.w3.org/1999/xlink"
                                 xlink:href="#tpath">
                          Bonjour le Monde! Canvas
                       </textPath>
                     </text>
                  </svg>

3.1. Média

iframe

3.2. Iframe média

iframe

<iframe id="accueil"
  title="accueil"
  width="500"
  height="400"
  src="./index.html">
</iframe>

3.2. Iframe média

iframe


View Larger Map
 <iframe id="openstreetmap" width="425" height="350"
     frameborder="0" scrolling="no" marginheight="0"
     marginwidth="0"
     src="https://www.openstreetmap.org/export/embed.html?bbox=4.7606849670410165%2C45.708696659903026%2C4.975776672363282%2C45.800443408584&amp;layer=mapnik"
     style="border: 1px solid black">
</iframe>

3.2. Iframe Média

iframe

<iframe id="mainpage" title="main page"
        width="500" height="400"
        src="https://commons.wikimedia.org/wiki/Flowers">
</iframe>

3.3. Média: vidéos

video

<video controls width="250">
   <source
       src="https://upload.wikimedia.org/wikipedia/commons/a/ab/Tui_feeding_from_flax_flowers_Wellington.ogv"
       type="video/ogg">
   Désolé, votre navigateur ne prend pas en charge les vidéos intégrées.
</video>

3.5. Média: vidéos

video

<video controls width="250">
  <source src="...ogv"
    type="video/ogg">
  <source src="...mp4"
    type="video/mp4">
      Désolé, votre navigateur ne prend pas en charge les vidéos intégrées.
</video>

3.5. Média: audio

audio

<audio controls
       src="https://upload.wikimedia.org/wikipedia/commons/9/98/Schumann_Prophet_Bird_from_Waldszenen.wav">
      Your browser does not support the <code>audio</code> element.
</audio>

3.5. Média: audio

audio

<audio
   controls
   src=".wav">
    Votre navigateur ne supporte pas l'élément audio.
</audio>

HTML5 Canvas: Références

Références

HTML5 Canvas: Références

Références

Crédits d'images