diff options
author | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:40:17 -0500 |
---|---|---|
committer | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:40:17 -0500 |
commit | 33058f2b292b3a581333bdfb21b8f671898c5060 (patch) | |
tree | 51c3e392513ec574331b2d3f85c394445ea803c6 /files/fr/web/api/canvas_api | |
parent | 8b66d724f7caf0157093fb09cfec8fbd0c6ad50a (diff) | |
download | translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.tar.gz translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.tar.bz2 translated-content-33058f2b292b3a581333bdfb21b8f671898c5060.zip |
initial commit
Diffstat (limited to 'files/fr/web/api/canvas_api')
15 files changed, 4013 insertions, 0 deletions
diff --git a/files/fr/web/api/canvas_api/index.html b/files/fr/web/api/canvas_api/index.html new file mode 100644 index 0000000000..a697d99b2a --- /dev/null +++ b/files/fr/web/api/canvas_api/index.html @@ -0,0 +1,168 @@ +--- +title: API canvas +slug: Web/API/Canvas_API +tags: + - API + - Canvas + - Reference +translation_of: Web/API/Canvas_API +--- +<div>{{IncludeSubnav("/fr/docs/Jeux")}} {{CanvasSidebar}}</div> + +<p class="summary">Ajouté en <a href="https://developer.mozilla.org/fr/docs/Web/Guide/HTML/HTML5">HTML5</a>, l'élément {{HTMLElement("canvas")}} est un nouvel élément qui peut être utilisé pour dessiner des graphismes via des scripts <a href="/fr/docs/JavaScript" title="fr/docs/JavaScript">JavaScript</a>. Par exemple, Il peut être utilisé pour dessiner des graphes, faire des compositions de photos, des animations, ou même faire du traitement ou de l'affichage de vidéos en temps réel.</p> + +<p>Les applications Mozilla ont commencé à supporter <canvas> à partir de Gecko 1.8 (c'est-à-dire <a href="/fr/docs/Firefox_1.5_pour_les_développeurs" title="fr/docs/Firefox_1.5_pour_les_développeurs">Firefox 1.5</a>). L'élément a été introduit à l'origine par Apple pour le <a class="external" href="http://www.apple.com/macosx/features/dashboard/">Dashboard d'OS X</a> et pour Safari. Internet Explorer supporte <canvas> depuis la version 9 et ultérieures, pour les versions précédentes d'IE, une page peut effectuer ce support de <canvas> en incluant un script depuis le projet <a href="http://excanvas.sourceforge.net/">Explorer Canvas </a>de Google.</p> + +<p>L'élément <canvas> est aussi utilisé par <a href="https://developer.mozilla.org/fr/docs/Web/API/WebGL_API">WebGL</a> pour afficher des graphismes 3D avec accélération matérielle sur des pages web.</p> + +<h2 id="Exemple">Exemple</h2> + +<p>Voilà un simple extrait de code qui utilise la méthode {{domxref("CanvasRenderingContext2D.fillRect()")}}.</p> + +<h3 id="HTML">HTML</h3> + +<pre class="brush: html notranslate"><canvas id="canvas"></canvas> +</pre> + +<h3 id="JavaScript">JavaScript</h3> + +<pre class="brush: js notranslate">var canvas = document.getElementById('canvas'); +var ctx = canvas.getContext('2d'); + +ctx.fillStyle = 'green'; +ctx.fillRect(10, 10, 100, 100); +</pre> + +<p>Éditez le code ci-dessous pour voir les changements avoir lieu directement dans le canvas:</p> + +<div class="hidden"> +<h6 id="Playable_code">Playable code</h6> + +<pre class="brush: html notranslate"><canvas id="canvas" width="400" height="200" class="playable-canvas"></canvas> +<div class="playable-buttons"> + <input id="edit" type="button" value="Edit" /> + <input id="reset" type="button" value="Reset" /> +</div> +<textarea id="code" class="playable-code"> +ctx.fillStyle = 'green'; +ctx.fillRect(10, 10, 100, 100);</textarea> +</pre> + +<pre class="brush: js notranslate">var canvas = document.getElementById('canvas'); +var ctx = canvas.getContext("2d"); +var textarea = document.getElementById('code'); +var reset = document.getElementById('reset'); +var edit = document.getElementById('edit'); +var code = textarea.value; + +function drawCanvas() { + ctx.clearRect(0, 0, canvas.width, canvas.height); + eval(textarea.value); +} + +reset.addEventListener('click', function() { + textarea.value = code; + drawCanvas(); +}); + +edit.addEventListener('click', function() { + textarea.focus(); +}) + +textarea.addEventListener('input', drawCanvas); +window.addEventListener('load', drawCanvas); +</pre> +</div> + +<p>{{ EmbedLiveSample('Playable_code', 700, 360) }}</p> + +<h2 id="Références">Références</h2> + +<div class="index"> +<ul> + <li>{{domxref("HTMLCanvasElement")}}</li> + <li>{{domxref("CanvasRenderingContext2D")}}</li> + <li>{{domxref("CanvasGradient")}}</li> + <li>{{domxref("CanvasImageSource")}}</li> + <li>{{domxref("CanvasPattern")}}</li> + <li>{{domxref("ImageBitmap")}}</li> + <li>{{domxref("ImageData")}}</li> + <li>{{domxref("RenderingContext")}}</li> + <li>{{domxref("TextMetrics")}}</li> + <li>{{domxref("OffscreenCanvas")}}{{experimental_inline}}</li> + <li>{{domxref("Path2D")}} {{experimental_inline}}{{domxref("ImageBitmapRenderingContext")}}{{experimental_inline}}</li> +</ul> +</div> + +<p>Les interfaces liées au <code>WebGLRenderingContext</code> sont référencées sous <a href="/en-US/docs/Web/WebGL" title="/en-US/docs/Web/WebGL">WebGL</a>.</p> + +<p>{{domxref("CanvasCaptureMediaStream")}} est lié.</p> + +<h2 id="Guides_et_tutoriels">Guides et tutoriels</h2> + +<dl> + <dt><a href="/fr/docs/Tutoriel_canvas">Tutoriel canvas</a></dt> + <dd>Un tutoriel complet qui couvre à la fois l'usage élémentaire de <code><canvas></code> mais aussi ses fonctionnalités avancées.</dd> + <dt><a href="/fr/docs/Extraits_de_code/Canvas" title="fr/docs/Extraits_de_code/Canvas">Extraits de code : Canvas</a></dt> + <dd>Quelques extraits de code orientés vers les développeurs d'extension qui utilisent <code><canvas></code>.</dd> + <dt><a href="/fr/docs/Un_raycaster_basique_avec_canvas">Demo: Un raycaster basique avec canvas</a></dt> + <dd>Une demonstration d'animation utilisant le ray-tracing dans un élément canvas.</dd> + <dt><a href="/fr/docs/Web/HTML/Canvas/Dessiner_des_objets_DOM_dans_un_element_canvas">Dessiner des objets DOM dans un élément canvas</a></dt> + <dd>Comment dessiner un contenu DOM, tel que des éléments HTML, dans un canvas.</dd> + <dt><a href="/fr/docs/HTML/Manipulating_video_using_canvas">Manipulation vidéo avec la balise canvas</a></dt> + <dd>Combiner {{HTMLElement("video")}} et {{HTMLElement("canvas")}} pour manipuler des données video en temps réel.</dd> +</dl> + +<h2 id="Ressources">Ressources</h2> + +<h3 id="Général">Général</h3> + +<ul> + <li><a href="http://joshondesign.com/p/books/canvasdeepdive/title.html">HTML5 Canvas Deep Dive</a> (en)</li> + <li><a href="http://bucephalus.org/text/CanvasHandbook/CanvasHandbook.html">Canvas Handbook</a> (en)</li> +</ul> + +<h3 id="Bibliothèques">Bibliothèques</h3> + +<ul> + <li><a href="http://fabricjs.com">Fabric.js</a> est une bibliothèque open-source qui peut analyser du code SVG.</li> + <li><a href="https://github.com/ericdrowell/KineticJS">Kinetic.js</a> est une bibliothèque open-source concentrée sur l'interactivité pour les applications mobiles et de bureau.</li> + <li><a href="http://paperjs.org/">Paper.js</a> est une bibliothèque open-source qui rajoute un système de dessin vectoriel au canvas HTML5.</li> + <li><a href="http://origamijs.com/docs/">Origami.js</a> est une bibliothèque légère open-source pour canvas.</li> + <li><a href="http://libcanvas.github.com/">libCanvas</a> est un framework canvas puissant et léger.</li> + <li><a href="http://processingjs.org">Processing.js</a> est un portage du langage de visuaisation Processing.</li> + <li><a href="https://playcanvas.com/">PlayCanvas</a> est un moteur de jeu open-source.</li> + <li><a href="http://www.pixijs.com/">Pixi.js</a> est un moteur de jeu open-source.</li> + <li><a href="http://www.liquidx.net/plotkit/">PlotKit</a> est une bibliothèque permettant de réaliser des diagrammes et des graphiques.</li> + <li><a class="link-https" href="https://github.com/jeremyckahn/rekapi">Rekapi</a> est une API d'animation par key-framing pour Canvas.</li> + <li><a href="http://senchalabs.github.com/philogl/">PhiloGL</a> est un framework WebGL pour la visualisation de données, pour la programmation créative et pour le developpement de jeux.</li> + <li><a href="http://thejit.org/">JavaScript InfoVis Toolkit</a> crée des visualisation de données interactives en 2D avec canvas pour le Web.</li> + <li><a href="http://www.createjs.com/easeljs">EaselJS</a> est une bibliothèque gratuite/open-source qui facilite l'utilisation de canvas pour faire des jeux ou de l'art</li> + <li><a href="http://scrawl.rikweb.org.uk/">Scrawl-canvas</a> est une autre bibliothèque open-source pour créer et manipuler des éléments 2D dans canvas</li> + <li><a href="https://www.patrick-wied.at/static/heatmapjs/">heatmap.js</a> est une bibliothèque open-source pour créer des cartes thermiques basées sur canvas</li> +</ul> + +<h2 id="Spécifications">Spécifications</h2> + +<table class="standard-table"> + <thead> + <tr> + <th scope="col">Specification</th> + <th scope="col">Status</th> + <th scope="col">Comment</th> + </tr> + </thead> + <tbody> + <tr> + <td>{{SpecName('HTML WHATWG', 'scripting.html#the-canvas-element', '<canvas>')}}</td> + <td>{{Spec2('HTML WHATWG')}}</td> + <td> </td> + </tr> + </tbody> +</table> + +<h2 id="Voir_aussi">Voir aussi</h2> + +<ul> + <li><a href="/en-US/docs/Web/WebGL">WebGL</a></li> +</ul> diff --git a/files/fr/web/api/canvas_api/tutoriel_canvas/advanced_animations/index.html b/files/fr/web/api/canvas_api/tutoriel_canvas/advanced_animations/index.html new file mode 100644 index 0000000000..fadf515090 --- /dev/null +++ b/files/fr/web/api/canvas_api/tutoriel_canvas/advanced_animations/index.html @@ -0,0 +1,376 @@ +--- +title: Animations avancées +slug: Web/API/Canvas_API/Tutoriel_canvas/Advanced_animations +translation_of: Web/API/Canvas_API/Tutorial/Advanced_animations +--- +<div>{{CanvasSidebar}} {{PreviousNext("Tutoriel_canvas/Animations_basiques", "Tutoriel_canvas/Pixel_manipulation_with_canvas")}}</div> + +<div class="summary"> +<p>Dans le dernier chapitre, nous avons réalisé des <a href="https://developer.mozilla.org/fr/docs/Tutoriel_canvas/Animations_basiques">animations basiques</a> et avons appris comment faire en sorte que les éléments se déplacent. Dans cette partie, nous allons regarder de prêt le mouvement lui-même et ajouter un peu de physique afin de réaliser nos animations avancées.</p> +</div> + +<h2 id="Dessinons_une_balle">Dessinons une balle</h2> + +<p>Nous allons utiliser une balle pour étudier les animations. Ainsi, Commençons par dessiner notre balle au sein du canevas.</p> + +<pre class="brush: html notranslate"><canvas id="canvas" width="600" height="300"></canvas> +</pre> + +<p>Comme d'habitude, nous avons tout d'abord besoin de dessiner le contexte. Pour dessiner la balle, nous allons créer un objet <code>ball</code> contenant des propriétés et une méthode <code>draw()</code> afin de la placer sur le canevas.</p> + +<pre class="brush: js notranslate">var canvas = document.getElementById('canvas'); +var ctx = canvas.getContext('2d'); + +var ball = { + x: 100, + y: 100, + radius: 25, + color: 'blue', + draw: function() { + ctx.beginPath(); + ctx.arc(this.x, this.y, this.radius, 0, Math.PI*2, true); + ctx.closePath(); + ctx.fillStyle = this.color; + ctx.fill(); + } +}; + +ball.draw();</pre> + +<p>Il n'y a rien de spécial ici, la balle est pour le moment un simple cercle qui est dessiné à l'aide de la méthode {{domxref("CanvasRenderingContext2D.arc()", "arc()")}}.</p> + +<h2 id="Ajout_de_la_vitesse">Ajout de la vitesse</h2> + +<p>Maintenant que nous avons une balle, nous sommes prêts à ajouter une animation simple comme nous avons pu le voir dans le <a href="https://developer.mozilla.org/fr/docs/Tutoriel_canvas/Animations_basiques">dernier chapitre</a> de ce tutoriel. Une fois encore, {{domxref("window.requestAnimationFrame()")}} nous aide à contrôler l'animation. Il est possible de déplacer la balle en ajoutant un vecteur de vitesse à la position. Pour chaque "frame", nous avons aussi {{domxref("CanvasRenderingContext2D.clearRect", "clear", "", 1)}} <em>(nettoyé)</em> les canvas pour supprimer les anciens cercles des "frames" précédents.</p> + +<pre class="brush: js; highlight:[8,9,24,25] notranslate">var canvas = document.getElementById('canvas'); +var ctx = canvas.getContext('2d'); +var raf; + +var ball = { + x: 100, + y: 100, + vx: 5, + vy: 2, + radius: 25, + color: 'blue', + draw: function() { + ctx.beginPath(); + ctx.arc(this.x, this.y, this.radius, 0, Math.PI*2, true); + ctx.closePath(); + ctx.fillStyle = this.color; + ctx.fill(); + } +}; + +function draw() { + ctx.clearRect(0,0, canvas.width, canvas.height); + ball.draw(); + ball.x += ball.vx; + ball.y += ball.vy; + raf = window.requestAnimationFrame(draw); +} + +canvas.addEventListener('mouseover', function(e){ + raf = window.requestAnimationFrame(draw); +}); + +canvas.addEventListener("mouseout",function(e){ + window.cancelAnimationFrame(raf); +}); + +ball.draw(); +</pre> + +<h2 id="Limites">Limites</h2> + +<p>Si aucun test de collision n'est effectué, notre balle sort hors du canevas rapidement. Nous avons ici besoin de vérifier si les positions <code>x</code> et <code>y</code> de la balle sont hors des dimensions du canevas et si c'est le cas, d'inverser la direction des vecteurs de vitesse. Pour faire cela, nous ajoutons les vérifications suivantes à la méthode <code>draw</code> :</p> + +<pre class="brush: js notranslate">if (ball.y + ball.vy > canvas.height || ball.y + ball.vy < 0) { + ball.vy = -ball.vy; +} +if (ball.x + ball.vx > canvas.width || ball.x + ball.vx < 0) { + ball.vx = -ball.vx; +}</pre> + +<h3 id="Première_demo">Première demo</h3> + +<p>Voyons voir ce que cela donne. Déplacez votre souris dans le canevas pour commencer l'animation :</p> + +<div class="hidden"> +<pre class="brush: html notranslate"><canvas id="canvas" style="border: 1px solid" width="600" height="300"></canvas></pre> + +<pre class="brush: js notranslate">var canvas = document.getElementById('canvas'); +var ctx = canvas.getContext('2d'); +var raf; + +var ball = { + x: 100, + y: 100, + vx: 5, + vy: 2, + radius: 25, + color: 'blue', + draw: function() { + ctx.beginPath(); + ctx.arc(this.x, this.y, this.radius, 0, Math.PI*2, true); + ctx.closePath(); + ctx.fillStyle = this.color; + ctx.fill(); + } +}; + +function draw() { + ctx.clearRect(0,0, canvas.width, canvas.height); + ball.draw(); + ball.x += ball.vx; + ball.y += ball.vy; + + if (ball.y + ball.vy > canvas.height || + ball.y + ball.vy < 0) { + ball.vy = -ball.vy; + } + if (ball.x + ball.vx > canvas.width || + ball.x + ball.vx < 0) { + ball.vx = -ball.vx; + } + + raf = window.requestAnimationFrame(draw); +} + +canvas.addEventListener('mouseover', function(e){ + raf = window.requestAnimationFrame(draw); +}); + +canvas.addEventListener("mouseout",function(e){ + window.cancelAnimationFrame(raf); +}); + +ball.draw();</pre> +</div> + +<p>{{EmbedLiveSample("Première_demo", "610", "310")}}</p> + +<h2 id="Accélération">Accélération</h2> + +<p>Afin d'obtenir un mouvement plus réel, vous pouvez jouer sur la vitesse, par exemple :</p> + +<pre class="brush: js notranslate">ball.vy *= .99; +ball.vy += .25;</pre> + +<p>Ceci ralentit la vitesse verticale à chaque rendu d'image de sorte que la balle va rebondir de moins en moins haut.</p> + +<div class="hidden"> +<h6 id="Second_demo">Second demo</h6> + +<pre class="brush: html notranslate"><canvas id="canvas" style="border: 1px solid" width="600" height="300"></canvas></pre> + +<pre class="brush: js notranslate">var canvas = document.getElementById('canvas'); +var ctx = canvas.getContext('2d'); +var raf; + +var ball = { + x: 100, + y: 100, + vx: 5, + vy: 2, + radius: 25, + color: 'blue', + draw: function() { + ctx.beginPath(); + ctx.arc(this.x, this.y, this.radius, 0, Math.PI*2, true); + ctx.closePath(); + ctx.fillStyle = this.color; + ctx.fill(); + } +}; + +function draw() { + ctx.clearRect(0,0, canvas.width, canvas.height); + ball.draw(); + ball.x += ball.vx; + ball.y += ball.vy; + ball.vy *= .99; + ball.vy += .25; + + if (ball.y + ball.vy > canvas.height || + ball.y + ball.vy < 0) { + ball.vy = -ball.vy; + } + if (ball.x + ball.vx > canvas.width || + ball.x + ball.vx < 0) { + ball.vx = -ball.vx; + } + + raf = window.requestAnimationFrame(draw); +} + +canvas.addEventListener('mouseover', function(e){ + raf = window.requestAnimationFrame(draw); +}); + +canvas.addEventListener("mouseout",function(e){ + window.cancelAnimationFrame(raf); +}); + +ball.draw();</pre> +</div> + +<p>{{EmbedLiveSample("Second_demo", "610", "310")}}</p> + +<h2 id="Effet_de_traînée">Effet de traînée</h2> + +<p>Jusqu'à maintenant, nous avons utilisé la méthode {{domxref("CanvasRenderingContext2D.clearRect", "clearRect")}} pour effacer les images précédentes. En la remplaçant par la méthode {{domxref("CanvasRenderingContext2D.fillRect", "fillRect")}} et en utilisant un remplissage semi-transparent, on obtient un effet de traînée.</p> + +<pre class="brush: js notranslate">ctx.fillStyle = 'rgba(255,255,255,0.3)'; +ctx.fillRect(0,0,canvas.width,canvas.height);</pre> + +<div class="hidden"> +<h6 id="Third_demo">Third demo</h6> + +<pre class="brush: html notranslate"><canvas id="canvas" style="border: 1px solid" width="600" height="300"></canvas></pre> + +<pre class="brush: js notranslate">var canvas = document.getElementById('canvas'); +var ctx = canvas.getContext('2d'); +var raf; + +var ball = { + x: 100, + y: 100, + vx: 5, + vy: 2, + radius: 25, + color: 'blue', + draw: function() { + ctx.beginPath(); + ctx.arc(this.x, this.y, this.radius, 0, Math.PI*2, true); + ctx.closePath(); + ctx.fillStyle = this.color; + ctx.fill(); + } +}; + +function draw() { + ctx.fillStyle = 'rgba(255,255,255,0.3)'; + ctx.fillRect(0,0,canvas.width,canvas.height); + ball.draw(); + ball.x += ball.vx; + ball.y += ball.vy; + ball.vy *= .99; + ball.vy += .25; + + if (ball.y + ball.vy > canvas.height || + ball.y + ball.vy < 0) { + ball.vy = -ball.vy; + } + if (ball.x + ball.vx > canvas.width || + ball.x + ball.vx < 0) { + ball.vx = -ball.vx; + } + + raf = window.requestAnimationFrame(draw); +} + +canvas.addEventListener('mouseover', function(e){ + raf = window.requestAnimationFrame(draw); +}); + +canvas.addEventListener("mouseout",function(e){ + window.cancelAnimationFrame(raf); +}); + +ball.draw();</pre> +</div> + +<p>{{EmbedLiveSample("Third_demo", "610", "310")}}</p> + +<h2 id="Ajout_dun_contrôle_de_souris">Ajout d'un contrôle de souris</h2> + +<p>Afin d'obtenir quelques contrôles sur la balle, nous pouvons faire suivre notre souris en utilisant l'événement <code><a href="/en-US/docs/Web/Reference/Events/mousemove">mousemove</a></code>, par exemple. L'événement <code><a href="/en-US/docs/Web/Events/click">click</a></code> relâche la balle et la laisse rebondir à nouveau.</p> + +<div class="hidden"> +<pre class="brush: html notranslate"><canvas id="canvas" style="border: 1px solid" width="600" height="300"></canvas></pre> +</div> + +<pre class="brush: js notranslate">var canvas = document.getElementById('canvas'); +var ctx = canvas.getContext('2d'); +var raf; +var running = false; + +var ball = { + x: 100, + y: 100, + vx: 5, + vy: 1, + radius: 25, + color: 'blue', + draw: function() { + ctx.beginPath(); + ctx.arc(this.x, this.y, this.radius, 0, Math.PI*2, true); + ctx.closePath(); + ctx.fillStyle = this.color; + ctx.fill(); + } +}; + +function clear() { + ctx.fillStyle = 'rgba(255,255,255,0.3)'; + ctx.fillRect(0,0,canvas.width,canvas.height); +} + +function draw() { + clear(); + ball.draw(); + ball.x += ball.vx; + ball.y += ball.vy; + + if (ball.y + ball.vy > canvas.height || ball.y + ball.vy < 0) { + ball.vy = -ball.vy; + } + if (ball.x + ball.vx > canvas.width || ball.x + ball.vx < 0) { + ball.vx = -ball.vx; + } + + raf = window.requestAnimationFrame(draw); +} + +canvas.addEventListener('mousemove', function(e){ + if (!running) { + clear(); + ball.x = e.clientX; + ball.y = e.clientY; + ball.draw(); + } +}); + +canvas.addEventListener("click",function(e){ + if (!running) { + raf = window.requestAnimationFrame(draw); + running = true; + } +}); + +canvas.addEventListener("mouseout",function(e){ + window.cancelAnimationFrame(raf); + running = false; +}); + +ball.draw(); +</pre> + +<p>Déplacez la balle en utilisant votre souris et relâchez-la avec un click.</p> + +<p>{{EmbedLiveSample("Ajout_d'un_contrôle_de_souris", "610", "310")}}</p> + +<h2 id="Casse-briques">Casse-briques</h2> + +<p>Ce petit chapitre explique seulement quelques techniques pour créer des animations avancées. Il en existe bien davantage ! <span id="result_box" lang="fr"><span>Que diriez-vous d'ajouter une raquette, des briques et de transformer cette démo en une partie de casse-briques ?</span> <span>Consultez notre zone de développement de jeux pour plus d'articles liés <a href="https://developer.mozilla.org/fr/docs/Jeux">aux jeux</a>.</span></span></p> + +<h2 id="Voir_aussi">Voir aussi</h2> + +<ul> + <li>{{domxref("window.requestAnimationFrame()")}}</li> + <li><a href="https://developer.mozilla.org/fr/docs/Games/Techniques/Efficient_animation_for_web_games">Animation efficace pour les jeux vidéo</a></li> +</ul> + +<p>{{PreviousNext("Tutoriel_canvas/Animations_basiques", "Tutoriel_canvas/Pixel_manipulation_with_canvas")}}</p> diff --git a/files/fr/web/api/canvas_api/tutoriel_canvas/ajout_de_styles_et_de_couleurs/index.html b/files/fr/web/api/canvas_api/tutoriel_canvas/ajout_de_styles_et_de_couleurs/index.html new file mode 100644 index 0000000000..15eef37006 --- /dev/null +++ b/files/fr/web/api/canvas_api/tutoriel_canvas/ajout_de_styles_et_de_couleurs/index.html @@ -0,0 +1,719 @@ +--- +title: Ajout de styles et de couleurs +slug: Web/API/Canvas_API/Tutoriel_canvas/Ajout_de_styles_et_de_couleurs +tags: + - Canvas + - Couleurs + - Formes géométriques + - Graphismes + - Tutorial +translation_of: Web/API/Canvas_API/Tutorial/Applying_styles_and_colors +--- +<div>{{CanvasSidebar}} {{PreviousNext("Tutoriel_canvas/Formes_géométriques", "Dessin_de_texte_avec_canvas")}}</div> + +<div class="summary"> +<p>Dans le chapitre sur <a href="https://developer.mozilla.org/fr/docs/Tutoriel_canvas/Formes_g%C3%A9om%C3%A9triques" title="/fr/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes">les formes géométriques</a>, nous avons utilisé les styles de lignes et de remplissage par défaut. Ici, nous allons explorer les options de canvas à notre disposition pour rendre nos dessins un peu plus attrayants. Vous apprendrez comment ajouter des couleurs différentes, des styles de ligne, des dégradés, des motifs et des ombres à vos dessins.</p> +</div> + +<h2 id="Colors" name="Colors">Les couleurs</h2> + +<p>Jusqu'à présent, nous avons seulement vu des méthodes sur le contexte de dessin. Si nous voulons appliquer des couleurs à une forme, il y a deux propriétés importantes que nous pouvons utiliser : <code>fillStyle</code> et <code>strokeStyle</code> .</p> + +<dl> + <dt>{{domxref("CanvasRenderingContext2D.fillStyle", "fillStyle = color")}}</dt> + <dd>Définit le style utilisé lors du remplissage de formes.</dd> + <dt>{{domxref("CanvasRenderingContext2D.strokeStyle", "strokeStyle = color")}}</dt> + <dd>Définit le style pour les contours des formes.</dd> +</dl> + +<p><code>color</code> est une chaîne représentant un CSS {{cssxref("<color>")}}, d'un objet gradient ou d'un objet motif. Nous allons examiner le gradient et la structure des objets plus tard. Par défaut, l'encadrement et la couleur de remplissage sont fixés sur noir (valeur <code>#000000</code> de CSS <code>color</code>).</p> + +<div class="note"> +<p><strong>Remarque: </strong> Lorsque vous définissez <code>strokeStyle</code> et <code>fillStyle</code>, la nouvelle valeur devient la valeur par défaut pour toutes les formes en cours d'élaboration à partir de là. Pour chaque forme que vous voulez dans une couleur différente, vous aurez besoin de réaffecter <code>fillStyle</code> ou <code>strokeStyle</code>.</p> +</div> + +<p>Les chaînes pour être valides, doivent être conforme à la spécification CSS {{cssxref("<color>")}}. Chacun des exemples suivants décrit la même couleur.</p> + +<pre class="brush: js line-numbers language-js notranslate"><code class="language-js"><span class="comment token">// Les valeurs possibles de fillStyle pour "orange"</span> + +ctx<span class="punctuation token">.</span>fillStyle <span class="operator token">=</span> <span class="string token">'orange'</span><span class="punctuation token">;</span> +ctx<span class="punctuation token">.</span>fillStyle <span class="operator token">=</span> <span class="string token">'#FFA500'</span><span class="punctuation token">;</span> +ctx<span class="punctuation token">.</span>fillStyle <span class="operator token">=</span> <span class="string token">'rgb(255, 165, 0)'</span><span class="punctuation token">;</span> +ctx<span class="punctuation token">.</span>fillStyle <span class="operator token">=</span> <span class="string token">'rgba(255, 165, 0, 1)'</span><span class="punctuation token">;</span></code></pre> + +<h3 id="A_fillStyle_example" name="A_fillStyle_example">Un exemple <code>fillStyle</code></h3> + +<p>Dans cet exemple, nous utilisons une nouvelle fois deux boucles <code>for</code> pour dessiner une grille de rectangles, chacun dans une couleur différente. L'image résultante devrait ressembler à la capture d'écran. Il n'y a rien de spectaculaire ici. Nous utilisons les deux variables <code>i</code> et <code>j</code> pour générer une couleur RVB unique pour chaque carré, et seulement modifier les valeurs rouges et vertes. Le canal bleu a une valeur fixe. En modifiant les canaux, vous pouvez générer toutes sortes de palettes. En augmentant les étapes, vous pouvez obtenir quelque chose qui ressemble à des palettes de couleurs que Photoshop utilise.</p> + +<pre class="brush: js;highlight[5,6] notranslate">function draw() { + var ctx = document.getElementById('canvas').getContext('2d'); + for (var i = 0; i < 6; i++) { + for (var j = 0; j < 6; j++) { + ctx.fillStyle = 'rgb(' + Math.floor(255 - 42.5 * i) + ',' + + Math.floor(255 - 42.5 * j) + ',0)'; + ctx.fillRect(j * 25, i * 25, 25, 25); + } + } +}</pre> + +<div class="hidden"> +<pre class="brush: html notranslate"><canvas id="canvas" width="150" height="150"></canvas></pre> + +<pre class="brush: js notranslate">draw();</pre> +</div> + +<p>Le résultat ressemble à ceci:</p> + +<p>{{EmbedLiveSample("A_fillStyle_example", 160, 160, "https://mdn.mozillademos.org/files/5417/Canvas_fillstyle.png")}}</p> + +<h3 id="A_strokeStyle_example" name="A_strokeStyle_example">Un exemple <code>strokeStyle</code></h3> + +<p>Cet exemple est similaire à celui ci-dessus, mais utilise <code>strokeStyle</code> pour changer les couleurs des contours des formes. Nous utilisons la méthode <code>arc()</code> pour dessiner des cercles au lieu de carrés.</p> + +<pre class="brush: js;highlight[5,6] line-numbers language-js notranslate"><code class="language-js"><span class="keyword token">function</span> <span class="function token">draw</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> ctx <span class="operator token">=</span> document<span class="punctuation token">.</span><span class="function token">getElementById</span><span class="punctuation token">(</span><span class="string token">'canvas'</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">getContext</span><span class="punctuation token">(</span><span class="string token">'2d'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">for</span> <span class="punctuation token">(</span><span class="keyword token">var</span> i <span class="operator token">=</span> <span class="number token">0</span><span class="punctuation token">;</span> i <span class="operator token"><</span> <span class="number token">6</span><span class="punctuation token">;</span> i<span class="operator token">++</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">for</span> <span class="punctuation token">(</span><span class="keyword token">var</span> j <span class="operator token">=</span> <span class="number token">0</span><span class="punctuation token">;</span> j <span class="operator token"><</span> <span class="number token">6</span><span class="punctuation token">;</span> j<span class="operator token">++</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + ctx<span class="punctuation token">.</span>strokeStyle <span class="operator token">=</span> <span class="string token">'rgb(0, '</span> <span class="operator token">+</span> Math<span class="punctuation token">.</span><span class="function token">floor</span><span class="punctuation token">(</span><span class="number token">255</span> <span class="operator token">-</span> <span class="number token">42.5</span> <span class="operator token">*</span> i<span class="punctuation token">)</span> <span class="operator token">+</span> <span class="string token">', '</span> <span class="operator token">+</span> + Math<span class="punctuation token">.</span><span class="function token">floor</span><span class="punctuation token">(</span><span class="number token">255</span> <span class="operator token">-</span> <span class="number token">42.5</span> <span class="operator token">*</span> j<span class="punctuation token">)</span> <span class="operator token">+</span> <span class="string token">')'</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">beginPath</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">arc</span><span class="punctuation token">(</span><span class="number token">12.5</span> <span class="operator token">+</span> j <span class="operator token">*</span> <span class="number token">25</span><span class="punctuation token">,</span> <span class="number token">12.5</span> <span class="operator token">+</span> i <span class="operator token">*</span> <span class="number token">25</span><span class="punctuation token">,</span> <span class="number token">10</span><span class="punctuation token">,</span> <span class="number token">0</span><span class="punctuation token">,</span> Math<span class="punctuation token">.</span>PI <span class="operator token">*</span> <span class="number token">2</span><span class="punctuation token">,</span> <span class="keyword token">true</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">stroke</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> + <span class="punctuation token">}</span> + <span class="punctuation token">}</span></code></pre> + +<div class="hidden"> +<pre class="brush: html notranslate"><canvas id="canvas" width="150" height="150"></canvas></pre> + +<pre class="brush: js line-numbers language-js notranslate"><code class="language-js"><span class="function token">draw</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre> +</div> + +<p>Le résultat ressemble à ceci :</p> + +<p>{{EmbedLiveSample("A_strokeStyle_example", "180", "180", "https://mdn.mozillademos.org/files/253/Canvas_strokestyle.png")}}</p> + +<h2 id="Transparency" name="Transparency">Transparence</h2> + +<p>En plus de dessiner des formes opaques sur la toile, nous pouvons également dessiner des formes semi-transparentes (ou translucides). Cela se fait soit par le réglage de <code>globalAlpha</code> ou en attribuant une couleur semi-transparente à <code>strokeStyle</code> et/ou <code>fillStyle</code>.</p> + +<dl> + <dt>{{domxref("CanvasRenderingContext2D.globalAlpha", "globalAlpha = transparencyValue")}}</dt> + <dd>Applique la valeur de transparence spécifiée à toutes les formes futures tracées sur le Canvas. La valeur doit être comprise entre 0.0 (complètement transparent) à 1.0 (complètement opaque). Cette valeur est de 1,0 (complètement opaque) par défaut.</dd> +</dl> + +<p>La propriété<code> globalAlpha</code> peut être utile si vous voulez dessiner un grand nombre de formes sur la toile avec la même transparence, mais sinon, il est généralement plus utile de définir la transparence sur les formes individuelles lors de la définition de leurs couleurs.</p> + +<p>Parce que <code>strokeStyle</code> et <code>fillStyle</code> acceptent les valeurs de couleur rvba CSS, nous pouvons utiliser la notation suivante pour attribuer une couleur transparente.</p> + +<pre class="brush: js notranslate">//Affecter des couleurs transparentes pour dessiner et remplir le style + +ctx.strokeStyle = "rgba(255, 0, 0, .5)"; +ctx.fillStyle = "rgba(255, 0, 0, .5)"; +</pre> + +<p>La fonction <code>rgba()</code> <em>(rvba)</em> est similaire à la fonction <code>rgb()</code> <em>(rvb)</em> mais il a un paramètre supplémentaire. Le dernier paramètre définit la valeur de la transparence de cette couleur particulière. La plage valide est entre 0,0 (totalement transparent) et 1,0 (totalement opaque).</p> + +<h3 id="A_globalAlpha_example" name="A_globalAlpha_example">Un exemple <code>globalAlpha</code></h3> + +<p>Dans cet exemple, nous allons dessiner un fond de quatre carrés de couleurs différentes. En plus de ceux-ci, nous allons dessiner un ensemble de cercles semi-transparents. <code>globalAlpha</code> est réglé à <code>0.2</code> et sera utilisé pour toutes les formes. Chaque étape de boucle <code>for</code> dessine un ensemble de cercles avec un rayon croissant. Le résultat final est un gradient radial. En superposant toujours plus de cercles, les uns au-dessus des autres, nous réduisons efficacement la transparence des cercles qui ont déjà été établis. En augmentant le pas et le nombre de cercles, l'arrière-plan devrait complètement disparaître du centre de l'image.</p> + +<pre class="brush: js;highlight[15] line-numbers language-js notranslate"><code class="language-js"><span class="keyword token">function</span> <span class="function token">draw</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> ctx <span class="operator token">=</span> document<span class="punctuation token">.</span><span class="function token">getElementById</span><span class="punctuation token">(</span><span class="string token">'canvas'</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">getContext</span><span class="punctuation token">(</span><span class="string token">'2d'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="comment token">// draw background</span> + ctx<span class="punctuation token">.</span>fillStyle <span class="operator token">=</span> <span class="string token">'#FD0'</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">fillRect</span><span class="punctuation token">(</span><span class="number token">0</span><span class="punctuation token">,</span> <span class="number token">0</span><span class="punctuation token">,</span> <span class="number token">75</span><span class="punctuation token">,</span> <span class="number token">75</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span>fillStyle <span class="operator token">=</span> <span class="string token">'#6C0'</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">fillRect</span><span class="punctuation token">(</span><span class="number token">75</span><span class="punctuation token">,</span> <span class="number token">0</span><span class="punctuation token">,</span> <span class="number token">75</span><span class="punctuation token">,</span> <span class="number token">75</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span>fillStyle <span class="operator token">=</span> <span class="string token">'#09F'</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">fillRect</span><span class="punctuation token">(</span><span class="number token">0</span><span class="punctuation token">,</span> <span class="number token">75</span><span class="punctuation token">,</span> <span class="number token">75</span><span class="punctuation token">,</span> <span class="number token">75</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span>fillStyle <span class="operator token">=</span> <span class="string token">'#F30'</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">fillRect</span><span class="punctuation token">(</span><span class="number token">75</span><span class="punctuation token">,</span> <span class="number token">75</span><span class="punctuation token">,</span> <span class="number token">75</span><span class="punctuation token">,</span> <span class="number token">75</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span>fillStyle <span class="operator token">=</span> <span class="string token">'#FFF'</span><span class="punctuation token">;</span> + + <span class="comment token">// règle la valeur de transparence</span> + ctx<span class="punctuation token">.</span>globalAlpha <span class="operator token">=</span> <span class="number token">0.2</span><span class="punctuation token">;</span> + + <span class="comment token">// Dessine des cercles semi-transparents</span> + <span class="keyword token">for</span> <span class="punctuation token">(</span>i <span class="operator token">=</span> <span class="number token">0</span><span class="punctuation token">;</span> i <span class="operator token"><</span> <span class="number token">7</span><span class="punctuation token">;</span> i<span class="operator token">++</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + ctx<span class="punctuation token">.</span><span class="function token">beginPath</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">arc</span><span class="punctuation token">(</span><span class="number token">75</span><span class="punctuation token">,</span> <span class="number token">75</span><span class="punctuation token">,</span> <span class="number token">10</span> <span class="operator token">+</span> <span class="number token">10</span> <span class="operator token">*</span> i<span class="punctuation token">,</span> <span class="number token">0</span><span class="punctuation token">,</span> Math<span class="punctuation token">.</span>PI <span class="operator token">*</span> <span class="number token">2</span><span class="punctuation token">,</span> <span class="keyword token">true</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">fill</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> +<span class="punctuation token">}</span></code></pre> + +<div class="hidden"> +<pre class="brush: html line-numbers language-html notranslate"><code class="language-html"><span class="tag token"><span class="tag token"><span class="punctuation token"><</span>canvas</span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>canvas<span class="punctuation token">"</span></span> <span class="attr-name token">width</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>150<span class="punctuation token">"</span></span> <span class="attr-name token">height</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>150<span class="punctuation token">"</span></span><span class="punctuation token">></span></span><span class="tag token"><span class="tag token"><span class="punctuation token"></</span>canvas</span><span class="punctuation token">></span></span></code></pre> + +<pre class="brush: js notranslate">draw();</pre> +</div> + +<p>{{EmbedLiveSample("A_globalAlpha_example", "180", "180", "https://mdn.mozillademos.org/files/232/Canvas_globalalpha.png")}}</p> + +<h3 id="An_example_using_rgba" name="An_example_using_rgba()">Un exemple en utilisant <code>rgba()</code></h3> + +<p>Dans ce deuxième exemple, nous faisons quelque chose de similaire, mais au lieu de dessiner des cercles, nous dessinons de petits rectangles à l'opacité croissante. L'utilisation de <code>rgba()</code> nous donne un peu plus de contrôle et de flexibilité.</p> + +<pre class="brush: js;highlight[16] line-numbers language-js notranslate"><code class="language-js"><span class="keyword token">function</span> <span class="function token">draw</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> ctx <span class="operator token">=</span> document<span class="punctuation token">.</span><span class="function token">getElementById</span><span class="punctuation token">(</span><span class="string token">'canvas'</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">getContext</span><span class="punctuation token">(</span><span class="string token">'2d'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="comment token">// Dessine le fond</span> + ctx<span class="punctuation token">.</span>fillStyle <span class="operator token">=</span> <span class="string token">'rgb(255, 221, 0)'</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">fillRect</span><span class="punctuation token">(</span><span class="number token">0</span><span class="punctuation token">,</span> <span class="number token">0</span><span class="punctuation token">,</span> <span class="number token">150</span><span class="punctuation token">,</span> <span class="number token">37.5</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span>fillStyle <span class="operator token">=</span> <span class="string token">'rgb(102, 204, 0)'</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">fillRect</span><span class="punctuation token">(</span><span class="number token">0</span><span class="punctuation token">,</span> <span class="number token">37.5</span><span class="punctuation token">,</span> <span class="number token">150</span><span class="punctuation token">,</span> <span class="number token">37.5</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span>fillStyle <span class="operator token">=</span> <span class="string token">'rgb(0, 153, 255)'</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">fillRect</span><span class="punctuation token">(</span><span class="number token">0</span><span class="punctuation token">,</span> <span class="number token">75</span><span class="punctuation token">,</span> <span class="number token">150</span><span class="punctuation token">,</span> <span class="number token">37.5</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span>fillStyle <span class="operator token">=</span> <span class="string token">'rgb(255, 51, 0)'</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">fillRect</span><span class="punctuation token">(</span><span class="number token">0</span><span class="punctuation token">,</span> <span class="number token">112.5</span><span class="punctuation token">,</span> <span class="number token">150</span><span class="punctuation token">,</span> <span class="number token">37.5</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="comment token">// Dessine des rectangles semi-transparents</span> + <span class="keyword token">for</span> <span class="punctuation token">(</span><span class="keyword token">var</span> i <span class="operator token">=</span> <span class="number token">0</span><span class="punctuation token">;</span> i <span class="operator token"><</span> <span class="number token">10</span><span class="punctuation token">;</span> i<span class="operator token">++</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + ctx<span class="punctuation token">.</span>fillStyle <span class="operator token">=</span> <span class="string token">'rgba(255, 255, 255, '</span> <span class="operator token">+</span> <span class="punctuation token">(</span>i <span class="operator token">+</span> <span class="number token">1</span><span class="punctuation token">)</span> <span class="operator token">/</span> <span class="number token">10</span> <span class="operator token">+</span> <span class="string token">')'</span><span class="punctuation token">;</span> + <span class="keyword token">for</span> <span class="punctuation token">(</span><span class="keyword token">var</span> j <span class="operator token">=</span> <span class="number token">0</span><span class="punctuation token">;</span> j <span class="operator token"><</span> <span class="number token">4</span><span class="punctuation token">;</span> j<span class="operator token">++</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + ctx<span class="punctuation token">.</span><span class="function token">fillRect</span><span class="punctuation token">(</span><span class="number token">5</span> <span class="operator token">+</span> i <span class="operator token">*</span> <span class="number token">14</span><span class="punctuation token">,</span> <span class="number token">5</span> <span class="operator token">+</span> j <span class="operator token">*</span> <span class="number token">37.5</span><span class="punctuation token">,</span> <span class="number token">14</span><span class="punctuation token">,</span> <span class="number token">27.5</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> + <span class="punctuation token">}</span> +<span class="punctuation token">}</span></code></pre> + +<div class="hidden"> +<pre class="brush: html line-numbers language-html notranslate"><code class="language-html"><span class="tag token"><span class="tag token"><span class="punctuation token"><</span>canvas</span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>canvas<span class="punctuation token">"</span></span> <span class="attr-name token">width</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>150<span class="punctuation token">"</span></span> <span class="attr-name token">height</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>150<span class="punctuation token">"</span></span><span class="punctuation token">></span></span><span class="tag token"><span class="tag token"><span class="punctuation token"></</span>canvas</span><span class="punctuation token">></span></span></code></pre> + +<pre class="brush: js line-numbers language-js notranslate"><code class="language-js"><span class="function token">draw</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre> +</div> + +<p>{{EmbedLiveSample("An_example_using_rgba()", "180", "180", "https://mdn.mozillademos.org/files/246/Canvas_rgba.png")}}</p> + +<h2 id="Line_styles" name="Line_styles">Le style des lignes</h2> + +<p>Il y a plusieurs propriétés qui nous permettent de modifier le style des lignes.</p> + +<dl> + <dt>{{domxref("CanvasRenderingContext2D.lineWidth", "lineWidth = value")}}</dt> + <dd>Définit la largeur des lignes qui serons tracées.</dd> + <dt>{{domxref("CanvasRenderingContext2D.lineCap", "lineCap = type")}}</dt> + <dd>Définit l'apparence des extrémités des lignes.</dd> + <dt>{{domxref("CanvasRenderingContext2D.lineJoin", "lineJoin = type")}}</dt> + <dd>Définit l'apparence des «coins» où les lignes se rencontrent.</dd> + <dt>{{domxref("CanvasRenderingContext2D.miterLimit", "miterLimit = value")}}</dt> + <dd>Établit une limite lorsque deux lignes se rejoignent en un angle aigu, pour permettre de contrôler l'épaisseur de la jonction.</dd> + <dt>{{domxref("CanvasRenderingContext2D.getLineDash", "getLineDash()")}}</dt> + <dd>Retourne le tableau du modele courant de ligne contenant un nombre pair de nombres positifs.</dd> + <dt>{{domxref("CanvasRenderingContext2D.setLineDash", "setLineDash(segments)")}}</dt> + <dd>Définit le modele de ligne.</dd> + <dt>{{domxref("CanvasRenderingContext2D.lineDashOffset", "lineDashOffset = value")}}</dt> + <dd>Indique où commencer un modele sur une ligne.</dd> +</dl> + +<p>Vous aurez une meilleure compréhension de ce qu'ils font en regardant les exemples ci-dessous.</p> + +<h3 id="A_lineWidth_example" name="A_lineWidth_example">Un exemple <code>lineWidth</code></h3> + +<p>Cette propriété définit l'épaisseur de la ligne actuelle. Les valeurs doivent être des nombres positifs. Par défaut, cette valeur est définie à 1,0.</p> + +<p>La largeur de ligne est l'épaisseur centrée sur le tracé. En d'autres termes, la zone qui est dessinée s'étend de part et d'autre du tracé. Parce que les coordonnées ne font pas référence directement aux pixels, une attention particulière doit être prise pour obtenir des lignes horizontales et verticales nettes.</p> + +<p>Dans l'exemple ci-dessous, 10 lignes droites sont dessinées avec des largeurs croissantes. La ligne à l'extrême gauche a 1,0 unités de large. Cependant, celle ci et toutes les lignes d'épaisseur impair ne semblent pas nettes, en raison du positionnement du tracé.</p> + +<pre class="brush: js;highlight[4] line-numbers language-js notranslate"><code class="language-js"><span class="keyword token">function</span> <span class="function token">draw</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> ctx <span class="operator token">=</span> document<span class="punctuation token">.</span><span class="function token">getElementById</span><span class="punctuation token">(</span><span class="string token">'canvas'</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">getContext</span><span class="punctuation token">(</span><span class="string token">'2d'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">for</span> <span class="punctuation token">(</span><span class="keyword token">var</span> i <span class="operator token">=</span> <span class="number token">0</span><span class="punctuation token">;</span> i <span class="operator token"><</span> <span class="number token">10</span><span class="punctuation token">;</span> i<span class="operator token">++</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + ctx<span class="punctuation token">.</span>lineWidth <span class="operator token">=</span> <span class="number token">1</span> <span class="operator token">+</span> i<span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">beginPath</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">moveTo</span><span class="punctuation token">(</span><span class="number token">5</span> <span class="operator token">+</span> i <span class="operator token">*</span> <span class="number token">14</span><span class="punctuation token">,</span> <span class="number token">5</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">lineTo</span><span class="punctuation token">(</span><span class="number token">5</span> <span class="operator token">+</span> i <span class="operator token">*</span> <span class="number token">14</span><span class="punctuation token">,</span> <span class="number token">140</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">stroke</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> +<span class="punctuation token">}</span></code></pre> + +<div class="hidden"> +<pre class="brush: html line-numbers language-html notranslate"><code class="language-html"><span class="tag token"><span class="tag token"><span class="punctuation token"><</span>canvas</span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>canvas<span class="punctuation token">"</span></span> <span class="attr-name token">width</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>150<span class="punctuation token">"</span></span> <span class="attr-name token">height</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>150<span class="punctuation token">"</span></span><span class="punctuation token">></span></span><span class="tag token"><span class="tag token"><span class="punctuation token"></</span>canvas</span><span class="punctuation token">></span></span></code></pre> + +<pre class="brush: js line-numbers language-js notranslate"><code class="language-js"><span class="function token">draw</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre> +</div> + +<p>{{EmbedLiveSample("A_lineWidth_example", "180", "180", "https://mdn.mozillademos.org/files/239/Canvas_linewidth.png")}}</p> + +<p>Pour l'obtention de lignes nettes, il faut comprendre comment les lignes sont tracées. Ci-dessous, la grille représente la grille de coordonnées. Les carrés sont des pixels réels de l'écran. Dans la première grille, un rectangle (2,1) à (5,5) est rempli. La zone entière couverte par les lignes (rouge clair) tombe sur les limites des pixels, de sorte que le rectangle rempli résultant aura des bords nets.</p> + +<p><img alt="" class="internal" src="https://mdn.mozillademos.org/files/201/Canvas-grid.png"></p> + +<p>Si vous considérez un tracé de (3,1) à (3,5) avec une épaisseur de ligne de <code>1.0</code>, vous vous retrouvez dans la situation de la deuxième grille. La surface réelle à remplir (bleu foncé) se prolonge seulement à moitié sur les pixels de part et d'autre du chemin. Une approximation de ceci doit être rendue, ce qui signifie que ces pixels sont partiellement ombrés, et le résultat est que toute la zone (le bleu clair et bleu foncé) est remplie avec une couleur moitié moins sombre que la couleur du tracé attendu. C'est ce qui arrive avec la largeur de <code>1.0</code> dans l'exemple précédent.</p> + +<p>Pour résoudre ce problème, vous devez être très précis dans la création de votre tracé. Sachant qu'une largeur de <code>1.0</code> s'étendra d'une demi-unité de chaque côté du tracé, créer le tracé de (3.5,1) à (3.5,5) aboutit à l'exemple trois pour une largeur de <code>1.0</code> et au remplissage d'un seul pixel de ligne verticale.</p> + +<div class="note"> +<p><strong>Note:</strong> Sachez que dans notre exemple de ligne verticale, la position Y fait toujours référence à une position de grille entière — sinon, vous verrez des pixels à moitié colorés à gauche et à droite (mais notez aussi que ce comportement dépend de l'actuel style <code>lineCap</code>, dont la valeur par défaut est <code>butt</code>. Vous pouvez essayer de tracer des traits consistants avec des coordonnées non-entières pour les lignes et avec une largeur particulière, en définissant le style <code>lineCap</code> à <code>square</code>, pour que le bord extérieur du trait autour du point final soit automatiquement étendu pour couvrir le pixel entier).</p> + +<p><span id="result_box" lang="fr"><span>Notez également que seuls les points de début et de fin d'un chemin sont affectés : si un chemin est fermé avec <code>closePath ()</code>, il n'y a pas de point de départ ni de point final ;</span> <span>à la place, tous les points d'extrémité du chemin sont connectés à leurs segments joints précédent et suivant, en utilisant le paramètre courant du style <code>lineJoin</code>, dont la valeur par défaut est <code>miter</code>, avec pour effet d'étendre automatiquement les bordures extérieures des segments connectés à leur point d'intersection.</span> Ainsi,<span> le trait de rendu couvrira exactement les pixels pleins centrés à chaque extrémité si ces segments connectés sont horizontaux et / ou verticaux.</span> <span>Voir les deux sections suivantes pour les démonstrations de ces styles de lignes supplémentaires.</span></span></p> +</div> + +<p><span id="result_box" lang="fr"><span>Pour les lignes de largeur paire, chaque moitié finit par être un nombre entier de pixels, vous voulez donc un chemin entre les pixels (c'est-à-dire (3,1) à (3,5)), au lieu de descendre au milieu des pixels</span> <span>.</span></span></p> + +<p>Bien que légèrement ennuyeux quand on travaille avec des graphismes 2D évolutifs, en accordant une attention à la grille de pixels et à la position des tracés, vous vous assurez du comportement correct de vos dessins, et ce, indépendamment de la mise à l'échelle ou d'autres transformations. Une ligne verticale de largeur 1,0 à la bonne position deviendra une ligne de 2 pixels nette à l'échelle 2.</p> + +<h3 id="A_lineCap_example" name="A_lineCap_example">Un exemple de <code>lineCap</code></h3> + +<p>La propriété <code>lineCap</code> détermine comment les extrêmités de chaque ligne sont dessinées. Il y a trois valeurs possibles pour la propriété : <code>butt</code>, <code>round</code> et <code>square</code>. Par défaut, la propriété est définie à <code>butt</code>.</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/236/Canvas_linecap.png" style="float: right; height: 190px; width: 190px;"></p> + +<dl> + <dt><code>butt </code><em>(bout)</em></dt> + <dd>L'extrémité des lignes est en angle droit.</dd> + <dt><code>round </code><em>(rond)</em></dt> + <dd>Les extrémités sont arrondies.</dd> + <dt><code>square </code><em>(carré)</em></dt> + <dd>Les extrémités sont en angle droit en ajoutant une extension d'une largeur égale à la ligne et une hauteur égale à la moitié de la largeur de la ligne.</dd> +</dl> + +<p>Dans cet exemple, nous avons tracé trois lignes, chacune avec une valeur différente pour la propriété <code>lineCap</code>. Nous avons par ailleurs ajouté deux guides pour voir exactement les différences entre les trois lignes. Chacune de ces trois lignes est identique entre les deux traits bleus.</p> + +<p>La ligne de gauche utilise l'option par défaut <code>butt</code>. Vous pourrez noter qu'elle est entièrement dessinée entre les deux guides. La deuxième utilise l'option <code>round</code>. Elle ajoute un demi-cercle à chaque extrémité d'un rayon valant la moitié de la largeur de la ligne. La ligne de droite utilise l'option <code>square</code>. Elle ajoute une extension avec une largeur égale à la ligne et une hauteur équivalante à la moitié de la largeur de la ligne.</p> + +<pre class="brush: js;highlight[18] line-numbers language-js notranslate"><code class="language-js"><span class="keyword token">function</span> <span class="function token">draw</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> ctx <span class="operator token">=</span> document<span class="punctuation token">.</span><span class="function token">getElementById</span><span class="punctuation token">(</span><span class="string token">'canvas'</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">getContext</span><span class="punctuation token">(</span><span class="string token">'2d'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">var</span> lineCap <span class="operator token">=</span> <span class="punctuation token">[</span><span class="string token">'butt'</span><span class="punctuation token">,</span> <span class="string token">'round'</span><span class="punctuation token">,</span> <span class="string token">'square'</span><span class="punctuation token">]</span><span class="punctuation token">;</span> + + <span class="comment token">// Dessiner des guides</span> + ctx<span class="punctuation token">.</span>strokeStyle <span class="operator token">=</span> <span class="string token">'#09f'</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">beginPath</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">moveTo</span><span class="punctuation token">(</span><span class="number token">10</span><span class="punctuation token">,</span> <span class="number token">10</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">lineTo</span><span class="punctuation token">(</span><span class="number token">140</span><span class="punctuation token">,</span> <span class="number token">10</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">moveTo</span><span class="punctuation token">(</span><span class="number token">10</span><span class="punctuation token">,</span> <span class="number token">140</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">lineTo</span><span class="punctuation token">(</span><span class="number token">140</span><span class="punctuation token">,</span> <span class="number token">140</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">stroke</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="comment token">// Dessiner des lignes</span> + ctx<span class="punctuation token">.</span>strokeStyle <span class="operator token">=</span> <span class="string token">'black'</span><span class="punctuation token">;</span> + <span class="keyword token">for</span> <span class="punctuation token">(</span><span class="keyword token">var</span> i <span class="operator token">=</span> <span class="number token">0</span><span class="punctuation token">;</span> i <span class="operator token"><</span> lineCap<span class="punctuation token">.</span>length<span class="punctuation token">;</span> i<span class="operator token">++</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + ctx<span class="punctuation token">.</span>lineWidth <span class="operator token">=</span> <span class="number token">15</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span>lineCap <span class="operator token">=</span> lineCap<span class="punctuation token">[</span>i<span class="punctuation token">]</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">beginPath</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">moveTo</span><span class="punctuation token">(</span><span class="number token">25</span> <span class="operator token">+</span> i <span class="operator token">*</span> <span class="number token">50</span><span class="punctuation token">,</span> <span class="number token">10</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">lineTo</span><span class="punctuation token">(</span><span class="number token">25</span> <span class="operator token">+</span> i <span class="operator token">*</span> <span class="number token">50</span><span class="punctuation token">,</span> <span class="number token">140</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">stroke</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> +<span class="punctuation token">}</span></code></pre> + +<div class="hidden"> +<pre class="brush: html line-numbers language-html notranslate"><code class="language-html"><span class="tag token"><span class="tag token"><span class="punctuation token"><</span>canvas</span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>canvas<span class="punctuation token">"</span></span> <span class="attr-name token">width</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>150<span class="punctuation token">"</span></span> <span class="attr-name token">height</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>150<span class="punctuation token">"</span></span><span class="punctuation token">></span></span><span class="tag token"><span class="tag token"><span class="punctuation token"></</span>canvas</span><span class="punctuation token">></span></span></code></pre> + +<pre class="brush: js line-numbers language-js notranslate"><code class="language-js"><span class="function token">draw</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre> +</div> + +<p>{{EmbedLiveSample("A_lineCap_example", "180", "180", "https://mdn.mozillademos.org/files/236/Canvas_linecap.png")}}</p> + +<h3 id="A_lineJoin_example" name="A_lineJoin_example">Un exemple de <code>lineJoin</code></h3> + +<p>La propriété <code>lineJoin</code> détermine comment deux segments (lignes, arcs ou courbes), de largeur non nulle se connectant dans une forme, sont joints ensemble (les segments de longueur nulle, dont les coordonnées de départ et de fin sont exactement les mêmes, sont ignorés).</p> + +<p>Il existe trois valeurs possibles pour cette propriété : <code>round</code>, <code>bevel</code> et <code>miter</code>. Par défaut, cette propriété est définie à <code>miter</code>. Notez que le paramètre <code>lineJoin</code> n'a pas d'effet si les deux segments connectés ont la même direction, parce qu'aucune zone de jointure ne sera ajoutée dans ce cas.</p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/237/Canvas_linejoin.png" style="float: right; height: 190px; width: 190px;"></p> + +<dl> + <dt><code>round </code><em>(rond)</em></dt> + <dd>Arrondit les angles des segments en ajoutant un arc de cercle centré à l'extrémité commune des segments connectés. Le rayon de ces angles arrondis est égal à la moitié de la largeur du trait.</dd> + <dt><code>bevel </code><em>(biseau)</em></dt> + <dd>Ajoute un triangle à l'extrémité commune des segments connectés.</dd> + <dt><code>miter </code><em>(onglet)</em></dt> + <dd><span id="result_box" lang="fr"><span>Les segments connectés sont reliés en prolongeant leurs bords extérieurs pour se connecter en un seul point, avec pour effet de remplir une zone supplémentaire en forme de losange.</span> <span>Ce paramètre est effectué par la propriété miterLimit qui est expliquée ci-dessous.</span></span></dd> +</dl> + +<p><span id="result_box" lang="fr"><span>L'exemple ci-dessous dessine trois chemins différents, démontrant chacun de ces trois paramètres de propriété<code> lineJoin</code> ;</span> <span>la sortie est montrée ci-dessus.</span></span></p> + +<pre class="brush: js;highlight[6] line-numbers language-js notranslate"><code class="language-js"><span class="keyword token">function</span> <span class="function token">draw</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> ctx <span class="operator token">=</span> document<span class="punctuation token">.</span><span class="function token">getElementById</span><span class="punctuation token">(</span><span class="string token">'canvas'</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">getContext</span><span class="punctuation token">(</span><span class="string token">'2d'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">var</span> lineJoin <span class="operator token">=</span> <span class="punctuation token">[</span><span class="string token">'round'</span><span class="punctuation token">,</span> <span class="string token">'bevel'</span><span class="punctuation token">,</span> <span class="string token">'miter'</span><span class="punctuation token">]</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span>lineWidth <span class="operator token">=</span> <span class="number token">10</span><span class="punctuation token">;</span> + <span class="keyword token">for</span> <span class="punctuation token">(</span><span class="keyword token">var</span> i <span class="operator token">=</span> <span class="number token">0</span><span class="punctuation token">;</span> i <span class="operator token"><</span> lineJoin<span class="punctuation token">.</span>length<span class="punctuation token">;</span> i<span class="operator token">++</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + ctx<span class="punctuation token">.</span>lineJoin <span class="operator token">=</span> lineJoin<span class="punctuation token">[</span>i<span class="punctuation token">]</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">beginPath</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">moveTo</span><span class="punctuation token">(</span><span class="operator token">-</span><span class="number token">5</span><span class="punctuation token">,</span> <span class="number token">5</span> <span class="operator token">+</span> i <span class="operator token">*</span> <span class="number token">40</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">lineTo</span><span class="punctuation token">(</span><span class="number token">35</span><span class="punctuation token">,</span> <span class="number token">45</span> <span class="operator token">+</span> i <span class="operator token">*</span> <span class="number token">40</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">lineTo</span><span class="punctuation token">(</span><span class="number token">75</span><span class="punctuation token">,</span> <span class="number token">5</span> <span class="operator token">+</span> i <span class="operator token">*</span> <span class="number token">40</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">lineTo</span><span class="punctuation token">(</span><span class="number token">115</span><span class="punctuation token">,</span> <span class="number token">45</span> <span class="operator token">+</span> i <span class="operator token">*</span> <span class="number token">40</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">lineTo</span><span class="punctuation token">(</span><span class="number token">155</span><span class="punctuation token">,</span> <span class="number token">5</span> <span class="operator token">+</span> i <span class="operator token">*</span> <span class="number token">40</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">stroke</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> +<span class="punctuation token">}</span></code></pre> + +<div class="hidden"> +<pre class="brush: html line-numbers language-html notranslate"><code class="language-html"><span class="tag token"><span class="tag token"><span class="punctuation token"><</span>canvas</span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>canvas<span class="punctuation token">"</span></span> <span class="attr-name token">width</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>150<span class="punctuation token">"</span></span> <span class="attr-name token">height</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>150<span class="punctuation token">"</span></span><span class="punctuation token">></span></span><span class="tag token"><span class="tag token"><span class="punctuation token"></</span>canvas</span><span class="punctuation token">></span></span></code></pre> + +<pre class="brush: js line-numbers language-js notranslate"><code class="language-js"><span class="function token">draw</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre> +</div> + +<p>{{EmbedLiveSample("A_lineJoin_example", "180", "180", "https://mdn.mozillademos.org/files/237/Canvas_linejoin.png")}}</p> + +<h3 id="A_demo_of_the_miterLimit_property" name="A_demo_of_the_miterLimit_property">Une démonstration de la propriété <code>miterLimit</code></h3> + +<p><span id="result_box" lang="fr"><span>Comme vous l'avez vu dans l'exemple précédent, lorsque vous joignez deux lignes avec l'option d'onglet, les bords extérieurs des deux lignes d'assemblage sont étendus jusqu'au point où ils se rencontrent.</span> <span>Pour les lignes qui sont à grands angles les unes avec les autres, ce point n'est pas loin du point de connexion interne.</span> <span>Cependant, lorsque les angles entre chaque ligne diminuent, la distance entre ces points augmente exponentiellement.</span></span></p> + +<p><span id="result_box" lang="fr"><span>La propriété <code>miterLimit</code> détermine dans quelle mesure le point de connexion externe peut être placé à partir du point de connexion interne.</span> <span>Si deux lignes dépassent cette valeur, une jointure biseau est dessinée à la place.</span> <span>Notez que la longueur ajoutée maximale est le produit de la largeur de ligne mesurée dans le système de coordonnées actuel, par la valeur de cette propriété <code>miterLimit</code> (dont la valeur par défaut est 10.0 dans le HTML </span></span> {{HTMLElement("canvas")}}). <span lang="fr"><code> </code><span><code>miterLimit</code> peut être défini indépendamment de l'échelle d'affichage actuelle ou de toutes les transformations affinées de chemins : il n'influence que la forme des bords de lignes effectivement rendues.</span></span></p> + +<p><span id="result_box" lang="fr"><span>Plus précisément, la limite d'onglet est le rapport maximal autorisé de la longueur d'extension (dans le canvas HTML, il est mesuré entre le coin extérieur des bords joints de la ligne et le point d'extrémité commun des segments de connexion spécifiés dans le chemin) à la moitié</span> de la <span>largeur de la ligne.</span> <span>Il peut être défini, de manière équivalente, comme le rapport maximum autorisé de la distance entre les points de jonction intérieur et extérieur des bords et la largeur totale de la ligne.</span> <span>Il est alors égal à la cosécante de la moitié de l'angle interne minimum des segments de connexion, en-dessous de laquelle aucune jointure d'onglet ne sera rendue, mais seulement une jointure en biseau :</span></span></p> + +<ul> + <li><code>miterLimit</code> = <strong>max</strong> <code>miterLength</code> / <code>lineWidth</code> = 1 / <strong>sin</strong> ( <strong>min</strong> <em>θ</em> / 2 )</li> + <li><span id="result_box" lang="fr"><span>La limite d'onglet par défaut de 10.0 supprimera tous les onglets pour les angles vifs inférieurs à environ 11 degrés.</span></span></li> + <li><span id="result_box" lang="fr"><span>Une limite d'onglet égale à √2 ≈ 1.4142136 (arrondie au-dessus) enlèvera les onglets pour tous les angles aigus, en conservant les joints d'onglet seulement pour les angles obtus ou droits.</span></span></li> + <li><span id="result_box" lang="fr"><span>Une limite d'onglet égale à 1.0 est valide mais désactivera tous les onglets.</span></span></li> + <li><span id="result_box" lang="fr"><span>Les valeurs inférieures à 1.0 sont invalides pour la limite d'onglet.</span></span></li> +</ul> + +<p><span id="result_box" lang="fr"><span>Voici une petite démo dans laquelle vous pouvez définir dynamiquement <code>miterLimit</code> et voir comment cela affecte les formes sur le canevas.</span> <span>Les lignes bleues indiquent où se trouvent les points de départ et d'arrivée de chacune des lignes du motif en zig-zag.</span></span></p> + +<p><span id="result_box" lang="fr"><span>Si vous spécifiez une valeur <code>miterLimit</code> inférieure à 4.2 dans cette démo, aucun des coins visibles ne se joindra avec une extension onglet, mais seulement avec un petit biseau près des lignes bleues ;</span> <span>avec une limite à onglets au-dessus de 10, la plupart des coins de cette démo devraient se combiner avec un onglet loin des lignes bleues et dont la hauteur diminue entre les coins de gauche à droite, car ils se connectent avec des angles croissants ;</span> <span>avec des valeurs intermédiaires, les coins du côté gauche ne rejoignent qu'un biseau près des lignes bleues et les coins du côté droit avec une extension à onglets (également avec une hauteur décroissante).</span></span></p> + +<pre class="brush: js;highlight[18] line-numbers language-js notranslate"><code class="language-js"><span class="keyword token">function</span> <span class="function token">draw</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> ctx <span class="operator token">=</span> document<span class="punctuation token">.</span><span class="function token">getElementById</span><span class="punctuation token">(</span><span class="string token">'canvas'</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">getContext</span><span class="punctuation token">(</span><span class="string token">'2d'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="comment token">// Éffacer canvas</span> + ctx<span class="punctuation token">.</span><span class="function token">clearRect</span><span class="punctuation token">(</span><span class="number token">0</span><span class="punctuation token">,</span> <span class="number token">0</span><span class="punctuation token">,</span> <span class="number token">150</span><span class="punctuation token">,</span> <span class="number token">150</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="comment token">// Dessiner des guides</span> + ctx<span class="punctuation token">.</span>strokeStyle <span class="operator token">=</span> <span class="string token">'#09f'</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span>lineWidth <span class="operator token">=</span> <span class="number token">2</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">strokeRect</span><span class="punctuation token">(</span><span class="operator token">-</span><span class="number token">5</span><span class="punctuation token">,</span> <span class="number token">50</span><span class="punctuation token">,</span> <span class="number token">160</span><span class="punctuation token">,</span> <span class="number token">50</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="comment token">// Définir les styles de lignes</span> + ctx<span class="punctuation token">.</span>strokeStyle <span class="operator token">=</span> <span class="string token">'#000'</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span>lineWidth <span class="operator token">=</span> <span class="number token">10</span><span class="punctuation token">;</span> + + <span class="comment token">// Vérifier l'entrée <em>(input)</em></span> + <span class="keyword token">if</span> <span class="punctuation token">(</span>document<span class="punctuation token">.</span><span class="function token">getElementById</span><span class="punctuation token">(</span><span class="string token">'miterLimit'</span><span class="punctuation token">)</span><span class="punctuation token">.</span>value<span class="punctuation token">.</span><span class="function token">match</span><span class="punctuation token">(</span><span class="regex token">/\d+(\.\d+)?/</span><span class="punctuation token">)</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + ctx<span class="punctuation token">.</span>miterLimit <span class="operator token">=</span> <span class="function token">parseFloat</span><span class="punctuation token">(</span>document<span class="punctuation token">.</span><span class="function token">getElementById</span><span class="punctuation token">(</span><span class="string token">'miterLimit'</span><span class="punctuation token">)</span><span class="punctuation token">.</span>value<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> <span class="keyword token">else</span> <span class="punctuation token">{</span> + <span class="function token">alert</span><span class="punctuation token">(</span><span class="string token">'Value must be a positive number'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> + + <span class="comment token">// Dessiner des lignes</span> + ctx<span class="punctuation token">.</span><span class="function token">beginPath</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">moveTo</span><span class="punctuation token">(</span><span class="number token">0</span><span class="punctuation token">,</span> <span class="number token">100</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">for</span> <span class="punctuation token">(</span>i <span class="operator token">=</span> <span class="number token">0</span><span class="punctuation token">;</span> i <span class="operator token"><</span> <span class="number token">24</span> <span class="punctuation token">;</span> i<span class="operator token">++</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> dy <span class="operator token">=</span> i <span class="operator token">%</span> <span class="number token">2</span> <span class="operator token">==</span> <span class="number token">0</span> <span class="operator token">?</span> <span class="number token">25</span> <span class="punctuation token">:</span> <span class="operator token">-</span><span class="number token">25</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">lineTo</span><span class="punctuation token">(</span>Math<span class="punctuation token">.</span><span class="function token">pow</span><span class="punctuation token">(</span>i<span class="punctuation token">,</span> <span class="number token">1.5</span><span class="punctuation token">)</span> <span class="operator token">*</span> <span class="number token">2</span><span class="punctuation token">,</span> <span class="number token">75</span> <span class="operator token">+</span> dy<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> + ctx<span class="punctuation token">.</span><span class="function token">stroke</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">return</span> <span class="keyword token">false</span><span class="punctuation token">;</span> +<span class="punctuation token">}</span></code></pre> + +<div class="hidden"> +<pre class="brush: html line-numbers language-html notranslate"><code class="language-html"><span class="tag token"><span class="tag token"><span class="punctuation token"><</span>table</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>tr</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>td</span><span class="punctuation token">></span></span><span class="tag token"><span class="tag token"><span class="punctuation token"><</span>canvas</span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>canvas<span class="punctuation token">"</span></span> <span class="attr-name token">width</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>150<span class="punctuation token">"</span></span> <span class="attr-name token">height</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>150<span class="punctuation token">"</span></span><span class="punctuation token">></span></span><span class="tag token"><span class="tag token"><span class="punctuation token"></</span>canvas</span><span class="punctuation token">></span></span><span class="tag token"><span class="tag token"><span class="punctuation token"></</span>td</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>td</span><span class="punctuation token">></span></span>Change the <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>code</span><span class="punctuation token">></span></span>miterLimit<span class="tag token"><span class="tag token"><span class="punctuation token"></</span>code</span><span class="punctuation token">></span></span> by entering a new value below and clicking the redraw button.<span class="tag token"><span class="tag token"><span class="punctuation token"><</span>br</span><span class="punctuation token">></span></span><span class="tag token"><span class="tag token"><span class="punctuation token"><</span>br</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>form</span> <span class="attr-name token">onsubmit</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>return draw();<span class="punctuation token">"</span></span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>label</span><span class="punctuation token">></span></span>Miter limit<span class="tag token"><span class="tag token"><span class="punctuation token"></</span>label</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>input</span> <span class="attr-name token">type</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>text<span class="punctuation token">"</span></span> <span class="attr-name token">size</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>3<span class="punctuation token">"</span></span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>miterLimit<span class="punctuation token">"</span></span><span class="punctuation token">/></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>input</span> <span class="attr-name token">type</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>submit<span class="punctuation token">"</span></span> <span class="attr-name token">value</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>Redraw<span class="punctuation token">"</span></span><span class="punctuation token">/></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>form</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>td</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>tr</span><span class="punctuation token">></span></span> +<span class="tag token"><span class="tag token"><span class="punctuation token"></</span>table</span><span class="punctuation token">></span></span></code></pre> + +<pre class="brush: js line-numbers language-js notranslate"><code class="language-js">document<span class="punctuation token">.</span><span class="function token">getElementById</span><span class="punctuation token">(</span><span class="string token">'miterLimit'</span><span class="punctuation token">)</span><span class="punctuation token">.</span>value <span class="operator token">=</span> document<span class="punctuation token">.</span><span class="function token">getElementById</span><span class="punctuation token">(</span><span class="string token">'canvas'</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">getContext</span><span class="punctuation token">(</span><span class="string token">'2d'</span><span class="punctuation token">)</span><span class="punctuation token">.</span>miterLimit<span class="punctuation token">;</span> +<span class="function token">draw</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre> +</div> + +<p>{{EmbedLiveSample("A_demo_of_the_miterLimit_property", "400", "180", "https://mdn.mozillademos.org/files/240/Canvas_miterlimit.png")}}</p> + +<h3 id="Using_line_dashes" name="Using_line_dashes">Utilisation de lignes pointillées</h3> + +<p><code>setLineDash</code> et <code>lineDashOffset</code> précisent le modèle de lignes. <code>setLineDash</code> accepte une liste de nombres qui spécifie les distances pour dessiner alternativement une ligne et un espace et <code>lineDashOffset</code> définit un décalage pour commencer le motif.</p> + +<p>Dans cet exemple, nous créons un effet de fourmis en marche. C'est une technique d'animation souvent employée dans les <span class="new"> sélections d'outils</span> des programmes graphiques. Cet effet permet à l'utilisateur de distinguer la frontière de l'image de fond de la sélection en animant la frontière. Dans une partie de ce tutoriel, vous pouvez apprendre comment faire cela et d'autres animations de base <a href="/fr/docs/Web/API/Canvas_API/Tutorial/Basic_animations" title="/fr/docs/Web/API/Canvas_API/Tutorial/Basic_animations">animation basiques.</a><a href="https://developer.mozilla.org/fr/docs/Tutoriel_canvas/Animations_basiques">.</a></p> + +<div class="hidden"> +<pre class="brush: html line-numbers language-html notranslate"><code class="language-html"><span class="tag token"><span class="tag token"><span class="punctuation token"><</span>canvas</span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>canvas<span class="punctuation token">"</span></span> <span class="attr-name token">width</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>110<span class="punctuation token">"</span></span> <span class="attr-name token">height</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>110<span class="punctuation token">"</span></span><span class="punctuation token">></span></span><span class="tag token"><span class="tag token"><span class="punctuation token"></</span>canvas</span><span class="punctuation token">></span></span></code></pre> +</div> + +<pre class="brush: js;highlight[6] line-numbers language-js notranslate"><code class="language-js"><span class="keyword token">var</span> ctx <span class="operator token">=</span> document<span class="punctuation token">.</span><span class="function token">getElementById</span><span class="punctuation token">(</span><span class="string token">'canvas'</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">getContext</span><span class="punctuation token">(</span><span class="string token">'2d'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="keyword token">var</span> offset <span class="operator token">=</span> <span class="number token">0</span><span class="punctuation token">;</span> + +<span class="keyword token">function</span> <span class="function token">draw</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + ctx<span class="punctuation token">.</span><span class="function token">clearRect</span><span class="punctuation token">(</span><span class="number token">0</span><span class="punctuation token">,</span> <span class="number token">0</span><span class="punctuation token">,</span> canvas<span class="punctuation token">.</span>width<span class="punctuation token">,</span> canvas<span class="punctuation token">.</span>height<span class="punctuation token">)</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">setLineDash</span><span class="punctuation token">(</span><span class="punctuation token">[</span><span class="number token">4</span><span class="punctuation token">,</span> <span class="number token">2</span><span class="punctuation token">]</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span>lineDashOffset <span class="operator token">=</span> <span class="operator token">-</span>offset<span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">strokeRect</span><span class="punctuation token">(</span><span class="number token">10</span><span class="punctuation token">,</span> <span class="number token">10</span><span class="punctuation token">,</span> <span class="number token">100</span><span class="punctuation token">,</span> <span class="number token">100</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="punctuation token">}</span> + +<span class="keyword token">function</span> <span class="function token">march</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + offset<span class="operator token">++</span><span class="punctuation token">;</span> + <span class="keyword token">if</span> <span class="punctuation token">(</span>offset <span class="operator token">></span> <span class="number token">16</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + offset <span class="operator token">=</span> <span class="number token">0</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> + <span class="function token">draw</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="function token">setTimeout</span><span class="punctuation token">(</span>march<span class="punctuation token">,</span> <span class="number token">20</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="punctuation token">}</span> + +<span class="function token">march</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre> + +<p>{{EmbedLiveSample("Using_line_dashes", "120", "120", "https://mdn.mozillademos.org/files/9853/marching-ants.png")}}</p> + +<h2 id="Gradients" name="Gradients">Dégradés</h2> + +<p><span id="result_box" lang="fr"><span>Comme n'importe quel programme de dessin normal, nous pouvons remplir et découper des formes à l'aide de dégradés linéaires et radiaux.</span> <span>Nous créons un objet {{domxref ("CanvasGradient")}} en utilisant l'une des méthodes suivantes.</span> <span>Nous pouvons ensuite affecter cet objet aux propriétés <code>fillStyle</code> ou <code>strokeStyle</code>.</span></span></p> + +<dl> + <dt>{{domxref("CanvasRenderingContext2D.createLinearGradient", "createLinearGradient(x1, y1, x2, y2)")}}</dt> + <dd><span id="result_box" lang="fr"><span>Crée un objet dégradé linéaire avec un point de départ (<code>x1</code>, <code>y1</code>) et un point final (<code>x2</code>, <code>y2</code>).</span></span></dd> + <dt>{{domxref("CanvasRenderingContext2D.createRadialGradient", "createRadialGradient(x1, y1, r1, x2, y2, r2)")}}</dt> + <dd><span id="result_box" lang="fr"><span>Crée un dégradé radial.</span> <span>Les paramètres représentent deux cercles, l'un avec son centre à (<code>x1</code>, <code>y1</code>) et un rayon <code>r1</code>, l'autre avec son centre à (<code>x2</code>, <code>y2</code>) avec un rayon <code>r2</code>.</span></span></dd> +</dl> + +<p>Par exemple:</p> + +<pre class="brush: js line-numbers language-js notranslate"><code class="language-js"><span class="keyword token">var</span> lineargradient <span class="operator token">=</span> ctx<span class="punctuation token">.</span><span class="function token">createLinearGradient</span><span class="punctuation token">(</span><span class="number token">0</span><span class="punctuation token">,</span> <span class="number token">0</span><span class="punctuation token">,</span> <span class="number token">150</span><span class="punctuation token">,</span> <span class="number token">150</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="keyword token">var</span> radialgradient <span class="operator token">=</span> ctx<span class="punctuation token">.</span><span class="function token">createRadialGradient</span><span class="punctuation token">(</span><span class="number token">75</span><span class="punctuation token">,</span> <span class="number token">75</span><span class="punctuation token">,</span> <span class="number token">0</span><span class="punctuation token">,</span> <span class="number token">75</span><span class="punctuation token">,</span> <span class="number token">75</span><span class="punctuation token">,</span> <span class="number token">100</span><span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre> + +<p><span id="result_box" lang="fr"><span>Une fois que nous avons créé un objet <code>CanvasGradient</code>, nous pouvons lui assigner des couleurs en utilisant la méthode <code>addColorStop ()</code>.</span></span></p> + +<dl> + <dt>{{domxref("CanvasGradient.addColorStop", "gradient.addColorStop(position, color)")}}</dt> + <dd><span id="result_box" lang="fr"><span>Crée un nouvel arrêt de couleur sur l'objet <code>gradient</code> <em>(dégradé)</em>.</span> <span>La position est un nombre entre 0.0 et 1.0 et définit la position relative de la couleur dans le dégradé ; et l'argument <code>color</code> doit être une chaîne représentant une CSS {{cssxref ("<color>")}}, indiquant la couleur que le dégradé</span> <span>devrait atteindre.</span></span></dd> +</dl> + +<p><span id="result_box" lang="fr"><span>Vous pouvez ajouter autant d'arrêts de couleur à un dégradé que vous le souhaitez.</span> <span>Ci-dessous figure un dégradé linéaire très simple du blanc au noir.</span></span></p> + +<pre class="brush: js line-numbers language-js notranslate"><code class="language-js"><span class="keyword token">var</span> lineargradient <span class="operator token">=</span> ctx<span class="punctuation token">.</span><span class="function token">createLinearGradient</span><span class="punctuation token">(</span><span class="number token">0</span><span class="punctuation token">,</span> <span class="number token">0</span><span class="punctuation token">,</span> <span class="number token">150</span><span class="punctuation token">,</span> <span class="number token">150</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +lineargradient<span class="punctuation token">.</span><span class="function token">addColorStop</span><span class="punctuation token">(</span><span class="number token">0</span><span class="punctuation token">,</span> <span class="string token">'white'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +lineargradient<span class="punctuation token">.</span><span class="function token">addColorStop</span><span class="punctuation token">(</span><span class="number token">1</span><span class="punctuation token">,</span> <span class="string token">'black'</span><span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre> + +<h3 id="A_createLinearGradient_example" name="A_createLinearGradient_example">Un exemple de <code>createLinearGradient</code></h3> + +<p><span id="result_box" lang="fr"><span>Dans cet exemple, nous allons créer deux dégradés différents.</span> <span>Comme vous pouvez le voir ici, les propriétés <code>strokeStyle</code> et <code>fillStyle</code> peuvent accepter un objet <code>canvasGradient</code> comme entrée valide.</span></span></p> + +<pre class="brush: js;highlight[5,11] line-numbers language-js notranslate"><code class="language-js"><span class="keyword token">function</span> <span class="function token">draw</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> ctx <span class="operator token">=</span> document<span class="punctuation token">.</span><span class="function token">getElementById</span><span class="punctuation token">(</span><span class="string token">'canvas'</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">getContext</span><span class="punctuation token">(</span><span class="string token">'2d'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="comment token">// Créer un dégradé</span> + <span class="keyword token">var</span> lingrad <span class="operator token">=</span> ctx<span class="punctuation token">.</span><span class="function token">createLinearGradient</span><span class="punctuation token">(</span><span class="number token">0</span><span class="punctuation token">,</span> <span class="number token">0</span><span class="punctuation token">,</span> <span class="number token">0</span><span class="punctuation token">,</span> <span class="number token">150</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + lingrad<span class="punctuation token">.</span><span class="function token">addColorStop</span><span class="punctuation token">(</span><span class="number token">0</span><span class="punctuation token">,</span> <span class="string token">'#00ABEB'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + lingrad<span class="punctuation token">.</span><span class="function token">addColorStop</span><span class="punctuation token">(</span><span class="number token">0.5</span><span class="punctuation token">,</span> <span class="string token">'#fff'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + lingrad<span class="punctuation token">.</span><span class="function token">addColorStop</span><span class="punctuation token">(</span><span class="number token">0.5</span><span class="punctuation token">,</span> <span class="string token">'#26C000'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + lingrad<span class="punctuation token">.</span><span class="function token">addColorStop</span><span class="punctuation token">(</span><span class="number token">1</span><span class="punctuation token">,</span> <span class="string token">'#fff'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="keyword token">var</span> lingrad2 <span class="operator token">=</span> ctx<span class="punctuation token">.</span><span class="function token">createLinearGradient</span><span class="punctuation token">(</span><span class="number token">0</span><span class="punctuation token">,</span> <span class="number token">50</span><span class="punctuation token">,</span> <span class="number token">0</span><span class="punctuation token">,</span> <span class="number token">95</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + lingrad2<span class="punctuation token">.</span><span class="function token">addColorStop</span><span class="punctuation token">(</span><span class="number token">0.5</span><span class="punctuation token">,</span> <span class="string token">'#000'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + lingrad2<span class="punctuation token">.</span><span class="function token">addColorStop</span><span class="punctuation token">(</span><span class="number token">1</span><span class="punctuation token">,</span> <span class="string token">'rgba(0, 0, 0, 0)'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="comment token">// assigner des dégradés aux styles "fill" et "stroke"</span> + ctx<span class="punctuation token">.</span>fillStyle <span class="operator token">=</span> lingrad<span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span>strokeStyle <span class="operator token">=</span> lingrad2<span class="punctuation token">;</span> + + <span class="comment token">// Dessiner des formes</span> + ctx<span class="punctuation token">.</span><span class="function token">fillRect</span><span class="punctuation token">(</span><span class="number token">10</span><span class="punctuation token">,</span> <span class="number token">10</span><span class="punctuation token">,</span> <span class="number token">130</span><span class="punctuation token">,</span> <span class="number token">130</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">strokeRect</span><span class="punctuation token">(</span><span class="number token">50</span><span class="punctuation token">,</span> <span class="number token">50</span><span class="punctuation token">,</span> <span class="number token">50</span><span class="punctuation token">,</span> <span class="number token">50</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + +<span class="punctuation token">}</span></code></pre> + +<div class="hidden"> +<pre class="brush: html line-numbers language-html notranslate"><code class="language-html"><span class="tag token"><span class="tag token"><span class="punctuation token"><</span>canvas</span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>canvas<span class="punctuation token">"</span></span> <span class="attr-name token">width</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>150<span class="punctuation token">"</span></span> <span class="attr-name token">height</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>150<span class="punctuation token">"</span></span><span class="punctuation token">></span></span><span class="tag token"><span class="tag token"><span class="punctuation token"></</span>canvas</span><span class="punctuation token">></span></span></code></pre> + +<pre class="brush: js line-numbers language-js notranslate"><code class="language-js"><span class="function token">draw</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre> +</div> + +<p><span id="result_box" lang="fr"><span>Le premier est un dégradé d'arrière-plan.</span> <span>Comme vous pouvez le voir, nous avons assigné deux couleurs à la même position.</span> <span>Vous faites cela pour faire des transitions de couleurs très nettes - dans ce cas du blanc au vert.</span> <span>Normalement, peu importe dans quel ordre vous définissez l'arrêt de la couleur, mais dans ce cas particulier, la différence peut être significative.</span> <span>Si vous conservez les affectations dans l'ordre où vous voulez qu'elles apparaissent, cela ne posera aucun problème.</span></span></p> + +<p><span id="result_box" lang="fr"><span>Dans le second gradient, nous n'avons pas assigné la couleur de départ (à la position 0.0) puisqu'il n'était pas strictement nécessaire car il prendra automatiquement la valeur de la prochaine couleur.</span> <span>Par conséquent, l'attribution de la couleur noire à la position 0,5 fait automatiquement passer le dégradé, du début à l'arrêt, en noir.</span></span></p> + +<p>{{EmbedLiveSample("A_createLinearGradient_example", "180", "180", "https://mdn.mozillademos.org/files/235/Canvas_lineargradient.png")}}</p> + +<h3 id="A_createRadialGradient_example" name="A_createRadialGradient_example">Un exemple de <code>createRadialGradient</code></h3> + +<p><span id="result_box" lang="fr"><span>Dans cet exemple, nous définirons quatre dégradés radiaux différents.</span> <span>Parce que nous avons le contrôle sur les points de départ et de fermeture du dégradé, nous pouvons obtenir des effets plus complexes que nous aurions normalement dans les dégradés radiaux "classiques" (c'est-à-dire un dégradé avec un seul point central </span><span>où le dégradé se développe vers l'extérieur dans une forme circulaire).</span></span></p> + +<pre class="brush: js;highlight[5,10,15,20] line-numbers language-js notranslate"><code class="language-js"><span class="keyword token">function</span> <span class="function token">draw</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> ctx <span class="operator token">=</span> document<span class="punctuation token">.</span><span class="function token">getElementById</span><span class="punctuation token">(</span><span class="string token">'canvas'</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">getContext</span><span class="punctuation token">(</span><span class="string token">'2d'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="comment token">// Créer un dégradé</span> + <span class="keyword token">var</span> radgrad <span class="operator token">=</span> ctx<span class="punctuation token">.</span><span class="function token">createRadialGradient</span><span class="punctuation token">(</span><span class="number token">45</span><span class="punctuation token">,</span> <span class="number token">45</span><span class="punctuation token">,</span> <span class="number token">10</span><span class="punctuation token">,</span> <span class="number token">52</span><span class="punctuation token">,</span> <span class="number token">50</span><span class="punctuation token">,</span> <span class="number token">30</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + radgrad<span class="punctuation token">.</span><span class="function token">addColorStop</span><span class="punctuation token">(</span><span class="number token">0</span><span class="punctuation token">,</span> <span class="string token">'#A7D30C'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + radgrad<span class="punctuation token">.</span><span class="function token">addColorStop</span><span class="punctuation token">(</span><span class="number token">0.9</span><span class="punctuation token">,</span> <span class="string token">'#019F62'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + radgrad<span class="punctuation token">.</span><span class="function token">addColorStop</span><span class="punctuation token">(</span><span class="number token">1</span><span class="punctuation token">,</span> <span class="string token">'rgba(1, 159, 98, 0)'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="keyword token">var</span> radgrad2 <span class="operator token">=</span> ctx<span class="punctuation token">.</span><span class="function token">createRadialGradient</span><span class="punctuation token">(</span><span class="number token">105</span><span class="punctuation token">,</span> <span class="number token">105</span><span class="punctuation token">,</span> <span class="number token">20</span><span class="punctuation token">,</span> <span class="number token">112</span><span class="punctuation token">,</span> <span class="number token">120</span><span class="punctuation token">,</span> <span class="number token">50</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + radgrad2<span class="punctuation token">.</span><span class="function token">addColorStop</span><span class="punctuation token">(</span><span class="number token">0</span><span class="punctuation token">,</span> <span class="string token">'#FF5F98'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + radgrad2<span class="punctuation token">.</span><span class="function token">addColorStop</span><span class="punctuation token">(</span><span class="number token">0.75</span><span class="punctuation token">,</span> <span class="string token">'#FF0188'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + radgrad2<span class="punctuation token">.</span><span class="function token">addColorStop</span><span class="punctuation token">(</span><span class="number token">1</span><span class="punctuation token">,</span> <span class="string token">'rgba(255, 1, 136, 0)'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="keyword token">var</span> radgrad3 <span class="operator token">=</span> ctx<span class="punctuation token">.</span><span class="function token">createRadialGradient</span><span class="punctuation token">(</span><span class="number token">95</span><span class="punctuation token">,</span> <span class="number token">15</span><span class="punctuation token">,</span> <span class="number token">15</span><span class="punctuation token">,</span> <span class="number token">102</span><span class="punctuation token">,</span> <span class="number token">20</span><span class="punctuation token">,</span> <span class="number token">40</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + radgrad3<span class="punctuation token">.</span><span class="function token">addColorStop</span><span class="punctuation token">(</span><span class="number token">0</span><span class="punctuation token">,</span> <span class="string token">'#00C9FF'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + radgrad3<span class="punctuation token">.</span><span class="function token">addColorStop</span><span class="punctuation token">(</span><span class="number token">0.8</span><span class="punctuation token">,</span> <span class="string token">'#00B5E2'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + radgrad3<span class="punctuation token">.</span><span class="function token">addColorStop</span><span class="punctuation token">(</span><span class="number token">1</span><span class="punctuation token">,</span> <span class="string token">'rgba(0, 201, 255, 0)'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="keyword token">var</span> radgrad4 <span class="operator token">=</span> ctx<span class="punctuation token">.</span><span class="function token">createRadialGradient</span><span class="punctuation token">(</span><span class="number token">0</span><span class="punctuation token">,</span> <span class="number token">150</span><span class="punctuation token">,</span> <span class="number token">50</span><span class="punctuation token">,</span> <span class="number token">0</span><span class="punctuation token">,</span> <span class="number token">140</span><span class="punctuation token">,</span> <span class="number token">90</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + radgrad4<span class="punctuation token">.</span><span class="function token">addColorStop</span><span class="punctuation token">(</span><span class="number token">0</span><span class="punctuation token">,</span> <span class="string token">'#F4F201'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + radgrad4<span class="punctuation token">.</span><span class="function token">addColorStop</span><span class="punctuation token">(</span><span class="number token">0.8</span><span class="punctuation token">,</span> <span class="string token">'#E4C700'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + radgrad4<span class="punctuation token">.</span><span class="function token">addColorStop</span><span class="punctuation token">(</span><span class="number token">1</span><span class="punctuation token">,</span> <span class="string token">'rgba(228, 199, 0, 0)'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="comment token">// dessiner des formes</span> + ctx<span class="punctuation token">.</span>fillStyle <span class="operator token">=</span> radgrad4<span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">fillRect</span><span class="punctuation token">(</span><span class="number token">0</span><span class="punctuation token">,</span> <span class="number token">0</span><span class="punctuation token">,</span> <span class="number token">150</span><span class="punctuation token">,</span> <span class="number token">150</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span>fillStyle <span class="operator token">=</span> radgrad3<span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">fillRect</span><span class="punctuation token">(</span><span class="number token">0</span><span class="punctuation token">,</span> <span class="number token">0</span><span class="punctuation token">,</span> <span class="number token">150</span><span class="punctuation token">,</span> <span class="number token">150</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span>fillStyle <span class="operator token">=</span> radgrad2<span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">fillRect</span><span class="punctuation token">(</span><span class="number token">0</span><span class="punctuation token">,</span> <span class="number token">0</span><span class="punctuation token">,</span> <span class="number token">150</span><span class="punctuation token">,</span> <span class="number token">150</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span>fillStyle <span class="operator token">=</span> radgrad<span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">fillRect</span><span class="punctuation token">(</span><span class="number token">0</span><span class="punctuation token">,</span> <span class="number token">0</span><span class="punctuation token">,</span> <span class="number token">150</span><span class="punctuation token">,</span> <span class="number token">150</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="punctuation token">}</span></code></pre> + +<div class="hidden"> +<pre class="brush: html line-numbers language-html notranslate"><code class="language-html"><span class="tag token"><span class="tag token"><span class="punctuation token"><</span>canvas</span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>canvas<span class="punctuation token">"</span></span> <span class="attr-name token">width</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>150<span class="punctuation token">"</span></span> <span class="attr-name token">height</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>150<span class="punctuation token">"</span></span><span class="punctuation token">></span></span><span class="tag token"><span class="tag token"><span class="punctuation token"></</span>canvas</span><span class="punctuation token">></span></span></code></pre> + +<pre class="brush: js line-numbers language-js notranslate"><code class="language-js"><span class="function token">draw</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre> +</div> + +<p><span id="result_box" lang="fr"><span>Dans ce cas, nous avons légèrement décalé le point de départ du point final pour obtenir un effet 3D sphérique.</span> <span>Il est préférable d'éviter de laisser les cercles intérieurs et extérieurs se chevaucher car cela entraîne des effets étranges, difficiles à prédire.</span></span></p> + +<p><span id="result_box" lang="fr"><span>Le dernier arrêt de couleur dans chacun des quatre dégradés utilise une couleur entièrement transparente.</span> <span>Si vous voulez une transition agréable de cette étape à la couleur précédente, les deux couleurs doivent être égales.</span> <span>Ce n'est pas très évident dans le code, car il utilise deux méthodes CSS différentes en démonstration, mais dans le premier dégradé <code># 019F62 = rgba (1,159,98,1)</code>.</span></span></p> + +<p>{{EmbedLiveSample("A_createRadialGradient_example", "180", "180", "https://mdn.mozillademos.org/files/244/Canvas_radialgradient.png")}}</p> + +<h2 id="Patterns" name="Patterns">Modèles</h2> + +<p><span id="result_box" lang="fr"><span>Dans l'un des exemples de la page précédente, nous avons utilisé une série de boucles pour créer un motif d'images.</span> <span>Il existe cependant une méthode beaucoup plus simple : la méthode <code>createPattern ()</code>.</span></span></p> + +<dl> + <dt>{{domxref("CanvasRenderingContext2D.createPattern", "createPattern(image, type)")}}</dt> + <dd><span id="result_box" lang="fr"><span>Crée et renvoie un nouvel objet de canvas.</span> <span><code>image</code> est un {{domxref ("CanvasImageSource")}} (c'est-à-dire un {{domxref ("HTMLImageElement")}} ; un autre élément canvas, </span></span> <code>type</code> <span lang="fr"> <span>est une chaîne indiquant comment utiliser l'image.</span></span></dd> +</dl> + +<p><span id="result_box" lang="fr"><span>Le type spécifie comment utiliser l'image pour créer le motif et doit avoir l'une des valeurs de chaîne suivantes :</span></span></p> + +<dl> + <dt><code>repeat</code></dt> + <dd><span id="result_box" lang="fr"><span>Tapisse la zone en répètant l'image dans les deux sens vertical et horizontal.</span></span></dd> + <dt><code>repeat-x</code></dt> + <dd>Tapisse la zone en répètant l'image horizontalement mais pas verticalement.</dd> + <dt><code>repeat-y</code></dt> + <dd>Tapisse la zone en répètant l'image verticalement mais pas horizontalement.</dd> + <dt><code>no-repeat</code></dt> + <dd>Ne tapisse pas la zone avec l'image, elle est utilisée une seule fois.</dd> +</dl> + +<p><span id="result_box" lang="fr"><span>Nous utilisons cette méthode pour créer un objet {{domxref ("CanvasPattern")}} qui est très similaire aux méthodes de dégradé que nous avons vu ci-dessus.</span> <span>Une fois que nous avons créé un modèle, nous pouvons l'affecter aux propriétés fillStyle ou strokeStyle.</span> <span>Par exemple :</span></span></p> + +<pre class="brush: js line-numbers language-js notranslate"><code class="language-js"><span class="keyword token">var</span> img <span class="operator token">=</span> <span class="keyword token">new</span> <span class="class-name token">Image</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +img<span class="punctuation token">.</span>src <span class="operator token">=</span> <span class="string token">'someimage.png'</span><span class="punctuation token">;</span> +<span class="keyword token">var</span> ptrn <span class="operator token">=</span> ctx<span class="punctuation token">.</span><span class="function token">createPattern</span><span class="punctuation token">(</span>img<span class="punctuation token">,</span> <span class="string token">'repeat'</span><span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre> + +<div class="note"> +<p><strong>Note:</strong> <span id="result_box" lang="fr"><span>Comme avec la méthode <code>drawImage ()</code>, vous devez vous assurer que l'image que vous utilisez est chargée avant d'appeler cette méthode, ou le motif pourrait être mal dessiné.</span></span></p> +</div> + +<h3 id="A_createPattern_example" name="A_createPattern_example">Un exemple de <code>createPattern</code></h3> + +<p><span id="result_box" lang="fr"><span>Dans ce dernier exemple, nous allons créer un modèle à affecter à la propriété <code>fillStyle</code>.</span> <span>La seule chose à noter, est l'utilisation du gestionnaire <code>onload</code> de l'image.</span> <span>Cela permet de s'assurer que l'image est chargée avant d'être affectée au motif.</span></span></p> + +<pre class="brush: js;highlight[10] line-numbers language-js notranslate"><code class="language-js"><span class="keyword token">function</span> <span class="function token">draw</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> ctx <span class="operator token">=</span> document<span class="punctuation token">.</span><span class="function token">getElementById</span><span class="punctuation token">(</span><span class="string token">'canvas'</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">getContext</span><span class="punctuation token">(</span><span class="string token">'2d'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="comment token">// créer un nouvel objet image à utiliser comme modèle</span> + <span class="keyword token">var</span> img <span class="operator token">=</span> <span class="keyword token">new</span> <span class="class-name token">Image</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + img<span class="punctuation token">.</span>src <span class="operator token">=</span> <span class="string token">'https://mdn.mozillademos.org/files/222/Canvas_createpattern.png'</span><span class="punctuation token">;</span> + img<span class="punctuation token">.</span>onload <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + + <span class="comment token">// créer le modèle</span> + <span class="keyword token">var</span> ptrn <span class="operator token">=</span> ctx<span class="punctuation token">.</span><span class="function token">createPattern</span><span class="punctuation token">(</span>img<span class="punctuation token">,</span> <span class="string token">'repeat'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span>fillStyle <span class="operator token">=</span> ptrn<span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">fillRect</span><span class="punctuation token">(</span><span class="number token">0</span><span class="punctuation token">,</span> <span class="number token">0</span><span class="punctuation token">,</span> <span class="number token">150</span><span class="punctuation token">,</span> <span class="number token">150</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="punctuation token">}</span> +<span class="punctuation token">}</span></code></pre> + +<div class="hidden"> +<pre class="brush: html line-numbers language-html notranslate"><code class="language-html"><span class="tag token"><span class="tag token"><span class="punctuation token"><</span>canvas</span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>canvas<span class="punctuation token">"</span></span> <span class="attr-name token">width</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>150<span class="punctuation token">"</span></span> <span class="attr-name token">height</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>150<span class="punctuation token">"</span></span><span class="punctuation token">></span></span><span class="tag token"><span class="tag token"><span class="punctuation token"></</span>canvas</span><span class="punctuation token">></span></span></code></pre> + +<pre class="brush: js line-numbers language-js notranslate"><code class="language-js"><span class="function token">draw</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre> + +<p>Le résultat ressemble à ceci :</p> +</div> + +<p>{{EmbedLiveSample("A_createPattern_example", "180", "180", "https://mdn.mozillademos.org/files/222/Canvas_createpattern.png")}}</p> + +<h2 id="Ombres">Ombres</h2> + +<p><span id="result_box" lang="fr"><span>L'utilisation des ombres ne comporte que quatre propriétés :</span></span></p> + +<dl> + <dt>{{domxref("CanvasRenderingContext2D.shadowOffsetX", "shadowOffsetX = float")}}</dt> + <dd><span id="result_box" lang="fr"><span>Indique la distance horizontale sur laquelle l'ombre doit s'étendre à partir de l'objet.</span> <span>Cette valeur n'est pas affectée par la matrice de transformation.</span> <span>La valeur par défaut est 0.</span></span></dd> + <dt>{{domxref("CanvasRenderingContext2D.shadowOffsetY", "shadowOffsetY = float")}}</dt> + <dd><span id="result_box" lang="fr"><span>Indique la distance verticale sur laquelle l'ombre doit s'étendre à partir de l'objet.</span> <span>Cette valeur n'est pas affectée par la matrice de transformation.</span> <span>La valeur par défaut est 0.</span></span></dd> + <dt>{{domxref("CanvasRenderingContext2D.shadowBlur", "shadowBlur = float")}}</dt> + <dd><span id="result_box" lang="fr"><span>Indique la taille de l'effet de floutage ;</span> <span>cette valeur ne correspond pas à un nombre de pixels et n'est pas affectée par la matrice de transformation actuelle.</span> <span>La valeur par défaut est 0.</span></span></dd> + <dt>{{domxref("CanvasRenderingContext2D.shadowColor", "shadowColor = color")}}</dt> + <dd>Une valeur de couleur CSS standard indiquant la couleur de l'effet d'ombre ; par défaut, il est entièrement noir transparent.</dd> +</dl> + +<p><span id="result_box" lang="fr"><span>Les propriétés <code>shadowOffsetX</code> et <code>shadowOffsetY</code> indiquent sur quelle distance l'ombre doit s'étendre à partir de l'objet dans les directions X et Y;</span> <span>ces valeurs ne sont pas affectées par la matrice de transformation actuelle.</span> <span>Utilisez des valeurs négatives pour faire en sorte que l'ombre s'étende vers le haut ou vers la gauche et des valeurs positives pour que l'ombre s'étende vers le bas ou vers la droite.</span> <span>La valeur par défaut est 0 pour les 2 propriétés.</span></span></p> + +<p><span id="result_box" lang="fr"><span>La propriété <code>shadowBlur</code> indique la taille de l'effet de flou ;</span> <span>cette valeur ne correspond pas à un nombre de pixels et n'est pas affectée par la matrice de transformation actuelle.</span> <span>La valeur par défaut est 0.</span></span></p> + +<p><span id="result_box" lang="fr"><span>La propriété <code>shadowColor</code> est une valeur de couleur CSS standard indiquant la couleur de l'effet d'ombre ;</span> <span>par défaut, il est entièrement en noir transparent.</span></span></p> + +<div class="note"> +<p><strong>Note :</strong> <span id="result_box" lang="fr"><span>Les ombres ne sont dessinées que pour les <a href="https://developer.mozilla.org/fr/docs/Web/API/Canvas_API/Tutorial/Compositing">opérations de composition</a> <code>source-over</code>.</span></span></p> +</div> + +<h3 id="A_shadowed_text_example" name="A_shadowed_text_example">Un exemple de texte ombré</h3> + +<p><span id="result_box" lang="fr"><span>Cet exemple dessine une chaîne de texte avec un effet d'ombrage.</span></span></p> + +<pre class="brush: js;highlight[4,5,6,7] line-numbers language-js notranslate"><code class="language-js"><span class="keyword token">function</span> <span class="function token">draw</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> ctx <span class="operator token">=</span> document<span class="punctuation token">.</span><span class="function token">getElementById</span><span class="punctuation token">(</span><span class="string token">'canvas'</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">getContext</span><span class="punctuation token">(</span><span class="string token">'2d'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + + ctx<span class="punctuation token">.</span>shadowOffsetX <span class="operator token">=</span> <span class="number token">2</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span>shadowOffsetY <span class="operator token">=</span> <span class="number token">2</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span>shadowBlur <span class="operator token">=</span> <span class="number token">2</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span>shadowColor <span class="operator token">=</span> <span class="string token">'rgba(0, 0, 0, 0.5)'</span><span class="punctuation token">;</span> + + ctx<span class="punctuation token">.</span>font <span class="operator token">=</span> <span class="string token">'20px Times New Roman'</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span>fillStyle <span class="operator token">=</span> <span class="string token">'Black'</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">fillText</span><span class="punctuation token">(</span><span class="string token">'Sample String'</span><span class="punctuation token">,</span> <span class="number token">5</span><span class="punctuation token">,</span> <span class="number token">30</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="punctuation token">}</span></code></pre> + +<div class="hidden"> +<pre class="brush: html line-numbers language-html notranslate"><code class="language-html"><span class="tag token"><span class="tag token"><span class="punctuation token"><</span>canvas</span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>canvas<span class="punctuation token">"</span></span> <span class="attr-name token">width</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>150<span class="punctuation token">"</span></span> <span class="attr-name token">height</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>80<span class="punctuation token">"</span></span><span class="punctuation token">></span></span><span class="tag token"><span class="tag token"><span class="punctuation token"></</span>canvas</span><span class="punctuation token">></span></span></code></pre> + +<pre class="brush: js line-numbers language-js notranslate"><code class="language-js"><span class="function token">draw</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre> +</div> + +<p>{{EmbedLiveSample("A_shadowed_text_example", "180", "100", "https://mdn.mozillademos.org/files/2505/shadowed-string.png")}}</p> + +<p><span id="result_box" lang="fr"><span>Nous allons regarder la propriété de la </span></span> <code>font</code> <em>(police de caratères)</em><span lang="fr"><span> et la méthode <code>fillText</code> dans le chapitre suivant sur le <a href="https://developer.mozilla.org/fr/docs/Dessin_de_texte_avec_canvas">dessin de texte</a>.</span></span></p> + +<h2 id="Canvas_fill_rules" name="Canvas_fill_rules"><span class="short_text" id="result_box" lang="fr"><span>Règles de remplissage Canvas</span></span></h2> + +<p><span id="result_box" lang="fr"><span>Lors de l'utilisation de <code>fill</code> (ou {{domxref ("CanvasRenderingContext2D.clip", "clip")}} et </span></span> {{domxref("CanvasRenderingContext2D.isPointInPath", "isPointinPath")}}) , <span lang="fr"> <span>déterminez si un point est à l'intérieur ou à l'extérieur d'un chemin et ainsi, s'il est rempli ou non.</span> <span>Ceci est utile lorsqu'un chemin en croise un autre ou est imbriqué.</span></span><br> + <br> + Deux valeurs sont possibles :</p> + +<ul> + <li><code><strong>"nonzero</strong></code>": la <a class="external external-icon" href="http://en.wikipedia.org/wiki/Nonzero-rule">règle non-zero</a>, qui est la règle par défaut.</li> + <li><code><strong>"evenodd"</strong></code>: La <a class="external external-icon" href="http://en.wikipedia.org/wiki/Even%E2%80%93odd_rule">règle even-odd</a>.</li> +</ul> + +<p>Dans cet exemple, nous utilisons la règle <code>evenodd</code> .</p> + +<pre class="brush: js;highlight[6] line-numbers language-js notranslate"><code class="language-js"><span class="keyword token">function</span> <span class="function token">draw</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> ctx <span class="operator token">=</span> document<span class="punctuation token">.</span><span class="function token">getElementById</span><span class="punctuation token">(</span><span class="string token">'canvas'</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">getContext</span><span class="punctuation token">(</span><span class="string token">'2d'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">beginPath</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">arc</span><span class="punctuation token">(</span><span class="number token">50</span><span class="punctuation token">,</span> <span class="number token">50</span><span class="punctuation token">,</span> <span class="number token">30</span><span class="punctuation token">,</span> <span class="number token">0</span><span class="punctuation token">,</span> Math<span class="punctuation token">.</span>PI <span class="operator token">*</span> <span class="number token">2</span><span class="punctuation token">,</span> <span class="keyword token">true</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">arc</span><span class="punctuation token">(</span><span class="number token">50</span><span class="punctuation token">,</span> <span class="number token">50</span><span class="punctuation token">,</span> <span class="number token">15</span><span class="punctuation token">,</span> <span class="number token">0</span><span class="punctuation token">,</span> Math<span class="punctuation token">.</span>PI <span class="operator token">*</span> <span class="number token">2</span><span class="punctuation token">,</span> <span class="keyword token">true</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">fill</span><span class="punctuation token">(</span><span class="string token">'evenodd'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="punctuation token">}</span></code></pre> + +<div class="hidden"> +<pre class="brush: html line-numbers language-html notranslate"><code class="language-html"><span class="tag token"><span class="tag token"><span class="punctuation token"><</span>canvas</span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>canvas<span class="punctuation token">"</span></span> <span class="attr-name token">width</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>100<span class="punctuation token">"</span></span> <span class="attr-name token">height</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>100<span class="punctuation token">"</span></span><span class="punctuation token">></span></span><span class="tag token"><span class="tag token"><span class="punctuation token"></</span>canvas</span><span class="punctuation token">></span></span></code></pre> + +<pre class="brush: js line-numbers language-js notranslate"><code class="language-js"><span class="function token">draw</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre> +</div> + +<p>{{EmbedLiveSample("Canvas_fill_rules", "110", "110", "https://mdn.mozillademos.org/files/9855/fill-rule.png")}}</p> + +<p>{{PreviousNext("Tutoriel_canvas/Formes_géométriques", "Dessin_de_texte_avec_canvas")}}</p> diff --git a/files/fr/web/api/canvas_api/tutoriel_canvas/animations_basiques/index.html b/files/fr/web/api/canvas_api/tutoriel_canvas/animations_basiques/index.html new file mode 100644 index 0000000000..f44929e8be --- /dev/null +++ b/files/fr/web/api/canvas_api/tutoriel_canvas/animations_basiques/index.html @@ -0,0 +1,339 @@ +--- +title: Animations basiques +slug: Web/API/Canvas_API/Tutoriel_canvas/Animations_basiques +tags: + - Canvas + - Graphiques + - HTML + - HTML5 + - Intermédiaire + - Tutoriel +translation_of: Web/API/Canvas_API/Tutorial/Basic_animations +--- +<div>{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Compositing", "Tutoriel_canvas/Advanced_animations")}}</div> + +<div class="summary"> +<p>Avec l'utilisation en Javascript du composant {{HTMLElement("canvas")}}, il est très simple de créer des animations (interactives). Ce chapitre décrit comment créer quelques animations basiques.</p> +</div> + +<p>La plus grosse limitation est sans doute qu'une fois qu'une forme est dessinée, elle reste telle quelle. Si on a besoin de la déplacer, il faut la redessiner avec ce qui était dessiné avant. Cela peut prendre beaucoup de temps de redessiner des images complexes et les performances dépendront beaucoup de la vitesse de l'ordinateur qui exécute cet affichage.</p> + +<h2 id="Basic_animation_steps" name="Basic_animation_steps">Les étapes d'une animation basique</h2> + +<p>Voici les étapes à suivre à chaque image dessinée (frame) :</p> + +<ol> + <li><strong>Effacer le canevas</strong><br> + À moins que les formes que vous voulez dessiner remplissent complètement le canevas (par exemple une image en arrière-plan), vous devrez effacer toutes les formes qui ont été dessinées précédemment. La manière la plus simple de le faire est d'utiliser la méthode {{domxref("CanvasRenderingContext2D.clearRect", "clearRect()")}}.</li> + <li><strong>Enregistrer l'état du canevas</strong><br> + Si vous changez des configurations qui affectent l'état du canevas (comme le style, les transformations, etc.), et vous voulez vous assurer que c'est l'état original qui est utilisé chaque fois que le canevas est redessiné, alors vous devez enregistrer l'état original.</li> + <li><strong>Dessiner les formes animées</strong><br> + Vous effectuez toutes les opérations pour afficher l'image.</li> + <li><strong>Restaurer l'état du canevas</strong><br> + Si l'état du canevas a été sauvegardé, vous restaurez cet état avant le prochain rendu.</li> +</ol> + +<h2 id="Controlling_an_animation" name="Controlling_an_animation">Contrôle d'une animation</h2> + +<p>Les formes sont dessinées en utilisant soit les méthodes du canevas directement soit en appelant des fonctions personnalisées. Dans des conditions normales, on ne voit le résultat des opérations sur le canevas que quand le script a terminé son exécution. Cela signifie qu'il n'est pas possible de créer une animation avec une boucle <code>for</code>.</p> + +<p>Il nous faut donc un moyen d'exécuter nos fonctions de dessin sur une période de temps. Il existe à ce jour trois manières de le faire.</p> + +<h3 id="Mises_à_jour_planifiées">Mises à jour planifiées</h3> + +<p>Les fonctions {{domxref("window.setInterval()")}}, {{domxref("window.setTimeout()")}}, et {{domxref("window.requestAnimationFrame()")}} peuvent être utilisées :</p> + +<dl> + <dt>{{domxref("WindowTimers.setInterval", "setInterval(function, delay)")}}</dt> + <dd>Lance la fonction définie par <code>function</code> chaque <code>delay</code> <em>(délai)</em> millisecondes.</dd> + <dt>{{domxref("WindowTimers.setTimeout", "setTimeout(function, delay)")}}</dt> + <dd>Exécute la fonction définie par <code>function</code> dans <code>delay</code> millisecondes.</dd> + <dt>{{domxref("Window.requestAnimationFrame()", "requestAnimationFrame(callback)")}}</dt> + <dd>Dit au navigateur qu'on veut afficher une animation et lui demande d'appeler la fonction <code>callback</code> pour mettre à jour cette animation avant de dessiner la prochaine image.</dd> +</dl> + +<p>Si vous n'avez pas besoin d'interaction utilisateur, vous pouvez utiliser la fonction <code>setInterval()</code>, elle va exécuter périodiquement votre code.</p> + +<p>Si vous voulez faire un jeu, et utiliser les événements du clavier et de la souris pour contrôler l'animation, vous pouvez utiliser <code>setTimeout()</code>. En utilisant des {{domxref("EventListener")}}, on peut récupèrer chaque interaction et d'exécuter nos fonctions d'animation.</p> + +<p>Dans les exemples suivants, nous utiliserons {{domxref("window.requestAnimationFrame()")}} pour contrôler les animations. Cette technique est plus fluide et plus efficace, elle appelle les opérations de rendu quand le système est prêt à dessiner l'image. Dans des conditions idéales, la fonction est alors lancée 60 fois par seconde, mais la fréquence sera réduite si l'animation se passe dans un onglet non visible.</p> + +<div class="note"> +<p>Pour plus d'informations sur la boucle d'animation, plus spécialement pour les jeux, rendez-vous sur l'article <a href="https://developer.mozilla.org/fr/docs/Jeux/Anatomie">L'anatomie d'un jeu vidéo</a> dans notre section <a href="https://developer.mozilla.org/fr/docs/Jeux">Développement de jeux vidéo</a>.</p> +</div> + +<h2 id="Un_système_terrestre_animé">Un système terrestre animé</h2> + +<p>Cette exemple anime un petit modèle de notre système terrestre.</p> + +<pre class="brush: js notranslate">var sun = new Image(); +var moon = new Image(); +var earth = new Image(); +function init(){ + sun.src = 'https://mdn.mozillademos.org/files/1456/Canvas_sun.png'; + moon.src = 'https://mdn.mozillademos.org/files/1443/Canvas_moon.png'; + earth.src = 'https://mdn.mozillademos.org/files/1429/Canvas_earth.png'; + window.requestAnimationFrame(draw); +} + +function draw() { + var ctx = document.getElementById('canvas').getContext('2d'); + + ctx.globalCompositeOperation = 'destination-over'; + ctx.clearRect(0,0,300,300); // effacer le canvas + + ctx.fillStyle = 'rgba(0,0,0,0.4)'; + ctx.strokeStyle = 'rgba(0,153,255,0.4)'; + ctx.save(); + ctx.translate(150,150); + + // Terre + var time = new Date(); + ctx.rotate( ((2*Math.PI)/60)*time.getSeconds() + ((2*Math.PI)/60000)*time.getMilliseconds() ); + ctx.translate(105,0); + ctx.fillRect(0,-12,50,24); // Ombre + ctx.drawImage(earth,-12,-12); + + // Lune + ctx.save(); + ctx.rotate( ((2*Math.PI)/6)*time.getSeconds() + ((2*Math.PI)/6000)*time.getMilliseconds() ); + ctx.translate(0,28.5); + ctx.drawImage(moon,-3.5,-3.5); + ctx.restore(); + + ctx.restore(); + + ctx.beginPath(); + ctx.arc(150,150,105,0,Math.PI*2,false); // Orbite terrestre + ctx.stroke(); + + ctx.drawImage(sun,0,0,300,300); + + window.requestAnimationFrame(draw); +} + +init(); +</pre> + +<div class="hidden"> +<pre class="brush: html notranslate"><canvas id="canvas" width="300" height="300"></canvas></pre> +</div> + +<p>{{EmbedLiveSample("Un_système_terrestre_animé", "310", "310", "https://mdn.mozillademos.org/files/202/Canvas_animation1.png")}}</p> + +<h2 id="Une_horloge_animée">Une horloge animée</h2> + +<p>Cette exemple dessine une horloge animée qui affiche l'heure actuelle.</p> + +<pre class="brush: js notranslate">function clock(){ + var now = new Date(); + var ctx = document.getElementById('canvas').getContext('2d'); + ctx.save(); + ctx.clearRect(0,0,150,150); + ctx.translate(75,75); + ctx.scale(0.4,0.4); + ctx.rotate(-Math.PI/2); + ctx.strokeStyle = "black"; + ctx.fillStyle = "white"; + ctx.lineWidth = 8; + ctx.lineCap = "round"; + + // Marquage des heures + ctx.save(); + for (var i=0;i<12;i++){ + ctx.beginPath(); + ctx.rotate(Math.PI/6); + ctx.moveTo(100,0); + ctx.lineTo(120,0); + ctx.stroke(); + } + ctx.restore(); + + // Marquage des minutes + ctx.save(); + ctx.lineWidth = 5; + for (i=0;i<60;i++){ + if (i%5!=0) { + ctx.beginPath(); + ctx.moveTo(117,0); + ctx.lineTo(120,0); + ctx.stroke(); + } + ctx.rotate(Math.PI/30); + } + ctx.restore(); + + var sec = now.getSeconds(); + var min = now.getMinutes(); + var hr = now.getHours(); + hr = hr>=12 ? hr-12 : hr; + + ctx.fillStyle = "black"; + + // Aiguille des heures + ctx.save(); + ctx.rotate( hr*(Math.PI/6) + (Math.PI/360)*min + (Math.PI/21600)*sec ) + ctx.lineWidth = 14; + ctx.beginPath(); + ctx.moveTo(-20,0); + ctx.lineTo(80,0); + ctx.stroke(); + ctx.restore(); + + // Aiguille des minutes + ctx.save(); + ctx.rotate( (Math.PI/30)*min + (Math.PI/1800)*sec ) + ctx.lineWidth = 10; + ctx.beginPath(); + ctx.moveTo(-28,0); + ctx.lineTo(112,0); + ctx.stroke(); + ctx.restore(); + + // Aiguille des secondes + ctx.save(); + ctx.rotate(sec * Math.PI/30); + ctx.strokeStyle = "#D40000"; + ctx.fillStyle = "#D40000"; + ctx.lineWidth = 6; + ctx.beginPath(); + ctx.moveTo(-30,0); + ctx.lineTo(83,0); + ctx.stroke(); + ctx.beginPath(); + ctx.arc(0,0,10,0,Math.PI*2,true); + ctx.fill(); + ctx.beginPath(); + ctx.arc(95,0,10,0,Math.PI*2,true); + ctx.stroke(); + ctx.fillStyle = "rgba(0,0,0,0)"; + ctx.arc(0,0,3,0,Math.PI*2,true); + ctx.fill(); + ctx.restore(); + + ctx.beginPath(); + ctx.lineWidth = 14; + ctx.strokeStyle = '#325FA2'; + ctx.arc(0,0,142,0,Math.PI*2,true); + ctx.stroke(); + + ctx.restore(); + + window.requestAnimationFrame(clock); +} + +window.requestAnimationFrame(clock);</pre> + +<div class="hidden"> +<pre class="brush: html notranslate"><canvas id="canvas" width="150" height="150"></canvas></pre> +</div> + +<p>{{EmbedLiveSample("Une_horloge_animée", "180", "180", "https://mdn.mozillademos.org/files/203/Canvas_animation2.png")}}</p> + +<h2 id="Un_panorama_défilant_en_boucle">Un panorama défilant en boucle</h2> + +<p>Dans cet exemple, un panorama défile de la gauche vers la droite et recommence. Nous utilisons une <a href="http://commons.wikimedia.org/wiki/File:Capitan_Meadows,_Yosemite_National_Park.jpg" title="http://commons.wikimedia.org/wiki/File:Capitan_Meadows,_Yosemite_National_Park.jpg">image du parc Yosemite National</a> récupérée sur Wikimedia, vous pouvez utiliser une autre image de votre choix qui est plus grande que le canevas.</p> + +<pre class="brush: js notranslate">var img = new Image(); + +// Variables utilisateur - les personnaliser pour changer l'image qui défile, ses +// directions, et la vitesse. + +img.src = 'https://mdn.mozillademos.org/files/4553/Capitan_Meadows,_Yosemite_National_Park.jpg'; +var CanvasXSize = 800; +var CanvasYSize = 200; +var speed = 30; // plus elle est basse, plus c'est rapide +var scale = 1.05; +var y = -4.5; // décalage vertical + +// Programme principal + +var dx = 0.75; +var imgW; +var imgH; +var x = 0; +var clearX; +var clearY; +var ctx; + +img.onload = function() { + imgW = img.width * scale; + imgH = img.height * scale; + + if (imgW > CanvasXSize) { + // image plus grande que le canvas + x = CanvasXSize - imgW; + } + if (imgW > CanvasXSize) { + // largeur de l'image plus grande que le canvas + clearX = imgW; + } else { + clearX = CanvasXSize; + } + if (imgH > CanvasYSize) { + // hauteur de l'image plus grande que le canvas + clearY = imgH; + } else { + clearY = CanvasYSize; + } + + // récupérer le contexte du canvas + ctx = document.getElementById('canvas').getContext('2d'); + + // définir le taux de rafraichissement + return setInterval(draw, speed); +} + +function draw() { + ctx.clearRect(0, 0, clearX, clearY); // clear the canvas + + // si image est <= taille du canvas + if (imgW <= CanvasXSize) { + // réinitialise, repart du début + if (x > CanvasXSize) { + x = -imgW + x; + } + // dessine image1 supplémentaire + if (x > 0) { + ctx.drawImage(img, -imgW + x, y, imgW, imgH); + } + // dessine image2 supplémentaire + if (x - imgW > 0) { + ctx.drawImage(img, -imgW * 2 + x, y, imgW, imgH); + } + } + + // image est > taille du canvas + else { + // réinitialise, repeart du début + if (x > (CanvasXSize)) { + x = CanvasXSize - imgW; + } + // dessine image supplémentaire + if (x > (CanvasXSize-imgW)) { + ctx.drawImage(img, x - imgW + 1, y, imgW, imgH); + } + } + // dessine image + ctx.drawImage(img, x, y,imgW, imgH); + // quantité à déplacer + x += dx; +} +</pre> + +<p>En dessous, vous trouvez l'élément {{HTMLElement("canvas")}} avec l'image qui défile. Notez que les dimensions de largeur et de hauteur spécifiées doivent correspondre aux valeurs des variables <code>CanvasXZSize</code> et <code>CanvasYSize</code> dans le code JavaScript.</p> + +<pre class="brush: html notranslate"><canvas id="canvas" width="800" height="200"></canvas></pre> + +<p>{{EmbedLiveSample("Un_panorama_défilant_en_boucle", "830", "230")}}</p> + +<h2 id="Other_examples" name="Other_examples">Autres exemples</h2> + +<dl> + <dt><a href="https://developer.mozilla.org/fr/docs/Un_raycaster_basique_avec_canvas" title="/en-US/docs/Web/Guide/HTML/A_basic_ray-caster">Un raycaster basique avec canvas</a></dt> + <dd>Un bon exemple d'animation contrôlée par le clavier.</dd> + <dt><a href="https://developer.mozilla.org/fr/docs/Tutoriel_canvas/Advanced_animations">Animations avancées</a></dt> + <dd>Nous nous attarderons sur quelques techniques d'animation et de gestion de physique avancées dans le prochain châpitre.</dd> +</dl> + +<p>{{PreviousNext("Web/API/Canvas_API/Tutorial/Compositing", "Tutoriel_canvas/Advanced_animations")}}</p> diff --git a/files/fr/web/api/canvas_api/tutoriel_canvas/composition/example/index.html b/files/fr/web/api/canvas_api/tutoriel_canvas/composition/example/index.html new file mode 100644 index 0000000000..8fbb3ec79c --- /dev/null +++ b/files/fr/web/api/canvas_api/tutoriel_canvas/composition/example/index.html @@ -0,0 +1,295 @@ +--- +title: Exemple de composition +slug: Web/API/Canvas_API/Tutoriel_canvas/Composition/Example +tags: + - Canvas + - Exemple + - Graphisme + - HTML + - HTML5 + - Tutoriel +translation_of: Web/API/Canvas_API/Tutorial/Compositing/Example +--- +<div>{{CanvasSidebar}}</div> + +<p>Cet exemple illustre un certain nombre d'<a href="/fr/docs/Web/API/CanvasRenderingContext2D.globalCompositeOperation">opérations de composition</a>. Le résultat donne ceci:</p> + +<p>{{EmbedLiveSample("Exemple_de_composition", "100%", 7250)}}</p> + +<h2 id="Exemple_de_composition">Exemple de composition</h2> + +<p>Ce code configure les valeurs globales utilisées par le reste du programme.</p> + +<pre class="brush: js notranslate">var canvas1 = document.createElement("canvas"); +var canvas2 = document.createElement("canvas"); +var gco = [ 'source-over','source-in','source-out','source-atop', + 'destination-over','destination-in','destination-out','destination-atop', + 'lighter', 'copy','xor', 'multiply', 'screen', 'overlay', 'darken', + 'lighten', 'color-dodge', 'color-burn', 'hard-light', 'soft-light', + 'difference', 'exclusion', 'hue', 'saturation', 'color', 'luminosity' + ].reverse(); +var gcoText = [ +"C'est la configuration par défaut, elle dessine les nouvelles formes au-dessus du contenu existant sur le canvas.", +"La nouvelle forme est dessinée uniquement là où il y a déjà du contenu sur le canvas. Tout le reste est rendu transparent.", +"La nouvelle forme est dessinée uniquement là où il n'y a pas de contenu sur le canvas.", +"La nouvelle forme est dessinée uniquement là où il y a déjà du contenu sur le canvas. Elle s'ajoute au contenu existant.", +"Les nouvelles formes sont dessinées derrière le contenu existant du canvas.", +"Le contenu existant du canvas est conservé là où il chevauche la nouvelle forme. Tout le reste est rendu transparent.", +"Le contenu existant du canvas est conservé là où il ne chevauche pas la nouvelle forme.", +"Le contenu existant du canvas est conservé là où il chevauche la nouvelle forme. La nouvelle forme est dessinée derrière le contenu existant.", +"La nouvelle forme est ajoutée en additionnant ses couleurs à celles du contenu existant.", +"Seule la nouvelle forme est affichée.", +"Les formes sont rendues transparentes lorsqu'elles se chevauchent.", +"Les pixels de la nouvelle forme sont multipliés avec les pixels du contenu existant. Le résultat est une image plus sombre.", +"Les pixels sont inversés, multipliés, puis inversés de nouveau. Le résultat est une image plus claire (l'inverse de multiply)", +"Une combinaison de multiply et screen. Les parties sombres du contenu existant deviennent plus sombres, et les parties claires deviennent plus claires.", +"Retiens les pixels les plus sombres entre les deux.", +"Retiens les pixels les plus clairs entre les deux.", +"Divise le layer inférieur par le layer supérieur inversé.", +"Divise le layer inférieur inversé par le layer supérieur, puis inverse le résultat.", +"Une combinaison de multiply et screen (comme overlay), mais avec le layer supérieur et inférieur inversés.", +"Assombrit ou éclaircit les couleurs, en fonction de la couleur de la forme ajoutée.", +"Soustrait le layer inférieur au layer supérieur ou inversemment pour toujours obtenir une valeur positive.", +"Comme difference, mais avec un contraste moins élevé.", +"Préserve la luminance et saturation du layer inférieur, et utilise la teinte du layer supérieur.", +"Préserve la luminance et teinte du layer inférieur, et utilise la saturation du layer supérieur.", +"Préserve la luminance du layer inférieur, et utilise la teinte et saturation du layer supérieur.", +"Préserve la teinte et saturation du layer inférieur, et utilise la luminance du layer supérieur." +].reverse(); +var width = 320; +var height = 340; +</pre> + +<h3 id="Programme_principal">Programme principal</h3> + +<p>Quand la page se charge, le code suivant s'exécute pour configurer et exécuter l'exemple:</p> + +<pre class="brush: js notranslate">window.onload = function() { + // lum en sRGB + var lum = { + r: 0.33, + g: 0.33, + b: 0.33 + }; + // redimensionne le canvas + canvas1.width = width; + canvas1.height = height; + canvas2.width = width; + canvas2.height = height; + lightMix() + colorSphere(); + runComposite(); + return; +}; +</pre> + +<p>Et dans le code suivant, <code>runComposite()</code> gère la majeure partie du travail, en s'appuyant sur un certain nombre de fonctions utilitaires pour faire les parties difficiles.</p> + +<pre class="brush: js notranslate">function createCanvas() { + var canvas = document.createElement("canvas"); + canvas.style.background = "url("+op_8x8.data+")"; + canvas.style.border = "1px solid #000"; + canvas.style.margin = "5px"; + canvas.width = width/2; + canvas.height = height/2; + return canvas; +} + +function runComposite() { + var dl = document.createElement("dl"); + document.body.appendChild(dl); + while(gco.length) { + var pop = gco.pop(); + var dt = document.createElement("dt"); + dt.textContent = pop; + dl.appendChild(dt); + var dd = document.createElement("dd"); + var p = document.createElement("p"); + p.textContent = gcoText.pop(); + dd.appendChild(p); + + var canvasToDrawOn = createCanvas(); + var canvasToDrawFrom = createCanvas(); + var canvasToDrawResult = createCanvas(); + + var ctx = canvasToDrawResult.getContext('2d'); + ctx.clearRect(0, 0, width, height) + ctx.save(); + ctx.drawImage(canvas1, 0, 0, width/2, height/2); + ctx.globalCompositeOperation = pop; + ctx.drawImage(canvas2, 0, 0, width/2, height/2); + ctx.globalCompositeOperation = "source-over"; + ctx.fillStyle = "rgba(0,0,0,0.8)"; + ctx.fillRect(0, height/2 - 20, width/2, 20); + ctx.fillStyle = "#FFF"; + ctx.font = "14px arial"; + ctx.fillText(pop, 5, height/2 - 5); + ctx.restore(); + + var ctx = canvasToDrawOn.getContext('2d'); + ctx.clearRect(0, 0, width, height) + ctx.save(); + ctx.drawImage(canvas1, 0, 0, width/2, height/2); + ctx.fillStyle = "rgba(0,0,0,0.8)"; + ctx.fillRect(0, height/2 - 20, width/2, 20); + ctx.fillStyle = "#FFF"; + ctx.font = "14px arial"; + ctx.fillText('existing content', 5, height/2 - 5); + ctx.restore(); + + var ctx = canvasToDrawFrom.getContext('2d'); + ctx.clearRect(0, 0, width, height) + ctx.save(); + ctx.drawImage(canvas2, 0, 0, width/2, height/2); + ctx.fillStyle = "rgba(0,0,0,0.8)"; + ctx.fillRect(0, height/2 - 20, width/2, 20); + ctx.fillStyle = "#FFF"; + ctx.font = "14px arial"; + ctx.fillText('new content', 5, height/2 - 5); + ctx.restore(); + + dd.appendChild(canvasToDrawOn); + dd.appendChild(canvasToDrawFrom); + dd.appendChild(canvasToDrawResult); + + dl.appendChild(dd); + } +}; +</pre> + +<h3 id="Fonctions_utilitaires">Fonctions utilitaires</h3> + +<p>Notre programme repose sur un certain nombbre de fonctions utilitaires:</p> + +<pre class="brush: js notranslate">var lightMix = function() { + var ctx = canvas2.getContext("2d"); + ctx.save(); + ctx.globalCompositeOperation = "lighter"; + ctx.beginPath(); + ctx.fillStyle = "rgba(255,0,0,1)"; + ctx.arc(100, 200, 100, Math.PI*2, 0, false); + ctx.fill() + ctx.beginPath(); + ctx.fillStyle = "rgba(0,0,255,1)"; + ctx.arc(220, 200, 100, Math.PI*2, 0, false); + ctx.fill() + ctx.beginPath(); + ctx.fillStyle = "rgba(0,255,0,1)"; + ctx.arc(160, 100, 100, Math.PI*2, 0, false); + ctx.fill(); + ctx.restore(); + ctx.beginPath(); + ctx.fillStyle = "#f00"; + ctx.fillRect(0,0,30,30) + ctx.fill(); +}; +</pre> + +<pre class="brush: js notranslate">var colorSphere = function(element) { + var ctx = canvas1.getContext("2d"); + var width = 360; + var halfWidth = width / 2; + var rotate = (1 / 360) * Math.PI * 2; // per degree + var offset = 0; // scrollbar offset + var oleft = -20; + var otop = -20; + for (var n = 0; n <= 359; n ++) { + var gradient = ctx.createLinearGradient(oleft + halfWidth, otop, oleft + halfWidth, otop + halfWidth); + var color = Color.HSV_RGB({ H: (n + 300) % 360, S: 100, V: 100 }); + gradient.addColorStop(0, "rgba(0,0,0,0)"); + gradient.addColorStop(0.7, "rgba("+color.R+","+color.G+","+color.B+",1)"); + gradient.addColorStop(1, "rgba(255,255,255,1)"); + ctx.beginPath(); + ctx.moveTo(oleft + halfWidth, otop); + ctx.lineTo(oleft + halfWidth, otop + halfWidth); + ctx.lineTo(oleft + halfWidth + 6, otop); + ctx.fillStyle = gradient; + ctx.fill(); + ctx.translate(oleft + halfWidth, otop + halfWidth); + ctx.rotate(rotate); + ctx.translate(-(oleft + halfWidth), -(otop + halfWidth)); + } + ctx.beginPath(); + ctx.fillStyle = "#00f"; + ctx.fillRect(15,15,30,30) + ctx.fill(); + return ctx.canvas; +}; +</pre> + +<pre class="brush: js notranslate">// HSV (1978) = H: Hue / S: Saturation / V: Value +Color = {}; +Color.HSV_RGB = function (o) { + var H = o.H / 360, + S = o.S / 100, + V = o.V / 100, + R, G, B; + var A, B, C, D; + if (S == 0) { + R = G = B = Math.round(V * 255); + } else { + if (H >= 1) H = 0; + H = 6 * H; + D = H - Math.floor(H); + A = Math.round(255 * V * (1 - S)); + B = Math.round(255 * V * (1 - (S * D))); + C = Math.round(255 * V * (1 - (S * (1 - D)))); + V = Math.round(255 * V); + switch (Math.floor(H)) { + case 0: + R = V; + G = C; + B = A; + break; + case 1: + R = B; + G = V; + B = A; + break; + case 2: + R = A; + G = V; + B = C; + break; + case 3: + R = A; + G = B; + B = V; + break; + case 4: + R = C; + G = A; + B = V; + break; + case 5: + R = V; + G = A; + B = B; + break; + } + } + return { + R: R, + G: G, + B: B + }; +}; + +var createInterlace = function (size, color1, color2) { + var proto = document.createElement("canvas").getContext("2d"); + proto.canvas.width = size * 2; + proto.canvas.height = size * 2; + proto.fillStyle = color1; // top-left + proto.fillRect(0, 0, size, size); + proto.fillStyle = color2; // top-right + proto.fillRect(size, 0, size, size); + proto.fillStyle = color2; // bottom-left + proto.fillRect(0, size, size, size); + proto.fillStyle = color1; // bottom-right + proto.fillRect(size, size, size, size); + var pattern = proto.createPattern(proto.canvas, "repeat"); + pattern.data = proto.canvas.toDataURL(); + return pattern; +}; + +var op_8x8 = createInterlace(8, "#FFF", "#eee");</pre> diff --git a/files/fr/web/api/canvas_api/tutoriel_canvas/composition/index.html b/files/fr/web/api/canvas_api/tutoriel_canvas/composition/index.html new file mode 100644 index 0000000000..cc646762dd --- /dev/null +++ b/files/fr/web/api/canvas_api/tutoriel_canvas/composition/index.html @@ -0,0 +1,110 @@ +--- +title: Composition et découpe +slug: Web/API/Canvas_API/Tutoriel_canvas/Composition +tags: + - Canvas + - Composition + - dessin +translation_of: Web/API/Canvas_API/Tutorial/Compositing +--- +<div>{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Transformations", "Web/API/Canvas_API/Tutorial/Basic_animations")}}</div> + +<div class="summary"> +<p>Dans tous nos <a href="/en-US/docs/Web/API/Canvas_API/Tutorial/Transformations">exemples précédents</a>, les formes étaient toutes dessinées les unes au dessus des autres. C'est plus que suffisant pour la plupart des situations, mais cela limite l'ordre dans lequel les formes composées sont construites. Nous pouvons cependant changer ce comportement en définissant la propriété <code>globalCompositeOperation</code>. En complément, la propriété <code>clip</code> nous permet de cacher les parties des formes que nous ne désirons pas.</p> +</div> + +<h2 id="globalCompositeOperation" name="globalCompositeOperation"><code>globalCompositeOperation</code></h2> + +<p>Nous pouvons non seulement dessiner de nouvelles formes derrière des formes existantes mais nous pouvons aussi les utiliser pour masquer certaines zones, supprimer des sections du canvas (ce n'est pas limité aux rectangles comme pour la méthode {{domxref("CanvasRenderingContext2D.clearRect", "clearRect()")}}) et davantage.</p> + +<dl> + <dt>{{domxref("CanvasRenderingContext2D.globalCompositeOperation", "globalCompositeOperation = type")}}</dt> + <dd>Cela configure le type d'opération de composition à appliquer lorsqu'on dessine de nouvelles formes, où le type correspond à une string qui fait référence à une des douze opérations de composition possibles.</dd> +</dl> + +<p>Reportez-vous aux <a href="/fr/docs/Tutoriel_canvas/Composition/Example">exemples de compositon</a> pour le code des exemples suivants.</p> + +<p>{{EmbedLiveSample("Exemple_de_composition", 750, 6750, "" ,"/Tutoriel_canvas/Composition/Example")}}</p> + +<h2 id="Clipping_paths" name="Clipping_paths">Détourage</h2> + +<p><img alt="" class="internal" src="https://mdn.mozillademos.org/files/209/Canvas_clipping_path.png" style="float: right;">Un détourage (<em>clipping path</em> en anglais) est comme une forme de canvas standard, à la différence près qu'elle sert à masquer certaines parties du canvas. Voyez l'image de droite, la forme rouge (en étoile) est un détourage du canvas. Tout ce qui est en dehors du chemin n'est pas dessiné sur le canvas.</p> + +<p>Si nous comparons le détourage à la propriété <code>globalCompositeOperation</code> vue précédemment, nous voyons deux modes de composition qui ont plus ou moins les mémes effets qu'avec <code>source-in</code> et <code>source-atop</code>. La différence la plus significative entre les deux est que le détourage n'est jamais dessiné sur le canvas à proprement parler et il n'est jamais affecté par l'ajout de nouvelles formes. Ça le rend idéal pour dessiner plusieurs formes dans une zone restreinte.</p> + +<p>Dans le chapitre "<a href="/en-US/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes" title="Web/Guide/HTML/Canvas_tutorial/Drawing_shapes#Drawing_paths">dessiner des formes avec le canevas</a>", nous n'avions mentionné que les méthodes <code>stroke()</code> et <code>fill()</code>, mais il y en a une troisième: <code>clip()</code> — elle permet de faire des détourages.</p> + +<dl> + <dt>{{domxref("CanvasRenderingContext2D.clip", "clip()")}}</dt> + <dd>Transforme le chemin en cours de création en détourage effectif.</dd> +</dl> + +<p>Il faut utiliser <code>clip()</code> plutot que <code>closePath()</code> pour fermer un chemin et enfaire un détourage.</p> + +<p>Par défault, l'élément {{HTMLElement("canvas")}} possède un détourage aux mêmes dimensions que le canvas lui-même. Donc, par défaut aucune découpe n'est <span class="ht">apparente</span>.</p> + +<h3 id="A_clip_example" name="A_clip_example">Un exemple de <code>clip</code></h3> + +<p>Dans cet exemple, nous allons utiliser un détourage circulaire pour restreindre le dessin d'un essemble d'étoiles aléatoires à une zone particulière (et circulaire...).</p> + +<pre class="brush: js;highlight[9] notranslate">function draw() { + var ctx = document.getElementById('canvas').getContext('2d'); + ctx.fillRect(0, 0, 150, 150); + ctx.translate(75, 75); + + // Create a circular clipping path + ctx.beginPath(); + ctx.arc(0, 0, 60, 0, Math.PI * 2, true); + ctx.clip(); + + // draw background + var lingrad = ctx.createLinearGradient(0, -75, 0, 75); + lingrad.addColorStop(0, '#232256'); + lingrad.addColorStop(1, '#143778'); + + ctx.fillStyle = lingrad; + ctx.fillRect(-75, -75, 150, 150); + + // draw stars + for (var j = 1; j < 50; j++) { + ctx.save(); + ctx.fillStyle = '#fff'; + ctx.translate(75 - Math.floor(Math.random() * 150), + 75 - Math.floor(Math.random() * 150)); + drawStar(ctx, Math.floor(Math.random() * 4) + 2); + ctx.restore(); + } + +} + +function drawStar(ctx, r) { + ctx.save(); + ctx.beginPath(); + ctx.moveTo(r, 0); + for (var i = 0; i < 9; i++) { + ctx.rotate(Math.PI / 5); + if (i % 2 === 0) { + ctx.lineTo((r / 0.525731) * 0.200811, 0); + } else { + ctx.lineTo(r, 0); + } + } + ctx.closePath(); + ctx.fill(); + ctx.restore(); +} +</pre> + +<div class="hidden"> +<pre class="brush: html notranslate"><canvas id="canvas" width="150" height="150"></canvas></pre> + +<pre class="brush: js notranslate">draw();</pre> +</div> + +<p>Dans les premières lignes de code, nous dessinons un rectangle noir ayant la même taille que le canvas comme toile de fond puis nous déplaçons l'origine au centre de l'image. Ensuite, nous créons le détourage circulaire en dessinant un arc (complet) et en faisant appelle à <code>clip()</code>. Les détourages font aussi partie de l'état de sauvegarde des canvas. Si on voulait garder le détourage d'origine, on pourrait par exemple sauvegarder l'état du canvas au préalable.</p> + +<p>Tout ce qui sera dessiné après la création du détourage n'apparaîtra qu'à l'intérieur de ce chemin. Vous pouvez voir ça clairement avec le dégradé linéaire qui est dessiné après. Ensuite, un ensemble de 50 étoiles aléatoires est dessiné, en utilisant la fonction <code>drawStar()</code>. Nous pouvons voir, une fois de plus, que les éléments (ici les étoiles) n'apparaissent qu'à l'intérieur du détourage.</p> + +<p>{{EmbedLiveSample("A_clip_example", "180", "180", "https://mdn.mozillademos.org/files/208/Canvas_clip.png")}}</p> + +<p>{{PreviousNext("Web/API/Canvas_API/Tutorial/Transformations", "Web/API/Canvas_API/Tutorial/Basic_animations")}}</p> diff --git a/files/fr/web/api/canvas_api/tutoriel_canvas/dessin_de_texte_avec_canvas/index.html b/files/fr/web/api/canvas_api/tutoriel_canvas/dessin_de_texte_avec_canvas/index.html new file mode 100644 index 0000000000..761b5baf3d --- /dev/null +++ b/files/fr/web/api/canvas_api/tutoriel_canvas/dessin_de_texte_avec_canvas/index.html @@ -0,0 +1,161 @@ +--- +title: Dessin de texte avec canvas +slug: Web/API/Canvas_API/Tutoriel_canvas/Dessin_de_texte_avec_canvas +tags: + - Canvas + - Graphismes + - HTML + - Tutoriels +translation_of: Web/API/Canvas_API/Tutorial/Drawing_text +--- +<p>{{CanvasSidebar}} {{PreviousNext("Tutoriel_canvas/Ajout_de_styles_et_de_couleurs", "Tutoriel_canvas/Utilisation_d'images")}}</p> + +<p class="summary">Après avoir vu comment <a href="https://developer.mozilla.org/fr/docs/Tutoriel_canvas/Ajout_de_styles_et_de_couleurs">appliquer les styles et les couleurs</a> dans le chapitre précédent, nous allons maintenant voir comment dessiner du texte sur canvas.</p> + +<h2 id="Dessin_de_texte">Dessin de texte</h2> + +<p> Le contexte de rendu du canevas fournit deux méthodes pour le rendu du texte :</p> + +<dl> + <dt>{{domxref("CanvasRenderingContext2D.fillText", "fillText(text, x, y [, maxWidth])")}}</dt> + <dd>Remplit un texte donné à la position (x, y). Facultatif, avec une largeur maximale à dessiner.</dd> + <dt>{{domxref("CanvasRenderingContext2D.strokeText", "strokeText(text, x, y [, maxWidth])")}}</dt> + <dd>Trait d'un texte donné à la position (x, y). Facultatif, avec une largeur maximale à dessiner.</dd> +</dl> + +<h3 id="A_fillText_example" name="A_fillText_example">Un exemple fillText</h3> + +<p><span id="result_box" lang="fr"><span>Le texte est rempli en utilisant le <code>fillStyle</code> actuel.</span></span></p> + +<pre class="brush: js;highlight[4] line-numbers language-js notranslate"><code class="language-js"><span class="keyword token">function</span> <span class="function token">draw</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> ctx <span class="operator token">=</span> document<span class="punctuation token">.</span><span class="function token">getElementById</span><span class="punctuation token">(</span><span class="string token">'canvas'</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">getContext</span><span class="punctuation token">(</span><span class="string token">'2d'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span>font <span class="operator token">=</span> <span class="string token">'48px serif'</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">fillText</span><span class="punctuation token">(</span><span class="string token">'Hello world'</span><span class="punctuation token">,</span> <span class="number token">10</span><span class="punctuation token">,</span> <span class="number token">50</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="punctuation token">}</span></code></pre> + +<div class="hidden"> +<pre class="brush: html line-numbers language-html notranslate"><code class="language-html"><span class="tag token"><span class="tag token"><span class="punctuation token"><</span>canvas</span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>canvas<span class="punctuation token">"</span></span> <span class="attr-name token">width</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>300<span class="punctuation token">"</span></span> <span class="attr-name token">height</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>100<span class="punctuation token">"</span></span><span class="punctuation token">></span></span><span class="tag token"><span class="tag token"><span class="punctuation token"></</span>canvas</span><span class="punctuation token">></span></span></code></pre> + +<pre class="brush: js line-numbers language-js notranslate"><code class="language-js"><span class="function token">draw</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre> +</div> + +<p>{{EmbedLiveSample("A_fillText_example", 310, 110)}}</p> + +<h3 id="A_strokeText_example" name="A_strokeText_example">Un exemple de strokeText</h3> + +<p><span id="result_box" lang="fr"><span>Le texte est rempli en utilisant le </span></span> <code>strokeStyle</code><span lang="fr"><span> courant.</span></span></p> + +<pre class="brush: js;highlight[4] line-numbers language-js notranslate"><code class="language-js"><span class="keyword token">function</span> <span class="function token">draw</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> ctx <span class="operator token">=</span> document<span class="punctuation token">.</span><span class="function token">getElementById</span><span class="punctuation token">(</span><span class="string token">'canvas'</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">getContext</span><span class="punctuation token">(</span><span class="string token">'2d'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span>font <span class="operator token">=</span> <span class="string token">'48px serif'</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">strokeText</span><span class="punctuation token">(</span><span class="string token">'Hello world'</span><span class="punctuation token">,</span> <span class="number token">10</span><span class="punctuation token">,</span> <span class="number token">50</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="punctuation token">}</span></code></pre> + +<div class="hidden"> +<pre class="brush: html line-numbers language-html notranslate"><code class="language-html"><span class="tag token"><span class="tag token"><span class="punctuation token"><</span>canvas</span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>canvas<span class="punctuation token">"</span></span> <span class="attr-name token">width</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>300<span class="punctuation token">"</span></span> <span class="attr-name token">height</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>100<span class="punctuation token">"</span></span><span class="punctuation token">></span></span><span class="tag token"><span class="tag token"><span class="punctuation token"></</span>canvas</span><span class="punctuation token">></span></span></code></pre> + +<pre class="brush: js line-numbers language-js notranslate"><code class="language-js"><span class="function token">draw</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre> +</div> + +<p>{{EmbedLiveSample("A_strokeText_example", 310, 110)}}</p> + +<h2 id="M.C3.A9thodes" name="M.C3.A9thodes">Style de texte</h2> + +<p><span id="result_box" lang="fr"><span>Dans les exemples ci-dessus, nous utilisons déjà la propriété de police pour rendre le texte un peu plus grand que la taille par défaut.</span> <span>Il existe d'autres propriétés qui vous permettent d'ajuster la façon dont le texte est affiché sur le canevas :</span></span></p> + +<dl> + <dt>{{domxref("CanvasRenderingContext2D.font", "font = value")}}</dt> + <dd><span id="result_box" lang="fr"><span>Le style de texte actuel utilisé lors du dessin du texte.</span> <span>Cette chaîne utilise la même syntaxe que la propriété CSS {{cssxref ("font")}}.</span> <span>La police par défaut est 10px sans-serif.</span></span></dd> + <dt>{{domxref("CanvasRenderingContext2D.textAlign", "textAlign = value")}}</dt> + <dd><span id="result_box" lang="fr"><span>Paramètre d'alignement du texte.</span> <span>Valeurs possibles : </span></span> <code>start</code> <em>(</em><span lang="fr"><span><em>début)</em>, </span></span> <code>end</code> <em>(</em><span lang="fr"><span><em>fin)</em>, </span></span> <code>left</code> <em>(</em><span lang="fr"><span><em>gauche)</em>, </span></span> <code>right</code> <em>(</em><span lang="fr"><span><em>droite)</em> ou </span></span> <code>center</code> <em>(</em><span lang="fr"><span><em>centre)</em>.</span> <span>La valeur par défaut est <code>start</code>.</span></span></dd> + <dt>{{domxref("CanvasRenderingContext2D.textBaseline", "textBaseline = value")}}</dt> + <dd><span id="result_box" lang="fr"><span>Paramètre d'alignement de base.</span> <span>Valeurs possibles : </span></span> <code>top</code> <em>(</em><span lang="fr"><span><em>haut)</em>, </span></span> <code>hanging</code> <em>(</em><span lang="fr"><span><em>suspendu)</em>, </span></span> <code>middle</code> <em>(</em><span lang="fr"><span><em>moyen)</em>, </span></span> <code>alphabetic</code> <em>(</em><span lang="fr"><span><em>alphabétique)</em>, </span></span> <code>ideographic</code> <em>(</em><span lang="fr"><span><em>idéographique)</em>, </span></span> <code>bottom</code> <em>(</em><span lang="fr"><span><em>en bas)</em>.</span> <span>La valeur par défaut est </span></span><code>alphabetic</code><span lang="fr"><span>.</span></span></dd> + <dt>{{domxref("CanvasRenderingContext2D.direction", "direction = value")}}</dt> + <dd><span id="result_box" lang="fr"><span>Directionnalité.</span> <span>Valeurs possibles: </span></span> <code>ltr</code> <em>(de gauche à droite)</em><span lang="fr"><span>, </span></span> <code>rtl</code> <em>(de droite à gauche)</em><span lang="fr"><span>, <code>inherit</code> <em>(hérité)</em>.</span> <span>La valeur par défaut est <code>inherit</code>.</span></span></dd> +</dl> + +<p><span id="result_box" lang="fr"><span>Ces propriétés peuvent vous être familières si vous avez déjà travaillé avec CSS.</span></span></p> + +<p><span id="result_box" lang="fr"><span>Le diagramme suivant du </span></span> <a class="external external-icon" href="http://www.whatwg.org/" title="http://www.whatwg.org/">WHATWG</a> <span lang="fr"><span> illustre les différentes lignes de base prises en charge par la propriété <code>textBaseline.</code></span></span></p> + +<p><img alt="The top of the em square is +roughly at the top of the glyphs in a font, the hanging baseline is +where some glyphs like आ are anchored, the middle is half-way +between the top of the em square and the bottom of the em square, +the alphabetic baseline is where characters like Á, ÿ, +f, and Ω are anchored, the ideographic baseline is +where glyphs like 私 and 達 are anchored, and the bottom +of the em square is roughly at the bottom of the glyphs in a +font. The top and bottom of the bounding box can be far from these +baselines, due to glyphs extending far outside the em square." src="http://www.whatwg.org/specs/web-apps/current-work/images/baselines.png"></p> + +<h3 id="Un_exemple_de_textBaseline">Un exemple de textBaseline</h3> + +<p><span id="result_box" lang="fr"><span>Modifiez le code ci-dessous et visualisez vos mises à jour en direct dans le canevas :</span></span></p> + +<pre class="brush: js;highlight[2] line-numbers language-js notranslate"><code class="language-js">ctx<span class="punctuation token">.</span>font <span class="operator token">=</span> <span class="string token">'48px serif'</span><span class="punctuation token">;</span> +ctx<span class="punctuation token">.</span>textBaseline <span class="operator token">=</span> <span class="string token">'hanging'</span><span class="punctuation token">;</span> +ctx<span class="punctuation token">.</span><span class="function token">strokeText</span><span class="punctuation token">(</span><span class="string token">'Hello world'</span><span class="punctuation token">,</span> <span class="number token">0</span><span class="punctuation token">,</span> <span class="number token">100</span><span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre> + +<div class="hidden"> +<h6 id="Playable_code" name="Playable_code">Playable code</h6> + +<pre class="brush: html line-numbers language-html notranslate"><code class="language-html"><span class="tag token"><span class="tag token"><span class="punctuation token"><</span>canvas</span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>canvas<span class="punctuation token">"</span></span> <span class="attr-name token">width</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>400<span class="punctuation token">"</span></span> <span class="attr-name token">height</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>200<span class="punctuation token">"</span></span> <span class="attr-name token">class</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>playable-canvas<span class="punctuation token">"</span></span><span class="punctuation token">></span></span><span class="tag token"><span class="tag token"><span class="punctuation token"></</span>canvas</span><span class="punctuation token">></span></span> +<span class="tag token"><span class="tag token"><span class="punctuation token"><</span>div</span> <span class="attr-name token">class</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>playable-buttons<span class="punctuation token">"</span></span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>input</span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>edit<span class="punctuation token">"</span></span> <span class="attr-name token">type</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>button<span class="punctuation token">"</span></span> <span class="attr-name token">value</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>Edit<span class="punctuation token">"</span></span> <span class="punctuation token">/></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>input</span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>reset<span class="punctuation token">"</span></span> <span class="attr-name token">type</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>button<span class="punctuation token">"</span></span> <span class="attr-name token">value</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>Reset<span class="punctuation token">"</span></span> <span class="punctuation token">/></span></span> +<span class="tag token"><span class="tag token"><span class="punctuation token"></</span>div</span><span class="punctuation token">></span></span> +<span class="tag token"><span class="tag token"><span class="punctuation token"><</span>textarea</span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>code<span class="punctuation token">"</span></span> <span class="attr-name token">class</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>playable-code<span class="punctuation token">"</span></span><span class="punctuation token">></span></span> +ctx.font = "48px serif"; +ctx.textBaseline = "hanging"; +ctx.strokeText("Hello world", 0, 100);<span class="tag token"><span class="tag token"><span class="punctuation token"></</span>textarea</span><span class="punctuation token">></span></span></code></pre> + +<pre class="brush: js line-numbers language-js notranslate"><code class="language-js"><span class="keyword token">var</span> canvas <span class="operator token">=</span> document<span class="punctuation token">.</span><span class="function token">getElementById</span><span class="punctuation token">(</span><span class="string token">'canvas'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="keyword token">var</span> ctx <span class="operator token">=</span> canvas<span class="punctuation token">.</span><span class="function token">getContext</span><span class="punctuation token">(</span><span class="string token">'2d'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="keyword token">var</span> textarea <span class="operator token">=</span> document<span class="punctuation token">.</span><span class="function token">getElementById</span><span class="punctuation token">(</span><span class="string token">'code'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="keyword token">var</span> reset <span class="operator token">=</span> document<span class="punctuation token">.</span><span class="function token">getElementById</span><span class="punctuation token">(</span><span class="string token">'reset'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="keyword token">var</span> edit <span class="operator token">=</span> document<span class="punctuation token">.</span><span class="function token">getElementById</span><span class="punctuation token">(</span><span class="string token">'edit'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="keyword token">var</span> code <span class="operator token">=</span> textarea<span class="punctuation token">.</span>value<span class="punctuation token">;</span> + +<span class="keyword token">function</span> <span class="function token">drawCanvas</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + ctx<span class="punctuation token">.</span><span class="function token">clearRect</span><span class="punctuation token">(</span><span class="number token">0</span><span class="punctuation token">,</span> <span class="number token">0</span><span class="punctuation token">,</span> canvas<span class="punctuation token">.</span>width<span class="punctuation token">,</span> canvas<span class="punctuation token">.</span>height<span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="function token">eval</span><span class="punctuation token">(</span>textarea<span class="punctuation token">.</span>value<span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="punctuation token">}</span> + +reset<span class="punctuation token">.</span><span class="function token">addEventListener</span><span class="punctuation token">(</span><span class="string token">'click'</span><span class="punctuation token">,</span> <span class="keyword token">function</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + textarea<span class="punctuation token">.</span>value <span class="operator token">=</span> code<span class="punctuation token">;</span> + <span class="function token">drawCanvas</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="punctuation token">}</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + +edit<span class="punctuation token">.</span><span class="function token">addEventListener</span><span class="punctuation token">(</span><span class="string token">'click'</span><span class="punctuation token">,</span> <span class="keyword token">function</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + textarea<span class="punctuation token">.</span><span class="function token">focus</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="punctuation token">}</span><span class="punctuation token">)</span> + +textarea<span class="punctuation token">.</span><span class="function token">addEventListener</span><span class="punctuation token">(</span><span class="string token">'input'</span><span class="punctuation token">,</span> drawCanvas<span class="punctuation token">)</span><span class="punctuation token">;</span> +window<span class="punctuation token">.</span><span class="function token">addEventListener</span><span class="punctuation token">(</span><span class="string token">'load'</span><span class="punctuation token">,</span> drawCanvas<span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre> +</div> + +<p>{{ EmbedLiveSample('Playable_code', 700, 360) }}</p> + +<h2 id="Mesures_de_texte_avancées"><span class="short_text" id="result_box" lang="fr"><span>Mesures de texte avancées</span></span></h2> + +<p><span id="result_box" lang="fr"><span>Dans le cas où vous avez besoin d'obtenir plus de détails sur le texte, la méthode suivante vous permet de le mesurer.</span></span></p> + +<dl> + <dt>{{domxref("CanvasRenderingContext2D.measureText", "measureText()")}}</dt> + <dd><span id="result_box" lang="fr"><span>Retourne un objet </span></span> {{domxref("TextMetrics")}} <span lang="fr"><span> contenant la largeur en pixels, sur la base duquel le texte spécifié sera dessiné dans le style de texte actuel.</span></span></dd> +</dl> + +<p><span id="result_box" lang="fr"><span>L'extrait de code suivant montre comment vous pouvez mesurer un texte et obtenir sa largeur.</span></span></p> + +<pre class="brush: js;highlight[3] line-numbers language-js notranslate"><code class="language-js"><span class="keyword token">function</span> <span class="function token">draw</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> ctx <span class="operator token">=</span> document<span class="punctuation token">.</span><span class="function token">getElementById</span><span class="punctuation token">(</span><span class="string token">'canvas'</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">getContext</span><span class="punctuation token">(</span><span class="string token">'2d'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">var</span> text <span class="operator token">=</span> ctx<span class="punctuation token">.</span><span class="function token">measureText</span><span class="punctuation token">(</span><span class="string token">'foo'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// objet TextMetrics</span> + text<span class="punctuation token">.</span>width<span class="punctuation token">;</span> <span class="comment token">// 16;</span> +<span class="punctuation token">}</span></code></pre> + +<h2 id="Notes_spécifiques_à_Gecko"><span class="short_text" id="result_box" lang="fr"><span>Notes spécifiques à Gecko</span></span></h2> + +<p><span id="result_box" lang="fr"><span>Dans Gecko (le moteur de rendu de Firefox, Firefox OS et d'autres applications basées sur Mozilla), certaines API préfixées ont été implémentées dans des versions antérieures pour dessiner du texte sur un canevas.</span> <span>Ceux-ci sont maintenant déconseillés et supprimés, et leur fonctionnement n'est pas garanti.</span></span></p> + +<p>{{PreviousNext("Tutoriel_canvas/Ajout_de_styles_et_de_couleurs", "Tutoriel_canvas/Utilisation_d'images")}}</p> diff --git a/files/fr/web/api/canvas_api/tutoriel_canvas/formes_géométriques/index.html b/files/fr/web/api/canvas_api/tutoriel_canvas/formes_géométriques/index.html new file mode 100644 index 0000000000..233d1baeb2 --- /dev/null +++ b/files/fr/web/api/canvas_api/tutoriel_canvas/formes_géométriques/index.html @@ -0,0 +1,581 @@ +--- +title: Dessiner des formes avec le canevas +slug: Web/API/Canvas_API/Tutoriel_canvas/Formes_géométriques +tags: + - Canvas + - Graphisme + - Guide + - HTML + - HTML5 + - Intermédiaire + - Tutoriel +translation_of: Web/API/Canvas_API/Tutorial/Drawing_shapes +--- +<p>{{CanvasSidebar}} {{PreviousNext("Tutoriel_canvas/Utilisation_de_base", "Tutoriel_canvas/Ajout_de_styles_et_de_couleurs")}}</p> + +<p class="summary">Maintenant que nous avons défini notre <a href="https://developer.mozilla.org/fr/docs/Tutoriel_canvas/Utilisation_de_base">environnement de canevas</a>, nous pouvons entrer dans les détails de la façon de dessiner sur le canevas. A la fin de cet article, vous aurez appris à tracer des rectangles, des triangles, des lignes, des arcs et des courbes, vous rendant ainsi familier avec certaines des formes de base. Le travail avec les trajets est essentiel lors du dessin d'objets sur le canevas, et nous verrons comment cela peut être fait.</p> + +<h2 id="La_grille">La grille</h2> + +<p><img alt="" class="internal" src="https://mdn.mozillademos.org/files/224/Canvas_default_grid.png" style="float: right; height: 220px; width: 220px;">Avant de pouvoir commencer à dessiner, il nous faut parler de la grille ou <strong>système de coordonnées</strong>. Notre schéma HTML de la page précédente avait un élément canevas large de 150 pixels et haut de 150 pixels. À droite, vous voyez ce canevas avec la grille par défaut superposée. Normalement, 1 unité dans la grille correspond à 1 pixel sur le canevas. L'origine de cette grille est positionnée dans le coin <em>supérieur gauche</em> de coordonnées (0, 0). Tous les éléments sont placés relativement à cette origine. Ainsi, le coin supérieur gauche du carré bleu est à <code>x</code> pixels à partir de la gauche et à <code>y</code> pixels à partir du haut, aux coordonnées (x, y). Plus loin dans ce tutoriel, nous verrons comment déplacer l'origine à une position différente, faire pivoter la grille ou même la mettre à l'échelle ; mais pour l'instant, nous nous en tiendrons aux valeurs par défaut.</p> + +<h2 id="Dessin_de_rectangles">Dessin de rectangles</h2> + +<p>Au contraire de <a href="/fr/docs/Web/SVG" rel="internal" title="en/SVG">SVG</a>, le {{HTMLElement("canvas")}} ne supporte qu'une seule forme primitive : le rectangle. Toute autre forme doit être créée en combinant un ou plusieurs trajets, c'est-à-dire des listes de points reliés par des lignes. Heureusement, nous avons un assortiment de fonctions de dessin de trajets, qui rendent possible la composition de formes très complexes.</p> + +<div id="section_3"> +<p>Commençons par le rectangle. Il y a trois fonctions qui dessinent des rectangles sur le canvas :</p> + +<dl> + <dt>{{domxref("CanvasRenderingContext2D.fillRect", "fillRect(x, y, largeur, hauteur)")}}</dt> + <dd>Dessine un rectangle rempli.</dd> + <dt>{{domxref("CanvasRenderingContext2D.strokeRect", "strokeRect(x, y, largeur, hauteur)")}}</dt> + <dd>Dessine un contour rectangulaire</dd> + <dt>{{domxref("CanvasRenderingContext2D.clearRect", "clearRect(x, y, largeur, hauteur)")}}</dt> + <dd>Efface la zone rectangulaire spécifiée, la rendant complètement transparente.</dd> +</dl> + +<p>Chacune de ces trois fonctions a les mêmes paramètres. <code>x</code> et <code>y</code> indiquent la position sur le canevas (par rapport à l'origine) du coin supérieur gauche du rectangle sur le canvas. <code>largeur</code> et <code>hauteur</code> indiquent la taille du rectangle.</p> + +<p>Ci-dessous la fonction <code>draw()</code> de la page précédente, mais utilisant maintenant ces trois fonctions.</p> + +<h3 id="Exemple_de_forme_rectangulaire">Exemple de forme rectangulaire</h3> + +<div class="hidden"> +<pre class="brush: html notranslate"><html> + <body onload="draw();"> + <canvas id="canvas" width="150" height="150"></canvas> + </body> +</html> +</pre> +</div> + +<pre class="brush: js notranslate">function draw() { + var canvas = document.getElementById('canvas'); + if (canvas.getContext) { + var ctx = canvas.getContext('2d'); + + ctx.fillRect(25, 25, 100, 100); + ctx.clearRect(45, 45, 60, 60); + ctx.strokeRect(50, 50, 50, 50); + } +}</pre> + +<p>Le résultat de cet exemple est montré ci-dessous.</p> + +<p>{{EmbedLiveSample("Exemple_de_forme_rectangulaire", 160, 160, "https://mdn.mozillademos.org/files/245/Canvas_rect.png")}}</p> + +<p>La fonction <code>fillRect()</code> dessine un grand carré noir de 100 pixels de côté. La fonction <code>clearRect()</code> efface ensuite un carré de 60x60 pixels, et finalement, la fonction <code>strokeRect()</code> est appelée pour créer un contour rectangulaire de 50x50 pixels dans l'espace effacé.</p> + +<p>Dans les pages qui suivent, nous verrons deux méthodes alternatives pour <code>clearRect()</code>, et nous verrons aussi comment changer la couleur et le style de trait des formes rendues.</p> + +<p>A la différence des fonctions de trajet que nous allons voir dans la prochaine section, les trois fonctions de rectangles dessinent immédiatement sur le canvas.</p> + +<h2 id="Dessin_de_trajets">Dessin de trajets</h2> + +<p>Les seules autres formes primitives sont les <em>trajets</em>. Un trajet est une liste de points, reliés par des segments de lignes qui peuvent être de différentes formes, incurvées ou non, de largeur différente et de couleur différente. Un trajet, ou même un sous-trajet, peut être fermé. La réalisation de formes utilisant des trajets requiert quelques étapes supplémentaires :</p> + +<ol> + <li>Tout d'abord, vous devez créer le trajet.</li> + <li>Ensuite vous devez utiliser des <a href="https://developer.mozilla.org/fr-FR/docs/Web/API/CanvasRenderingContext2D#Paths">instructions de dessin</a> pour dessiner sur le trajet.</li> + <li>Finalement, vous devez fermer le trajet.</li> + <li>Une fois que le trajet a été créé, vous devez le tracer ou le remplir pour le faire apparaître.</li> +</ol> + +<p>Voici les functions utilisées pour réaliser ces étapes :</p> + +<dl> + <dt>{{domxref("CanvasRenderingContext2D.beginPath", "beginPath()")}}</dt> + <dd>Crée un nouveau trajet. Une fois créé, les fonctions de dessin ultérieures seront dirigées vers le trajet et utilisées pour le construire.</dd> + <dt><a href="https://developer.mozilla.org/fr-FR/docs/Web/API/CanvasRenderingContext2D#Paths">Méthodes de trajet</a></dt> + <dd>Méthodes pour définir différents trajets pour les objets.</dd> + <dt>{{domxref("CanvasRenderingContext2D.closePath", "closePath()")}}</dt> + <dd>Ferme le trajet pour que les fonctions de dessin ultérieures soient à nouveau dirigées vers le contexte.</dd> + <dt>{{domxref("CanvasRenderingContext2D.stroke", "stroke()")}}</dt> + <dd>Dessine la forme en traçant son contour.</dd> + <dt>{{domxref("CanvasRenderingContext2D.fill", "fill()")}}</dt> + <dd>Dessine une forme pleine en remplissant la zone de contenu du trajet.</dd> +</dl> + +<p>La première étape pour créer un trajet est d'appeler <code>beginPath()</code>. En interne, les trajets sont stockés comme une liste de sous-trajets (lignes, arcs, etc) qui ensemble réalisent une forme. Chaque fois que cette méthode est appelée, la liste est remise à zéro, et nous pouvons commencer à dessiner de nouvelles formes.</p> + +<div class="note"><strong>Note :</strong> lorsque le trajet en cours est vide, par exemple immédiatement après avoir appelé <code>beginPath()</code>, ou sur un canvas nouvellement créé, la première instruction de construction de trajet est toujours traitée comme un <code>moveTo()</code>, indépendamment de ce qu'elle est en réalité. Pour cette raison, il sera pratiquement toujours souhaitable d'indiquer la position de départ après la réinitialisation d'un trajet.</div> + +<p>La deuxième étape est d'appeler les méthodes qui indiquent effectivement les sous-trajets à dessiner. Nous verrons ces méthodes bientôt.</p> + +<p>La troisième méthode, optionnelle, est l'appel à <code>closePath()</code>. Cette méthode essaye de fermer la forme géométrique en dessinant une ligne droite depuis le point courant jusqu'au début du trajet. Si la forme a déjà été fermée ou s'il n'y a qu'un seul point dans la liste, cette fonction ne fait rien.</p> + +<div class="note"><strong>Note :</strong> quand vous appelez <code>fill()</code>, toutes les formes ouvertes sont automatiquement fermées, ainsi vous n'avez pas à appeler <code>closePath()</code>. Ce n'est <strong>pas</strong> le cas quand vous appelez <code>stroke()</code>.</div> + +<h3 id="Dessin_dun_triangle">Dessin d'un triangle</h3> + +<p>Par exemple, le code pour dessiner un triangle peut ressembler à ce qui suit :</p> + +<div class="hidden"> +<pre class="brush: html notranslate"><html> + <body onload="dessiner();"> + <canvas id="canevas" width="150" height="150"></canvas> + </body> +</html> +</pre> +</div> + +<pre class="brush: js notranslate">function dessiner() { + var canevas = document.getElementById('canevas'); + if (canevas.getContext) { + var ctx = canevas.getContext('2d'); + + ctx.beginPath(); + ctx.moveTo(75, 50); + ctx.lineTo(100, 75); + ctx.lineTo(100, 25); + ctx.fill(); + } +} +</pre> + +<p>Le résultat ressemble à :</p> + +<p>{{EmbedLiveSample("Dessin_d'un_triangle", 110, 110, "https://mdn.mozillademos.org/files/9847/triangle.png")}}</p> + +<h3 id="Déplacement_du_stylo">Déplacement du stylo</h3> + +<p>Une fonction très utile, qui ne dessine rien mais qui fait tout de même partie de la liste de trajets décrite plus haut, est la fonction <code>moveTo()</code>. La meilleure façon de l'imaginer est le fait de lever un stylo ou un crayon depuis une position sur un papier, et de le placer sur une autre.</p> + +<dl> + <dt>{{domxref("CanvasRenderingContext2D.moveTo", "moveTo(x, y)")}}</dt> + <dd>Déplace le stylo aux coordonnées <code>x</code> et <code>y</code>.</dd> +</dl> + +<p>Lorsque le canevas est initialisé ou que <code>beginPath()</code> est appelé, vous souhaiterez typiquement utiliser <code>moveTo()</code> pour positionner le point de départ quelque part ailleurs. On pourrait aussi utiliser <code>moveTo()</code> pour dessiner des trajets non reliés. Jetez un coup d'œil à l'émoticon ci-dessous.</p> + +<p>Pour essayer par vous-même, vous pouvez utiliser le fragment de code ci-dessous. Collez-le simplement dans la fonction <code>draw()</code> que nous avons vue plus tôt.</p> + +<div class="hidden"> +<pre class="brush: html notranslate"><html> + <body onload="draw();"> + <canvas id="canvas" width="150" height="150"></canvas> + </body> +</html> +</pre> +</div> + +<pre class="brush: js notranslate">function draw() { + var canvas = document.getElementById('canvas'); + if (canvas.getContext) { + var ctx = canvas.getContext('2d'); + + ctx.beginPath(); + ctx.arc(75, 75, 50, 0, Math.PI * 2, true); // Cercle extérieur + ctx.moveTo(110,75); + ctx.arc(75, 75, 35, 0, Math.PI, false); // Bouche (sens horaire) + ctx.moveTo(65, 65); + ctx.arc(60, 65, 5, 0, Math.PI * 2, true); // Oeil gauche + ctx.moveTo(95, 65); + ctx.arc(90, 65, 5, 0, Math.PI * 2, true); // Oeil droite + ctx.stroke(); + } +} +</pre> + +<p>Le résultat ressemble à ce qui suit :</p> + +<p>{{EmbedLiveSample("Déplacement_du_stylo", 160, 160, "https://mdn.mozillademos.org/files/252/Canvas_smiley.png")}}</p> + +<p>Si vous voulez voir les lignes d'interconnexion, vous pouvez enlever les lignes qui appellent <code>moveTo()</code>.</p> + +<div class="note"> +<p><strong>Note :</strong> pour en savoir plus sur la fonction <code>arc()</code>, voir la section {{anch("Arcs")}} ci-dessous.</p> +</div> + +<h3 id="Les_lignes">Les lignes</h3> + +<p>Pour dessiner des lignes droites, utilisez la méthode <code>lineTo()</code>.</p> + +<dl> + <dt>{{domxref("CanvasRenderingContext2D.lineTo", "lineTo(x, y)")}}</dt> + <dd>Dessine une ligne depuis la position de dessin courante jusqu'à la position spécifiée par <code>x</code> et <code>y</code>.</dd> +</dl> + +<p>Cette méthode prend deux arguments, <code>x</code> et <code>y</code>, qui sont les coordonnées du point final de la ligne. Le point de départ dépend des trajets précédemment tracés, où le point final du trajet précédent est le point de départ du suivant, etc. Le point de départ peut aussi être changé en utilisant la méthode <code>moveTo()</code>.</p> + +<p>L'exemple ci-dessous dessine deux triangles, un rempli et un filaire.</p> + +<div class="hidden"> +<pre class="brush: html notranslate"><html> + <body onload="dessiner();"> + <canvas id="canevas" width="150" height="150"></canvas> + </body> +</html> +</pre> +</div> + +<pre class="brush: js notranslate">function dessiner() { + var canevas = document.getElementById('canevas'); + if (canevas.getContext) { + var ctx = canevas.getContext('2d'); + + // Triangle plein + ctx.beginPath(); + ctx.moveTo(25, 25); + ctx.lineTo(105, 25); + ctx.lineTo(25, 105); + ctx.fill(); + + // Triangle filaire + ctx.beginPath(); + ctx.moveTo(125, 125); + ctx.lineTo(125, 45); + ctx.lineTo(45, 125); + ctx.closePath(); + ctx.stroke(); + } +} +</pre> + +<p>Il commence par appeler <code>beginPath()</code> pour démarrer un nouveau trajet de forme. Nous utilisons ensuite la méthode <code>moveTo()</code> pour déplacer le point de départ à la position désirée. En dessous, deux lignes sont dessinées, qui constituent deux côtés du triangle.</p> + +<p>{{EmbedLiveSample("Les_lignes", 160, 160, "https://mdn.mozillademos.org/files/238/Canvas_lineTo.png")}}</p> + +<p>Vous remarquerez la différence entre le triangle plein et le filaire. Cela, comme mentionné précédemment, vient du fait que les formes sont automatiquement fermées lorsqu'un trajet est rempli, mais pas lorsqu'elles sont dessinées au trait. Si nous avions omis le <code>closePath()</code> pour le triangle filaire, seules deux lignes auraient été tracées, et non pas un triangle complet.</p> + +<h3 id="Les_arcs">Les arcs</h3> + +<p>Pour dessiner des arcs ou des cercles, on utilise les méthodes <code>arc() ou arcTo()</code>.</p> + +<dl> + <dt>{{domxref("CanvasRenderingContext2D.arc", "arc(x, y, rayon, angleInitial, angleFinal, antihoraire)")}}</dt> + <dd>Dessine un arc de cercle qui est centré à la position <em>(x, y),</em> de rayon <em>r</em>, commençant à <em>angleInitial</em> et finissant à <em>angleFinal</em> en allant dans le sens indiqué par <em>antihoraire</em> (par défaut, horaire).</dd> + <dt><strong>{{domxref("CanvasRenderingContext2D.arcTo", "arcTo(x1, y1, x2, y2, rayon)")}}</strong></dt> + <dd>Dessine un arc avec les points de contrôle et l'angle donnés, relié au point précédent par une ligne droite.</dd> +</dl> + +<p>Regardons plus en détail la méthode <code>arc</code>, qui prend six paramètres : <code>x</code> et <code>y</code> sont les coordonnées du centre du cercle sur lequel l'arc doit être tracé. <code>rayon</code> se passe d'explication. Les paramètres <code>angleInitial et</code> <code>angleFinal</code> définissent en radians les points de départ et d'arrivée de l'arc, le long de la courbe du cercle. Ceux-ci sont mesurés à partir de l'axe des x. Le paramètre <code>antihoraire</code> est une valeur booléenne qui, lorsque <code>true</code>, dessine l'arc dans le sens antihoraire, sinon, l'arc est dessiné dans le sens horaire.</p> + +<div class="note"> +<p><strong>Note </strong>: les angles dans la fonction <code>arc</code> sont mesurés en radians, et non en degrés. Pour convertir des degrés en radians, vous pouvez utiliser l'expression JavaScript suivante : <code>radians = (Math.PI/180)*degres</code>.</p> +</div> + +<p>L'exemple suivant est un peu plus complexe que ceux que nous avons vus plus haut. Il dessine 12 arcs différents, avec des angles et des remplissages différents.</p> + +<p>Les deux <a href="https://developer.mozilla.org/fr-FR/docs/Web/JavaScript/Reference/Statements/for">boucles <code>for</code></a> bouclent sur les lignes et les colonnes des arcs. Pour chaque arc, on commence un nouveau trajet en appelant <code>beginPath()</code>. Dans le code, chacun des paramètres dans l'arc est une variable pour des raisons de clarté, mais en réalité, vous n'avez pas besoin de le faire.</p> + +<p>Les coordonnées <code>x</code> et <code>y</code> devraient être claires. <code>rayon</code> et <code>angleInitial</code> sont fixés. L'<code>angleFinal</code> commence à 180 degrés (demi-cercle) dans la première colonne et il est augmenté par pas de 90 degrés, pour finir par un cercle complet dans la dernière colonne.</p> + +<p>L'instruction pour le paramètre <code>antihoraire</code> a pour résultat que la première et de la troisième ligne sont dessinées comme des arcs de sens horaire, et que la deuxième et quatrième sont dessinées comme des arcs de sens antihoraire. Enfin, l'instruction <code>if</code> fait des arcs filaires dans la moité supérieure, et des arcs remplis dans la moitié inférieure.</p> + +<div class="note"> +<p><strong>Note :</strong> cet exemple requiert canevas légèrement plus large que les autres sur cette page : 150 x 200 pixels.</p> +</div> + +<div class="hidden"> +<pre class="brush: html notranslate"><html> + <body onload="dessiner();"> + <canvas id="canevas" width="150" height="200"></canvas> + </body> +</html> +</pre> +</div> + +<pre class="brush: js notranslate">function dessiner() { + var canevas = document.getElementById('canevas'); + if (canevas.getContext) { + var ctx = canevas.getContext('2d'); + + for(var i = 0; i < 4; i++) { + for(var j = 0; j < 3; j++) { + ctx.beginPath(); + var x = 25 + j * 50; // Coordonnée x + var y = 25 + i * 50; // Coordonnée y + var rayon = 20; // Rayon de l'arc + var angleInitial = 0; // Point de départ sur le cercle + var angleFinal = Math.PI + (Math.PI * j) / 2; // Point d'arrivée sur le cercle + var antihoraire = i % 2 != 0; // Horaire ou antihoraire + + ctx.arc(x, y, rayon, angleInitial, angleFinal, antihoraire); + + if (i>1) { + ctx.fill(); + } else { + ctx.stroke(); + } + } + } + } +} +</pre> + +<p>{{EmbedLiveSample("Les_arcs", 160, 210, "https://mdn.mozillademos.org/files/204/Canvas_arc.png")}}</p> + +<h3 id="Les_courbes_quadratiques_et_de_Bézier">Les courbes quadratiques et de Bézier</h3> + +<p>Le type suivant de trajets disponible est la <a href="https://fr.wikipedia.org/wiki/Courbe_de_B%C3%A9zier">courbe de Bézier</a>, disponible en deux variétés, cubique et quadratique. Elles sont généralement utilisées pour dessiner des formes naturelles complexes.</p> + +<dl> + <dt>{{domxref("CanvasRenderingContext2D.quadraticCurveTo", "quadraticCurveTo(cp1x, cp1y, x, y)")}}</dt> + <dd>Dessine une courbe de Bézier quadratique depuis la position courante du stylo jusqu'au point final spécifié par <code>x</code> et <code>y</code>, en utilisant le point de contrôle spécifié par <code>cp1x</code> et <code>cp1y</code>.</dd> + <dt>{{domxref("CanvasRenderingContext2D.bezierCurveTo", "bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)")}}</dt> + <dd>Dessine une courbe de Bézier cubique depuis la position courante du stylo jusqu'au point spécifié par <code>x</code> et <code>y</code>, en utilisant les points de contrôle (<code>cp1x</code>, <code>cp1y</code>) et (<code>cp2x</code>, <code>cp2y</code>).</dd> +</dl> + +<p><img alt="" class="internal" src="https://mdn.mozillademos.org/files/223/Canvas_curves.png" style="float: right; height: 190px; width: 190px;">La différence entre ces deux méthodes est mieux décrite par l'image à droite. Une courbe quadratique de Bézier a un point de départ et un point d'arrivée (points bleus), et seulement un <strong>point de contrôle</strong> (indiqué par le point rouge), tandis qu'une courbe de Bézier cubique utilise deux points de contrôle.</p> + +<p>Les paramètres <code>x</code> et <code>y</code> de ces deux méthodes sont les coordonnées du point d'arrivée. <code>cp1x</code> et <code>cp1y</code> sont les coordonnées du premier point de contrôle, et <code>cp2x</code> et <code>cp2y</code> sont les coordonnées du second point de contrôle.</p> + +<p>Utiliser des courbes quadratiques et cubiques de Bézier peut constituer un certain défi, car à la différence d'un logiciel de tracé des vecteurs comme <em>Adobe Illustrator</em>, nous n'avons pas de retour visuel direct concernant ce que nous faisons. Cela rend passablement difficile le dessin de formes complexes. Dans l'exemple suivant, nous allons dessiner quelques formes naturelles simples, mais si vous avez du temps et - surtout - de la patience, des formes bien plus complexes peuvent être créées.</p> + +<p>Il n'y a rien de très difficile dans ces exemples. Dans les deux cas, on peut voir une succession de courbes être dessinées qui aboutissent finalement à une forme complète.</p> + +<h4 id="Courbes_de_Bézier_quadratiques">Courbes de Bézier quadratiques</h4> + +<p>Cet exemple utilise plusieurs courbes quadratiques de Bézier pour rendre une bulle de dialogue.</p> + +<div class="hidden"> +<pre class="brush: html notranslate"><html> + <body onload="dessiner();"> + <canvas id="canevas" width="150" height="150"></canvas> + </body> +</html> +</pre> +</div> + +<pre class="brush: js notranslate">function dessiner() { + var canevas = document.getElementById('canevas'); + if (canevas.getContext) { + var ctx = canevas.getContext('2d'); + + // Exemples de courbes quadratiques + ctx.beginPath(); + ctx.moveTo(75, 25); + ctx.quadraticCurveTo(25, 25, 25, 62.5); + ctx.quadraticCurveTo(25, 100, 50, 100); + ctx.quadraticCurveTo(50, 120, 30, 125); + ctx.quadraticCurveTo(60, 120, 65, 100); + ctx.quadraticCurveTo(125, 100, 125, 62.5); + ctx.quadraticCurveTo(125, 25, 75, 25); + ctx.stroke(); + } +} +</pre> + +<p>{{EmbedLiveSample("Courbes_de_Bézier_quadratiques", 160, 160, "https://mdn.mozillademos.org/files/243/Canvas_quadratic.png")}}</p> + +<h4 id="Les_courbes_de_Bézier_cubiques">Les courbes de Bézier cubiques</h4> + +<p>Cet exemple dessine un cœur en utilisant les courbes de Bézier cubiques.</p> + +<div class="hidden"> +<pre class="brush: html notranslate"><html> + <body onload="dessiner();"> + <canvas id="canevas" width="150" height="150"></canvas> + </body> +</html> +</pre> +</div> + +<pre class="brush: js notranslate">function dessiner() { + var canevas = document.getElementById('canevas'); + if (canevas.getContext) { + var ctx = canevas.getContext('2d'); + + // Exemple de courbes cubiques + ctx.beginPath(); + ctx.moveTo(75, 40); + ctx.bezierCurveTo(75, 37, 70, 25, 50, 25); + ctx.bezierCurveTo(20, 25, 20, 62.5, 20, 62.5); + ctx.bezierCurveTo(20, 80, 40, 102, 75, 120); + ctx.bezierCurveTo(110, 102, 130, 80, 130, 62.5); + ctx.bezierCurveTo(130, 62.5, 130, 25, 100, 25); + ctx.bezierCurveTo(85, 25, 75, 37, 75, 40); + ctx.fill(); + } +} +</pre> + +<p>{{EmbedLiveSample("Les_courbes_de_Bézier_cubiques", 160, 160, "https://mdn.mozillademos.org/files/207/Canvas_bezier.png")}}</p> + +<h3 id="Rectangles">Rectangles</h3> + +<p>En plus des trois méthodes que nous avons vues dans {{anch("Dessin de rectangles")}}, qui dessinent des formes rectangulaires directement sur le canevas, il y a la méthode <code>rect()</code>, qui ajoute un trajet rectangulaire à un trajet actuellement ouvert.</p> + +<dl> + <dt>{{domxref("CanvasRenderingContext2D.rect", "rect(x, y, largeur, hauteur)")}}</dt> + <dd>Dessine un rectangle dont l'angle supérieur gauche est spécifié par (<code>x</code>, <code>y</code>), avec les <code>largeur</code> et <code>hauteur</code> spécifiées.</dd> +</dl> + +<p>Quand cette méthode est exécutée, la méthode <code>moveTo()</code> est automatiquement appelée avec les paramètres (0,0). En d'autres termes, la position en cours du stylo est automatiquement réinitialisée aux coordonnées par défaut.</p> + +<h3 id="Combiner_les_possibilités">Combiner les possibilités</h3> + +<p>Jusqu'à présent, chaque exemple de cette page a utilisé un seul type de fonction de trajet par forme. Cependant, il n'y a pas de limite au nombre ou aux types de trajets que vous pouvez utiliser pour créer une forme. Ainsi, dans ce dernier exemple, combinons toutes les fonctions de trajet pour faire un ensemble de personnages d'un jeu très célèbre.</p> + +<div class="hidden"> +<pre class="brush: html notranslate"><html> + <body onload="dessiner();"> + <canvas id="canevas" width="150" height="150"></canvas> + </body> +</html> +</pre> +</div> + +<pre class="brush: js notranslate">function dessiner() { + var canevas = document.getElementById('canevas'); + if (canevas.getContext) { + var ctx = canevas.getContext('2d'); + + rectArrondi(ctx, 12, 12, 150, 150, 15); + rectArrondi(ctx, 19, 19, 150, 150, 9); + rectArrondi(ctx, 53, 53, 49, 33, 10); + rectArrondi(ctx, 53, 119, 49, 16, 6); + rectArrondi(ctx, 135, 53, 49, 33, 10); + rectArrondi(ctx, 135, 119, 25, 49, 10); + + ctx.beginPath(); + ctx.arc(37, 37, 13, Math.PI/7, -Math.PI/7, false); + ctx.lineTo(31, 37); + ctx.fill(); + + for(var i = 0; i< 8; i++) { + ctx.fillRect(51 + i * 16, 35, 4, 4); + } + + for(i = 0; i < 6; i++) { + ctx.fillRect(115, 51 + i * 16, 4, 4); + } + + for(i = 0; i < 8; i++) { + ctx.fillRect(51 + i * 16, 99, 4, 4); + } + + ctx.beginPath(); + ctx.moveTo(83, 116); + ctx.lineTo(83, 102); + ctx.bezierCurveTo(83, 94, 89, 88, 97, 88); + ctx.bezierCurveTo(105, 88, 111, 94, 111, 102); + ctx.lineTo(111, 116); + ctx.lineTo(106.333, 111.333); + ctx.lineTo(101.666, 116); + ctx.lineTo(97, 111.333); + ctx.lineTo(92.333, 116); + ctx.lineTo(87.666, 111.333); + ctx.lineTo(83, 116); + ctx.fill(); + + ctx.fillStyle = "white"; + ctx.beginPath(); + ctx.moveTo(91, 96); + ctx.bezierCurveTo(88, 96, 87, 99, 87, 101); + ctx.bezierCurveTo(87, 103, 88, 106, 91, 106); + ctx.bezierCurveTo(94, 106, 95, 103, 95, 101); + ctx.bezierCurveTo(95, 99, 94, 96, 91, 96); + ctx.moveTo(103, 96); + ctx.bezierCurveTo(100, 96, 99, 99, 99, 101); + ctx.bezierCurveTo(99, 103, 100, 106, 103, 106); + ctx.bezierCurveTo(106, 106, 107, 103, 107, 101); + ctx.bezierCurveTo(107, 99, 106, 96, 103, 96); + ctx.fill(); + + ctx.fillStyle = "black"; + ctx.beginPath(); + ctx.arc(101, 102, 2, 0, Math.PI * 2, true); + ctx.fill(); + + ctx.beginPath(); + ctx.arc(89, 102, 2, 0, Math.PI * 2, true); + ctx.fill(); + } +} + +// Une fonction utilitaire pour tracer des rectangles avec des coins arrondis + +function rectArrondi(ctx, x, y, largeur, hauteur, rayon) { + ctx.beginPath(); + ctx.moveTo(x, y + rayon); + ctx.lineTo(x, y + hauteur - rayon); + ctx.quadraticCurveTo(x, y + hauteur, x + rayon, y + hauteur); + ctx.lineTo(x + largeur - rayon, y + hauteur); + ctx.quadraticCurveTo(x + largeur, y + hauteur, x + largeur, y + hauteur - rayon); + ctx.lineTo(x + largeur, y + rayon); + ctx.quadraticCurveTo(x + largeur, y, x + largeur - rayon, y); + ctx.lineTo(x + rayon,y); + ctx.quadraticCurveTo(x, y, x, y + rayon); + ctx.stroke(); +} + +</pre> + +<p>L'image résultante ressemble à ce qui suit :</p> + +<div id="section_18"> +<p>{{EmbedLiveSample("Combiner_les_possibilités", 160, 160)}}</p> + +<p>Nous ne l'expliquerons pas plus en détails, du fait que c'est étonnament simple. Les choses les plus importantes à noter sont l'utilisation de la propriété <code>fillStyle</code> sur le contexte du dessin, et l'utilisation d'une fonction utilitaire dans ce cas, rectArrondi<code>())</code>. L'utilisation de fonctions utilitaires pour des éléments de dessin que vous faites souvent peut être très utile, et peut réduire la quantité de code dont vous avez besoin, ainsi que sa complexité.</p> + +<p>Nous reviendrons sur <code>fillStyle</code> plus en détail plus loin dans ce tutoriel. Pour l'instant, tout ce que nous faisons est de l'utiliser pour changer en blanc la couleur pour les trajets depuis la couleur noire par défaut, et inversement ensuite.</p> +</div> +</div> + +<h2 id="Objets_Path2D">Objets Path2D</h2> + +<p>Comme nous l'avons vu dans le dernier exemple, il peut y avoir une série de trajets et d'instructions de dessin pour dessiner des objets sur votre canevas. Pour simplifier le code et améliorer les performances, l'objet {{domxref("Path2D")}}, disponible dans les versions récentes des navigateurs, vous permet de mettre en cache ou d'enregistrer ces instrucions de dessin. Vous pourrez alors rejouer vos trajets rapidement.<br> + Voyons comment nous pouvons construire un objet <code>Path2D </code>:</p> + +<dl> + <dt>{{domxref("Path2D.Path2D", "Path2D()")}}</dt> + <dd>Le constructor <code><strong>Path2D()</strong></code> retourne un objet <code>Path2D</code> nouvellement instancié, optionellement avec un autre trajet comme argument (crée une copie), ou optionellement avec une chaîne constituée de données de <a href="https://developer.mozilla.org/fr-FR/docs/Web/SVG/Tutorial/Paths">trajet SVG</a>.</dd> +</dl> + +<pre class="notranslate"><code>new Path2D(); // objet trajet vide +new Path2D(trajet); // copie depuis un autre objet Path2D +new Path2D(d); // trajet depuis des données de trajet SVG</code></pre> + +<p>Toutes les <a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D#Paths">méthodes de trajet</a> telles que <code>moveTo</code>, <code>rect</code>, <code>arc</code> ou <code>quadraticCurveTo</code>, etc., que nous avons appris à connaître ci-dessus, sont disponibles sur les objets <code>Path2D</code>.</p> + +<p>L'API <code>Path2D</code> ajoute aussi une manière de combiner des trajets en utilisant la méthode <code>addPath</code>. Cela peut être utile quand vous voulez contruire des objets à partir de plusieurs composants, par exemple.</p> + +<dl> + <dt>{{domxref("Path2D.addPath", "Path2D.addPath(trajet [, transformation])")}}</dt> + <dd>Ajoute un trajet, au trajet en cours, avec une matrice de transformation.</dd> +</dl> + +<h3 id="Exemple_de_Path2D">Exemple de Path2D</h3> + +<p>Dans cet exemple, on crée un rectangle et un cercle. Tous deux sont stockés comme des objets <code>Path2D</code>, de sorte qu'ils sont disponibles pour un usage ultérieur. Avec la nouvelle API <code>Path2D</code>, plusieurs méthodes ont été mises à jour pour accepter optionnellement un objet <code>Path2D</code> à utiliser au lieu du trajet en cours. Ici, <code>stroke</code> et <code>fill</code> sont utilisés avec un argument de trajet pour dessiner les deux objets sur le canevas, par exemple.</p> + +<div class="hidden"> +<pre class="brush: html notranslate"><html> + <body onload="dessiner();"> + <canvas id="canvas" width="130" height="100"></canvas> + </body> +</html> +</pre> +</div> + +<pre class="brush: js;highlight[6,9] notranslate">function dessiner() { + var canevas = document.getElementById('canvas'); + if (canevas.getContext){ + var ctx = canevas.getContext('2d'); + + var rectangle = new Path2D(); + rectangle.rect(10, 10, 50, 50); + + var cercle = new Path2D(); + cercle.moveTo(125, 35); + cercle.arc(100, 35, 25, 0, 2 * Math.PI); + + ctx.stroke(rectangle); + ctx.fill(cercle); + } +}</pre> + +<p>{{EmbedLiveSample("Exemple_de_Path2D", 130, 110, "https://mdn.mozillademos.org/files/9851/path2d.png")}}</p> + +<h3 id="Utilisation_de_trajets_SVG">Utilisation de trajets SVG</h3> + +<p>Une autre fonctionnalité puissante de la nouvelle API <code>Path2D</code> de canevas est l'utilisation de <a href="https://developer.mozilla.org/fr-FR/docs/Web/SVG/Tutorial/Paths">données de trajet SVG</a> pour initialiser des trajets sur votre canevas. Cela peut vous permettre de faire circuler des données de trajet et les réutiliser, à la fois en SVG et dans un canevas.</p> + +<p>Le trajet se déplacera au point (<code>M10 10</code>) et se déplacera alors de 80 points horizontalement vers la droite (<code>h 80</code>), ensuite de 80 points vers le bas (<code>v 80</code>), puis de 80 points vers la gauche (<code>h -80</code>), et reviendra alors au départ (<code>z</code>). Vous pouvez voir cet exemple sur la page du <a href="https://developer.mozilla.org/en-US/docs/Web/API/Path2D.Path2D#Using_SVG_paths">constructeur P<code>ath2D</code></a>.</p> + +<pre class="notranslate"><code>var p = new Path2D("M10 10 h 80 v 80 h -80 Z");</code></pre> + +<p>{{PreviousNext("Tutoriel_canvas/Utilisation_de_base", "Tutoriel_canvas/Ajout_de_styles_et_de_couleurs")}}</p> diff --git a/files/fr/web/api/canvas_api/tutoriel_canvas/hit_regions_and_accessibility/index.html b/files/fr/web/api/canvas_api/tutoriel_canvas/hit_regions_and_accessibility/index.html new file mode 100644 index 0000000000..59a4d1ce35 --- /dev/null +++ b/files/fr/web/api/canvas_api/tutoriel_canvas/hit_regions_and_accessibility/index.html @@ -0,0 +1,97 @@ +--- +title: Hit regions and accessibility +slug: Web/API/Canvas_API/Tutoriel_canvas/Hit_regions_and_accessibility +translation_of: Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility +--- +<div>{{CanvasSidebar}} {{ PreviousNext("Web/API/Canvas_API/Tutorial/Pixel_manipulation_with_canvas", "Web/API/Canvas_API/Tutorial/Optimizing_canvas") }}</div> + +<div class="summary">L'élément {{HTMLElement("canvas")}} lui-même est juste un bitmap et ne fourni aucune information sur les objets dessinés. Le contenu des canvas n'est pas sujet aux outils d'accessibility comme l'est la sémantique HTML. En général vous devriez éviter d'utiliser les canvas sur les sites ou les applications accessibles. Le marche à suivre suivante peut vous aider à les rendre plus accessibles.</div> + +<h2 id="Moyen_de_repli">Moyen de repli</h2> + +<p>Le contenu à l'intérieur d'un tag <code><canvas> ... </canvas></code> peut être utilisé comme moyen de secours pour les navigteurs qui ne supportent pas le rendu de canvas. C'est aussi très utile pour les utilisateurs qui utilisent des technologies adaptées (comme les lecteurs d'écran) qui peuvent lire et interpréter les éléments du DOM. Un bon exemple sur <a href="http://www.html5accessibility.com/tests/canvas.html">html5accessibility.com</a> demontre comment cela peut être fait.</p> + +<pre class="brush: html notranslate"><canvas> + <h2>Shapes</h2> + <p>A rectangle with a black border. + In the background is a pink circle. + Partially overlaying the <a href="http://en.wikipedia.org/wiki/Circle" onfocus="drawCircle();" onblur="drawPicture();">circle</a>. + Partially overlaying the circle is a green + <a href="http://en.wikipedia.org/wiki/Square" onfocus="drawSquare();" onblur="drawPicture();">square</a> + and a purple <a href="http://en.wikipedia.org/wiki/Triangle" onfocus="drawTriangle();" onblur="drawPicture();">triangle</a>, + both of which are semi-opaque, so the full circle can be seen underneath.</p> +</canvas> </pre> + +<p>Jetez un oeil à la <a href="https://www.youtube.com/watch?v=ABeIFlqYiMQ">video comment NVDA lit cet exemple par Steve Faulkner</a> (en anglais).</p> + +<h2 id="Les_règles_ARIA">Les règles ARIA</h2> + +<p>Accessible Rich Internet Applications <strong>(<a href="/en-US/docs/Web/Accessibility/ARIA">ARIA</a>)</strong> (≈ <a href="https://fr.wikipedia.org/wiki/Accessible_Rich_Internet_Applications">Les applications Internet Accessibles Riches)</a> défini des pistes pour rendre le contenu Web et les applications Web plus accessibles pour les personnes ayant un handicap. Vous pouvez utiliser les attributs ARIA pour decrire le comportement et le but de vos éléments canvas. Allez voir <a href="/en-US/docs/Web/Accessibility/ARIA">ARIA</a> et <a href="/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques">les techniques ARIA</a> pour plus d'informations.</p> + +<pre class="brush: html notranslate"><canvas id="button" tabindex="0" role="button" aria-pressed="false" aria-label="Start game"></canvas> +</pre> + +<h2 id="Zones_cibles_hit_Region">Zones cibles (hit Region)</h2> + +<p>Que les coordonnés de la souris soient dans une zone particulière des canvas, est un problème fréquent à résoudre. L'API de la "hit region" vous permet de definir une zone de votre canvas et offre une autre possibilité pour proposer du contenu interactif dans les canvas a destination des outils d'accessibilité. Il permet de rendre la "hit detection" plus simple easier and vous laisser envoyer des événements aux éléments du DOM. L'API a les trois methodes suivantes (qui sont encore expérimentales dans les navigateurs actuel ; reportez-vous au tableau des comptibilités des navigateurs).</p> + +<dl> + <dt>{{domxref("CanvasRenderingContext2D.addHitRegion()")}} {{experimental_inline}}</dt> + <dd>Ajoute une "hit region" au canvas..</dd> + <dt>{{domxref("CanvasRenderingContext2D.removeHitRegion()")}} {{experimental_inline}}</dt> + <dd>Supprime la "hit region" avec l'<code>id</code> spécifiée venant du canvas.</dd> + <dt>{{domxref("CanvasRenderingContext2D.clearHitRegions()")}} {{experimental_inline}}</dt> + <dd>Retire toutes les "hit regions" du cnavas.</dd> +</dl> + +<p>Vous pouvez ajouter une "hit region" à votre chemin et vérifier la propriété {{domxref("MouseEvent.region")}} pour tester si votre souris entre dans votre région, par exemple.</p> + +<pre class="brush: html notranslate"><canvas id="canvas"></canvas> +<script> +var canvas = document.getElementById('canvas'); +var ctx = canvas.getContext('2d'); + +ctx.beginPath(); +ctx.arc(70, 80, 10, 0, 2 * Math.PI, false); +ctx.fill(); +ctx.addHitRegion({id: 'circle'}); + +canvas.addEventListener('mousemove', function(event) { + if (event.region) { + alert('hit region: ' + event.region); + } +}); +</script></pre> + +<p>La méthode <code>addHitRegion()</code> accepte aussi une option de <code>control</code> pour envoyer des événement vers un élément (c'est un enfant des canvas):</p> + +<pre class="brush: js notranslate">ctx.addHitRegion({control: element});</pre> + +<p>Cela peut être utile pour le routage d'éléments {{HTMLElement("input")}}, par exemple. Regardez aussi <a href="http://codepen.io/adobe/pen/BhcmK">codepen demo</a>.</p> + +<h2 id="Focus_rings">Focus rings</h2> + +<p>Quand on travaille avec le clavier, focus rings (anneaux de mise au point) sont utilies pour aider dans la navigation sur une page. Pour dessiner des "focus ring" dans un dessin de canvas, la propriété <code>drawFocusIfNeeded</code> peut être utilisée.</p> + +<dl> + <dt>{{domxref("CanvasRenderingContext2D.drawFocusIfNeeded()")}} {{experimental_inline}}</dt> + <dd>Si un élément donné est ciblé, cette méthode dessine un anneaud de mise ne valeur autoure du chemin courant.</dd> +</dl> + +<p>De plus, la méthode <code>scrollPathIntoView()</code> peut être utilisée pour rendre visible un élément dans une page s'il est ciblé, par exemple.</p> + +<dl> + <dt>{{domxref("CanvasRenderingContext2D.scrollPathIntoView()")}} {{experimental_inline}}</dt> + <dd>Affiche le chemin courant ou le chemin donné.</dd> +</dl> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="https://www.w3.org/WAI/PF/HTML/wiki/Canvas_Accessibility_Use_Cases">Canvas accessibility use cases</a></li> + <li><a href="https://www.w3.org/html/wg/wiki/AddedElementCanvas">Canvas element accessibility issues</a></li> + <li><a href="http://www.paciellogroup.com/blog/2012/06/html5-canvas-accessibility-in-firefox-13/">HTML5 Canvas Accessibility in Firefox 13 – by Steve Faulkner</a></li> + <li><a href="https://html.spec.whatwg.org/multipage/scripting.html#best-practices">Best practices for interactive canvas elements</a></li> +</ul> + +<div>{{ PreviousNext("Web/API/Canvas_API/Tutorial/Pixel_manipulation_with_canvas", "Web/API/Canvas_API/Tutorial/Optimizing_canvas") }}</div> diff --git a/files/fr/web/api/canvas_api/tutoriel_canvas/index.html b/files/fr/web/api/canvas_api/tutoriel_canvas/index.html new file mode 100644 index 0000000000..a430b361bd --- /dev/null +++ b/files/fr/web/api/canvas_api/tutoriel_canvas/index.html @@ -0,0 +1,52 @@ +--- +title: Tutoriel canvas +slug: Web/API/Canvas_API/Tutoriel_canvas +tags: + - Canvas + - Guide + - HTML + - Tutoriel_canvas + - Tutoriels +translation_of: Web/API/Canvas_API/Tutorial +--- +<div>{{CanvasSidebar}}</div> + +<p><img alt="" src="/@api/deki/files/1232/=Canvas_tut_examples.jpg" style="float: right;"></p> + +<p class="summary"><strong><a href="https://developer.mozilla.org/fr/docs/Web/HTML/Element/canvas" title="fr/HTML/Canvas"><code><canvas></code></a></strong> est un nouvel élément <a href="https://developer.mozilla.org/fr/docs/Web/HTML" title="fr/HTML">HTML</a> qui peut être utilisé pour dessiner des éléments graphiques à l'aide de scripts (habituellement <a href="https://developer.mozilla.org/fr/docs/Glossaire/JavaScript" title="fr/JavaScript">JavaScript</a>). Il permet par exemple de dessiner des graphiques, de réaliser des compositions de photographies ou des animations simples (voire <a href="https://developer.mozilla.org/fr/docs/Un_raycaster_basique_avec_canvas" title="fr/Un_raycaster_basique">pas si simples</a>). Les images à droite montrent quelques exemples d'implémentations utilisant <code><canvas></code> que nous verrons plus tard dans ce tutoriel.</p> + +<p><span id="result_box" lang="fr"><span>Ce tutoriel explique comment utiliser l'élément <code><canvas></code> pour dessiner des graphiques 2D, en commençant par les bases.</span> <span>Les exemples fournis devraient vous donner des idées claires sur ce que vous pouvez faire avec la toile et fournir des extraits de code qui peuvent vous aider à créer votre propre contenu.</span></span></p> + +<p><span id="result_box" lang="fr"><span>D'abord introduit dans WebKit par Apple pour le tableau de bord OS X, <code><canvas></code> a depuis été implémenté dans les navigateurs.</span> <span>Aujourd'hui, tous les principaux navigateurs le prennent en charge.</span></span></p> + +<h2 id="Avant_de_commencer" name="Avant_de_commencer">Avant de commencer</h2> + +<p>L'utilisation de l'élément <code><canvas></code> n'a rien de très compliqué, mais nécessite tout de même une compréhension de base de <a href="https://developer.mozilla.org/fr/docs/Web/HTML" title="fr/HTML">HTML</a> et <a href="https://developer.mozilla.org/fr/docs/Glossaire/JavaScript" title="fr/JavaScript">JavaScript</a>. L'élément <code><canvas></code> n'est pas reconnu par tous les vieux navigateurs, mais il est supporté par les versions les plus récentes des principaux. <span id="result_box" lang="fr"><span>La taille par défaut de </span></span> canvas <span lang="fr"><span> est 300 px × 150 px (largeur × hauteur).</span> <span>Mais les tailles personnalisées peuvent être définies à l'aide des propriétés <a href="https://developer.mozilla.org/fr/docs/Web/HTML">HTML</a> <code>height</code> et <code>width</code>.</span> <span>Afin de dessiner des graphiques sur </span></span> canvas <span lang="fr"><span>, nous utilisons un objet de contexte JavaScript, qui crée des graphiques à la volée.</span></span></p> + +<h2 id="Dans_ce_tutoriel" name="Dans_ce_tutoriel">Dans ce tutoriel</h2> + +<ul> + <li><a href="https://developer.mozilla.org/fr/docs/Tutoriel_canvas/Utilisation_de_base" title="fr/Tutoriel_canvas/Utilisation_de_base">Utilisation de base</a></li> + <li><a href="https://developer.mozilla.org/fr/docs/Tutoriel_canvas/Formes_g%C3%A9om%C3%A9triques" title="fr/Tutoriel_canvas/Formes_géométriques">Dessin de formes géométriques</a></li> + <li><a href="https://developer.mozilla.org/fr/docs/Tutoriel_canvas/Ajout_de_styles_et_de_couleurs" title="fr/Tutoriel_canvas/Ajout_de_styles_et_de_couleurs">Ajout de styles et de couleurs</a></li> + <li><a href="https://developer.mozilla.org/fr/docs/Dessin_de_texte_avec_canvas">Dessin de texte</a></li> + <li><a href="https://developer.mozilla.org/fr/docs/Tutoriel_canvas/Utilisation_d'images" title="fr/Tutoriel_canvas/Utilisation_d'images">Utilisation d'images</a></li> + <li><a href="https://developer.mozilla.org/fr/docs/Tutoriel_canvas/Transformations" title="fr/Tutoriel_canvas/Transformations">Transformations</a></li> + <li><a href="https://developer.mozilla.org/fr/docs/Web/API/Canvas_API/Tutorial/Compositing" title="fr/Tutoriel_canvas/Compositions">Compositions et découpage</a></li> + <li><a href="https://developer.mozilla.org/fr/docs/Tutoriel_canvas/Animations_basiques" title="fr/Tutoriel_canvas/Animations_basiques">Animations basiques</a></li> + <li><a href="https://developer.mozilla.org/fr/docs/Tutoriel_canvas/Advanced_animations">Animations avancées</a></li> + <li><a href="https://developer.mozilla.org/fr/docs/Tutoriel_canvas/Pixel_manipulation_with_canvas">Manipulation des pixels</a></li> + <li><a href="https://developer.mozilla.org/fr/docs/Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility">Régions touchées et accessibilité</a></li> + <li><a href="https://developer.mozilla.org/fr/docs/Tutoriel_canvas/Optimizing_canvas" title="https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Optimizing_canvas">Optimisation</a></li> + <li><a href="https://developer.mozilla.org/fr/docs/Web/API/Canvas_API/Tutorial/Finale">Final</a></li> +</ul> + +<h2 id="Voir_aussi" name="Voir_aussi">Voir aussi</h2> + +<ul> + <li><a href="https://developer.mozilla.org/fr/docs/Web/HTML/Canvas" title="fr/HTML/Canvas">Page du sujet canvas</a></li> + <li><a class="external external-icon" href="http://www.html5canvastutorials.com/" title="http://www.html5canvastutorials.com/">HTML5CanvasTutorials</a> (en)</li> + <li><a href="/Special:Tags?tag=Exemples_d'utilisation_de_canvas&language=fr" title="Special:Tags?tag=Exemples_d'utilisation_de_canvas&language=fr">Exemples d'utilisation de canvas</a> (en)</li> +</ul> + +<p>{{ Next("Tutoriel_canvas/Utilisation_de_base") }}</p> diff --git a/files/fr/web/api/canvas_api/tutoriel_canvas/optimizing_canvas/index.html b/files/fr/web/api/canvas_api/tutoriel_canvas/optimizing_canvas/index.html new file mode 100644 index 0000000000..d8e6e8383c --- /dev/null +++ b/files/fr/web/api/canvas_api/tutoriel_canvas/optimizing_canvas/index.html @@ -0,0 +1,112 @@ +--- +title: Optimiser les Canvas +slug: Web/API/Canvas_API/Tutoriel_canvas/Optimizing_canvas +translation_of: Web/API/Canvas_API/Tutorial/Optimizing_canvas +--- +<div>{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility", "Web/API/Canvas_API/Tutorial/Finale")}}</div> + +<div class="summary"> +<p>L'élément {{HTMLElement("canvas")}} est l'un des standards les plus utilisés pour le rendu graphique 2D sur le web. Il est surtout utilisé dans les jeux et les visualisations complexes. Cependant, les sites et applications web poussent les canvas à leurs limites, et les performances commencent à en pâtir. Cet article propose des suggestions pour optimiser votre utilisation de l'élément canvas, et pour être certain que votre site ou application web fonctionne bien.</p> +</div> + +<h2 id="Conseils_sur_les_performances">Conseils sur les performances</h2> + +<p>Ceci est une liste de conseils pour améliorer les performances</p> + +<h3 id="Pré-rendre_les_primitifs_similaires_ou_répéter_les_objects_dans_un_canvas_hors-champ">Pré-rendre les primitifs similaires ou répéter les objects dans un canvas hors-champ</h3> + +<p>Si vous avez besoin d'ajouter un dessin complexe identique à chaque image rendue, préférez l'utilisation d'un canvas hors-champ, le rendre une fois (ou à chaque fois qu'il change) sur ce canvas, puis dessinez-le sur le canvas principal à chaque image rendue.</p> + +<pre class="brush: js notranslate">myEntity.offscreenCanvas = document.createElement("canvas"); +myEntity.offscreenCanvas.width = myEntity.width; +myEntity.offscreenCanvas.height = myEntity.height; +myEntity.offscreenContext = myEntity.offscreenCanvas.getContext("2d"); + +myEntity.render(myEntity.offscreenContext); +</pre> + +<h3 id="Abandonnez_les_coordonnées_décimales_et_utilisez_des_entiers_à_la_place">Abandonnez les coordonnées décimales et utilisez des entiers à la place</h3> + +<p>Un rendu de sous-pixel est opéré quand on dessine des objets sur un canvas sans valeur entière.</p> + +<pre class="brush: js notranslate">ctx.drawImage(myImage, 0.3, 0.5); +</pre> + +<p>Cela pousse le navigateur à faire des calculs supplémentaires pour créer un effet d'anti-crénelage. Pour empêcher cela, il faut s'assurer d'arrondir les coordonnées utilisées pour {{domxref("CanvasRenderingContext2D.drawImage", "drawImage()")}}.</p> + +<h3 id="Ne_pas_redimensionner_dimages_avec_drawImage">Ne pas redimensionner d'images avec <code>drawImage</code></h3> + +<p>Préférez mettre en cache plusieurs dimensions de votre image dans un canvas hors-champ au lieu de les redimensionner constamment avec {{domxref("CanvasRenderingContext2D.drawImage", "drawImage()")}}.</p> + +<h3 id="Utiliser_des_canvas_empilés_pour_les_scènes_complexes">Utiliser des canvas empilés pour les scènes complexes</h3> + +<p>Pour des scènes complexes, on peut souvent remarquer que quelques éléments changent souvent tandis que d'autres ne changent jamais. Une optimisation possible dans ce cas consiste à utiliser plusieurs calques sous forme de canvas empilés.</p> + +<p>Par exemple, on peut créer un calque UI, dessiné au-dessus de tous les autres uniquement lorsque l'utilisateur accède à un menu. En dessous, un calque <em>jeu</em> où les entités du jeu sont souvent mises à jour. Et, à l'arrière, un calque de fond rarement modifié.</p> + +<pre class="brush: html notranslate"><div id="stage"> + <canvas id="ui-layer" width="480" height="320"></canvas> + <canvas id="game-layer" width="480" height="320"></canvas> + <canvas id="background-layer" width="480" height="320"></canvas> +</div> + +<style> + #stage { + width: 480px; + height: 320px; + position: relative; + border: 2px solid black + } + canvas { position: absolute; } + #ui-layer { z-index: 3 } + #game-layer { z-index: 2 } + #background-layer { z-index: 1 } +</style> +</pre> + +<h3 id="Du_CSS_pour_les_grandes_images_de_fond">Du CSS pour les grandes images de fond</h3> + +<p>Si comme pour la plupart des jeux, vous utilisez une image de fond statique, préférez utiliser un simple {{HTMLElement("div")}} en dessous du canvas avec les propriétés CSS {{cssxref("background")}} appropriées. Cela vous évitera de redessiner une grande image dans le canvas à chaque tick.</p> + +<h3 id="Redimensionner_les_canvas_avec_CSS_transform">Redimensionner les canvas avec CSS transform</h3> + +<p><a href="/fr/docs/Web/CSS/CSS_Transforms/Utilisation_des_transformations_CSS">Les transformations CSS</a> sont plus rapides car elles utilisent le GPU. Le mieux est d'utiliser un canvas plus grand et de réduire sa taille. Pour Firefox OS, les dimensions sont de 480 x 320 px.</p> + +<pre class="brush: js notranslate">var scaleX = window.innerWidth / canvas.width; +var scaleY = window.innerHeight / canvas.height; + +var scaleToFit = Math.min(scaleX, scaleY); +var scaleToCover = Math.max(scaleX, scaleY); + +stage.style.transformOrigin = "0 0"; //scale from top left +stage.style.transform = "scale(" + scaleToFit + ")"; +</pre> + +<h3 id="Utiliser_lattribut_moz-opaque_Gecko_only">Utiliser l'attribut <code>moz-opaque</code> (Gecko only)</h3> + +<p>Si le canvas n'a pas besoin de transparence, ajouter l'attribut <code>moz-opaque</code> dans la balise canvas. Cette information peut être utilisée par le navigateur pour optimiser le rendu.</p> + +<pre class="brush: html notranslate"><canvas id="mycanvas" moz-opaque></canvas></pre> + +<h3 id="Dautres_conseils">D'autres conseils</h3> + +<ul> + <li>Regrouper les appels canevas (par exemple, dessiner un chemin de plusieurs lignes plutôt que plusieurs lignes séparées).</li> + <li>Éviter de refaire un rendu si ce n'est pas nécessaire.</li> + <li>Rendre uniquement les différences, pas tout le canvas.</li> + <li>Éviter la propriété {{domxref("CanvasRenderingContext2D.shadowBlur", "shadowBlur")}} quand c'est possible.</li> + <li>Empêcher <a href="/fr/docs/Dessin_de_texte_avec_canvas">le rendu de texte</a> quand c'est possible.</li> + <li>Essayer différents moyens d'effacer le canvas : ({{domxref("CanvasRenderingContext2D.clearRect", "clearRect()")}} vs. {{domxref("CanvasRenderingContext2D.fillRect", "fillRect()")}} vs. redimensionner le canevas).</li> + <li>Avec les animations, utiliser {{domxref("window.requestAnimationFrame()")}} plutôt que {{domxref("window.setInterval()")}}.</li> + <li>Faire attention aux bibliothèques physiques lourdes.</li> + <li>Tester les performances avec <a href="http://jsperf.com" title="http://jsperf.com">JSPerf</a>.</li> +</ul> + +<h2 id="Voir_aussi">Voir aussi</h2> + +<ul> + <li><a href="http://www.html5rocks.com/en/tutorials/canvas/performance/#toc-ref">Improving HTML5 Canvas Performance – HTML5 Rocks</a></li> + <li><a href="https://hacks.mozilla.org/2013/05/optimizing-your-javascript-game-for-firefox-os/">Optimizing your JavaScript game for Firefox OS – Mozilla Hacks</a></li> +</ul> + +<p>{{PreviousNext("Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility", "Web/API/Canvas_API/Tutorial/Finale")}}</p> diff --git a/files/fr/web/api/canvas_api/tutoriel_canvas/pixel_manipulation_with_canvas/index.html b/files/fr/web/api/canvas_api/tutoriel_canvas/pixel_manipulation_with_canvas/index.html new file mode 100644 index 0000000000..a2182f43c1 --- /dev/null +++ b/files/fr/web/api/canvas_api/tutoriel_canvas/pixel_manipulation_with_canvas/index.html @@ -0,0 +1,258 @@ +--- +title: Manipulation de pixels avec canvas +slug: Web/API/Canvas_API/Tutoriel_canvas/Pixel_manipulation_with_canvas +translation_of: Web/API/Canvas_API/Tutorial/Pixel_manipulation_with_canvas +--- +<div>{{CanvasSidebar}} {{PreviousNext("Tutoriel_canvas/Advanced_animations", "Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility")}}</div> + +<div class="summary"> +<p>Jusqu'à présent, nous n'avons pas examiné dans le détail les pixels réels de notre canevas. Avec l'objet ImageData, vous pouvez directement lire et écrire dans le tableau de données de l'image, pour manipuler les pixels un par un. Nous verrons également comment le lissage (anticrénelage) de l'image peut être contrôlé et comment sauvegarder des images depuis votre canevas.</p> +</div> + +<h2 id="Lobjet_ImageData">L'objet <code>ImageData</code></h2> + +<p>L'objet {{domxref("ImageData")}} représente les données de pixels sous-jacentes à une zone d'un objet canevas. Il contient les attributs (en lecture seule) suivants :</p> + +<dl> + <dt><code>width</code></dt> + <dd>La largeur de l'image en pixels.</dd> + <dt><code>height</code></dt> + <dd>La hauteur de l'image en pixels.</dd> + <dt><code>data</code></dt> + <dd>Un {{jsxref("Uint8ClampedArray")}} représentant un tableau monodimensionnel contenant les données dans l'ordre RVBA, ayant des valeurs entières entre 0 et 255 (inclus).</dd> +</dl> + +<p>La propriété <code>data</code> retourne un tableau {{jsxref("Uint8ClampedArray")}} auquel on peut accéder pour voir plus en détail les données brutes des pixels ; chaque pixel est représenté par quatre valeurs sur un octet (rouge, vert, bleu et alpha, dans cet ordre ; c'est-à-dire, le format "RVBA"). Chaque composante de couleur est représentée par un entier entre 0 et 255. Chaque composante reçoit un indice à l'intérieur du tableau, la composante rouge du pixel supérieur gauche étant à l'indice 0 à l'intérieur du tableau. Les pixels continuent ensuite de gauche à droite, puis vers le bas, jusqu'au bout du tableau.</p> + +<p>Le {{jsxref("Uint8ClampedArray")}} contient <code>height</code><em>(hauteur)</em> × <code>width</code><em>(largeur)</em> × 4 octets, dont les valeurs d'indices vont de 0 à (<code>height</code>×<code>width</code>×4)-1.</p> + +<p>Par exemple, pour lire la valeur de la composante bleue d'un pixel situé en colonne 200, ligne 50 de l'image, vous pouvez faire ce qui suit :</p> + +<pre class="brush: js notranslate">composanteBleue = imageData.data[((50 * (imageData.width * 4)) + (200 * 4)) + 2];</pre> + +<p>Vous pouvez accéder à la taille en octets du tableau de pixels en lisant l'attribut <code>Uint8ClampedArray.length</code> :</p> + +<pre class="brush: js notranslate">var nbOctets = imageData.data.length; +</pre> + +<h2 id="Création_dun_objet_ImageData">Création d'un objet <code>ImageData</code></h2> + +<p>Pour créer un nouvel objet <code>ImageData</code> vierge, vous pouvez utiliser la méthode {{domxref("CanvasRenderingContext2D.createImageData", "createImageData()")}}. Il existe deux versions de la méthode <code>createImageData() </code>:</p> + +<pre class="brush: js notranslate">var monImageData = ctx.createImageData(largeur, hauteur);</pre> + +<p>Cela crée un nouvel objet <code>ImageData</code> avec les dimensions spécifiées. Tous les pixels sont prédéfinis comme étant noirs transparents.</p> + +<p>Vous pouvez aussi créer un nouvel objet <code>ImageData</code> ayant les mêmes dimensions que celles de l'objet indiqué par <code>autreImageData</code>. Les pixels du nouvel objet sont tous prédéfinis comme étant noirs transparents. <strong>Cela ne copie pas les données d'image !</strong></p> + +<pre class="brush: js notranslate">var monImageData = ctx.createImageData(autreImageData);</pre> + +<h2 id="Obtention_des_données_pixel_pour_un_contexte">Obtention des données pixel pour un contexte</h2> + +<p>Pour obtenir un objet <code>ImageData</code> contenant une copie des données pixel pour un contexte de canevas, vous pouvez utiliser la méthode <code>getImageData()</code> :</p> + +<pre class="brush: js notranslate">var monImageData = ctx.getImageData(gauche, haut, largeur, hauteur);</pre> + +<p>Cette méthode retourne un objet <code>ImageData</code> représentant les données pixel pour la zone du canevas dont les coins sont représentés par les points (<code>left</code>,<code>top</code>) <em><code> (gauche,haut)</code></em>, (<code>left+width</code>, <code>top</code>) <em>(gauche+largeur, haut)</em>, (<code>left</code>, <code>top+height</code>)<em> (gauche, haut+hauteur)</em> et (<code>left+width</code>, <code>top+height</code>) <em>(gauche+largeur, haut+hauteur)</em>. Les coordonnées sont spécifiées en unités d'espace de coordonnées du canevas.</p> + +<div class="note"> +<p><strong>Note </strong>: Tous les pixels en dehors du canevas seront retournés comme noirs transparents dans l'objet <code>ImageData</code> résultant.</p> +</div> + +<p>Cette méthode est aussi présentée dans l'article <a href="https://developer.mozilla.org/fr/docs/HTML/Manipulating_video_using_canvas">Manipulation vidéo utilisant canvas</a>.</p> + +<h3 id="Une_pipette_à_couleur">Une pipette à couleur</h3> + +<p>Dans cet exemple, nous utilisons la méthode <a href="https://developer.mozilla.org/fr/docs/Web/API/CanvasRenderingContext2D/getImageData">getImageData() </a>pour afficher la couleur en dessous du curseur de la souris. Pour cela, nous avons besoin de la position en cours de la souris donnée par <code>layerX</code> et <code>layerY</code>, nous recherchons ensuite les données pixel à cette position dans le tableau de pixels que <a href="https://developer.mozilla.org/fr/docs/Web/API/CanvasRenderingContext2D/getImageData">getImageData()</a> nous fournit. Finalement, nous utilisons les données du tableau pour définir une couleur d'arrière-plan et un texte dans le <code><div></code> pour afficher la couleur.</p> + +<div class="hidden"> +<pre class="brush: html; notranslate"><canvas id="canvas" width="300" height="227" style="float:left"></canvas> +<div id="color" style="width:200px;height:50px;float:left"></div> +</pre> +</div> + +<pre class="notranslate"><code>var img = new Image(); +img.src = 'https://mdn.mozillademos.org/files/5397/rhino.jpg'; +var canvas = document.getElementById('canvas'); +var ctx = canvas.getContext('2d'); +img.onload = function() { + ctx.drawImage(img, 0, 0); + img.style.display = 'none'; +}; +var color = document.getElementById('color'); +function pick(event) { + var x = event.layerX; + var y = event.layerY; + var pixel = ctx.getImageData(x, y, 1, 1); + var data = pixel.data; + var rgba = 'rgba(' + data[0] + ', ' + data[1] + + ', ' + data[2] + ', ' + (data[3] / 255) + ')'; + color.style.background = rgba; + color.textContent = rgba; +} +canvas.addEventListener('mousemove', pick);</code></pre> + +<p>{{ EmbedLiveSample('A_color_picker', 610, 240) }}</p> + +<h2 id="Peinture_des_données_pixel_dans_un_contexte">Peinture des données pixel dans un contexte</h2> + +<p>Vous pouvez utiliser la méthode <a href="https://developer.mozilla.org/fr/docs/Web/API/CanvasRenderingContext2D/putImageData">putImageData() </a>pour peindre les données pixel dans un contexte :</p> + +<pre class="brush: js notranslate">ctx.putImageData(monImageData, dx, dy); +</pre> + +<p>Les paramètres <code>dx</code> et <code>dy</code> indiquent les coordonnées système dans le contexte du coin supérieur gauche des données pixel qui doivent être peintes.</p> + +<p>Par exemple, pour peindre l'image entière représentée par <code>monImageData</code> dans le coin supérieur gauche du contexte, vous pouvez simplement faire ce qui suit :</p> + +<pre class="brush: js notranslate">ctx.putImageData(monImageData, 0, 0); +</pre> + +<h3 id="Niveaux_de_gris_et_inversion_de_couleurs">Niveaux de gris et inversion de couleurs</h3> + +<p>Dans cet exemple, nous itérons sur tous les pixels pour changer leurs valeurs, puis nous remettons le tableau de pixels modifié sur le canevas à l'aide de <a href="/fr-FR/docs/Web/API/CanvasRenderingContext2D/putImageData">putImageData()</a>. La fonction inversion soustrait simplement chaque couleur de la valeur maximale 255. La fonction grayscale <em>(niveaux de gris)</em> fait simplement la moyenne du rouge, du vert et du bleu. Vous pouvez également utiliser une moyenne pondérée, donnée par la formule x = 0.299r + 0.587v + 0.114b, par exemple. Voir <a href="https://fr.wikipedia.org/wiki/Niveau_de_gris">Niveaux de gris</a> sur Wikipedia pour plus d'informations.</p> + +<div class="hidden"> +<pre class="brush: html; notranslate"><canvas id="canevas" width="300" height="227"></canvas> +<div> + <input id="btnniveaudegris" value="Niveau de gris" type="button"> + <input id="btninversion" value="Inversion" type="button"> +</div> +</pre> +</div> + +<pre class="brush: js notranslate">var img = new Image(); +img.src = 'https://mdn.mozillademos.org/files/5397/rhino.jpg'; +img.onload = function() { + dessiner(this); +}; + +function dessiner(img) { + var canevas = document.getElementById('canevas'); + var ctx = canevas.getContext('2d'); + ctx.drawImage(img, 0, 0); + img.style.display = 'none'; + var imageData = ctx.getImageData(0, 0, canevas.width, canevas.height); + var data = imageData.data; + + var inversion = function() { + for (var i = 0; i < data.length; i += 4) { + data[i] = 255 - data[i]; // rouge + data[i + 1] = 255 - data[i + 1]; // vert + data[i + 2] = 255 - data[i + 2]; // bleu + } + ctx.putImageData(imageData, 0, 0); + }; + + var niveaudegris = function() { + for (var i = 0; i < data.length; i += 4) { + var moy = (data[i] + data[i + 1] + data[i + 2]) / 3; + data[i] = moy; // rouge + data[i + 1] = moy; // vert + data[i + 2] = moy; // bleu + } + ctx.putImageData(imageData, 0, 0); + }; + + var btninversion = document.getElementById('btninversion'); + btninversion.addEventListener('click', inversion); + var btnniveaudegris = document.getElementById('btnniveaudegris'); + btnniveaudegris.addEventListener('click', niveaudegris); +} +</pre> + +<p>{{ EmbedLiveSample('Grayscaling_and_inverting_colors', 330, 270) }}</p> + +<h2 id="Zoom_et_anticrénelage">Zoom et anticrénelage</h2> + +<p><span id="result_box" lang="fr"><span>A l'aide de la méthode {{domxref ("CanvasRenderingContext2D.drawImage", "drawImage ()")}}, un deuxième canevas, et la propriété </span></span> {{domxref("CanvasRenderingContext2D.imageSmoothingEnabled", "imageSmoothingEnabled")}} , nous pouvons<span lang="fr"><span> zoomer sur notre image et voir les détails.</span></span></p> + +<p><span id="result_box" lang="fr"><span>Nous obtenons la position de la souris et recadrons une image de 5 pixels à gauche et au-dessus à 5 pixels à droite et en-dessous.</span> <span>Ensuite, nous copions celle-ci sur un autre canevas et redimensionnons l'image à la taille que nous voulons.</span> <span>Dans la zone de zoom, nous redimensionnons une zone de 10 × 10 pixels du canevas d'origine à 200 × 200.</span></span></p> + +<pre class="brush: js notranslate">zoomctx.drawImage(canvas, + Math.abs(x - 5), Math.abs(y - 5), + 10, 10, 0, 0, 200, 200);</pre> + +<p><span id="result_box" lang="fr"><span>Étant donné que l'anticrénelage est activé par défaut, nous pouvons désactiver le lissage pour voir les pixels clairs.</span> <span>Vous pouvez basculer la case à cocher pour voir l'effet de la propriété <code>imageSmoothingEnabled</code> (qui a besoin de préfixes pour différents navigateurs).</span></span></p> + +<h6 class="hidden" id="Zoom_example">Zoom example</h6> + +<div class="hidden"> +<pre class="brush: html; notranslate"><canvas id="canvas" width="300" height="227"></canvas> +<canvas id="zoom" width="300" height="227"></canvas> +<div> +<label for="smoothbtn"> + <input type="checkbox" name="smoothbtn" checked="checked" id="smoothbtn"> + Enable image smoothing +</label> +</div> +</pre> +</div> + +<pre class="brush: js notranslate">var img = new Image(); +img.src = 'https://mdn.mozillademos.org/files/5397/rhino.jpg'; +img.onload = function() { + draw(this); +}; + +function draw(img) { + var canvas = document.getElementById('canvas'); + var ctx = canvas.getContext('2d'); + ctx.drawImage(img, 0, 0); + img.style.display = 'none'; + var zoomctx = document.getElementById('zoom').getContext('2d'); + + var smoothbtn = document.getElementById('smoothbtn'); + var toggleSmoothing = function(event) { + zoomctx.imageSmoothingEnabled = this.checked; + zoomctx.mozImageSmoothingEnabled = this.checked; + zoomctx.webkitImageSmoothingEnabled = this.checked; + zoomctx.msImageSmoothingEnabled = this.checked; + }; + smoothbtn.addEventListener('change', toggleSmoothing); + + var zoom = function(event) { + var x = event.layerX; + var y = event.layerY; + zoomctx.drawImage(canvas, + Math.abs(x - 5), + Math.abs(y - 5), + 10, 10, + 0, 0, + 200, 200); + }; + + canvas.addEventListener('mousemove', zoom); +}</pre> + +<p>{{ EmbedLiveSample('Zoom_example', 620, 490) }}</p> + +<h2 id="Sauvegarde_des_images">Sauvegarde des images</h2> + +<p><span id="result_box" lang="fr"><span>L' {{domxref ("HTMLCanvasElement")}} fournit une méthode <code>toDataURL ()</code>, utile lors de l'enregistrement d'images.</span> <span>Il retourne un <a href="https://developer.mozilla.org/fr/docs/Web/HTTP/Basics_of_HTTP/Data_URIs">URI de données</a> contenant une représentation de l'image dans le format spécifié par le paramètre de <code>type</code> (par défaut en </span></span> <a class="external external-icon" href="https://en.wikipedia.org/wiki/Portable_Network_Graphics">PNG</a> <span lang="fr"><span>).</span> <span>L'image renvoyée est dans une résolution de 96 dpi.</span></span></p> + +<dl> + <dt>{{domxref("HTMLCanvasElement.toDataURL", "canvas.toDataURL('image/png')")}}</dt> + <dd>Par défaut. Crée un image PNG.</dd> + <dt>{{domxref("HTMLCanvasElement.toDataURL", "canvas.toDataURL('image/jpeg', quality)")}}</dt> + <dd><span id="result_box" lang="fr"><span>Crée une image JPG.</span> <span>En option, vous pouvez fournir une qualité comprise entre 0 et 1, 1 étant de la meilleure qualité et 0 presque non reconnaissable mais de petite taille.</span></span></dd> +</dl> + +<p><span id="result_box" lang="fr"><span>Une fois que vous avez généré un URI de données à partir de votre canevas, vous pouvez l'utiliser comme source de {{HTMLElement ("image")}} ou le mettre dans un lien hypertexte avec un attribut de téléchargement pour l'enregistrer sur le disque par exemple.</span></span></p> + +<p><span id="result_box" lang="fr"><span>Vous pouvez également créer un {{domxref ("Blob")}} à partir du canevas.</span></span></p> + +<dl> + <dt>{{domxref("HTMLCanvasElement.toBlob", "canvas.toBlob(callback, type, encoderOptions)")}}</dt> + <dd><span id="result_box" lang="fr"><span>Crée un objet <code>Blob</code> représentant l'image contenue dans le canevas.</span></span></dd> +</dl> + +<h2 id="Voir_aussi">Voir aussi</h2> + +<ul> + <li>{{domxref("ImageData")}}</li> + <li><a href="https://developer.mozilla.org/fr/docs/HTML/Manipulating_video_using_canvas">Manipulating video using canvas</a></li> + <li><a href="https://codepo8.github.io/canvas-images-and-pixels/">Canevas, images et pixels – par Christian Heilmann (en)</a></li> +</ul> + +<p>{{PreviousNext("Tutoriel_canvas/Advanced_animations", "Web/API/Canvas_API/Tutorial/Hit_regions_and_accessibility")}}</p> diff --git a/files/fr/web/api/canvas_api/tutoriel_canvas/transformations/index.html b/files/fr/web/api/canvas_api/tutoriel_canvas/transformations/index.html new file mode 100644 index 0000000000..bf21fab4c8 --- /dev/null +++ b/files/fr/web/api/canvas_api/tutoriel_canvas/transformations/index.html @@ -0,0 +1,276 @@ +--- +title: Transformations +slug: Web/API/Canvas_API/Tutoriel_canvas/Transformations +tags: + - Canvas + - Graphismes + - Guide + - HTML + - Web +translation_of: Web/API/Canvas_API/Tutorial/Transformations +--- +<div>{{CanvasSidebar}} {{PreviousNext("Tutoriel_canvas/Utilisation_d'images", " Web/API/Canvas_API/Tutorial/Compositing ")}}</div> + +<div class="summary">Précédemment dans ce tutoriel, nous avons étudié la <a href="https://developer.mozilla.org/fr/docs/Tutoriel_canvas/Formes_g%C3%A9om%C3%A9triques">grille du canevas</a> et le <strong>système de coordonnées</strong>. Jusqu'à maintenant, nous avons uniquement utilisé la grille par défaut et modifié la taille de la globalité du canevas afin de répondre à nos besoins. Les transformations que nous allons aborder dans la suite vont nous permettre, de manière plus puissante, d'effectuer des déplacements et des rotations sur la grille et même d'effectuer des mises à l'échelle.</div> + +<h2 id="Sauvegarde_et_restauration_détat">Sauvegarde et restauration d'état</h2> + +<p>Avant d'étudier les méthodes de transformations, examinons deux autres méthodes qui vont être indispensables à partir du moment où l'on commence à créer des dessins complexes.</p> + +<dl> + <dt>{{domxref("CanvasRenderingContext2D.save", "save()")}}</dt> + <dd>Sauvegarde l'état du canevas dans sa globalité.</dd> + <dt>{{domxref("CanvasRenderingContext2D.restore", "restore()")}}</dt> + <dd>Restore le plus récent état sauvegardé du canevas.</dd> +</dl> + +<p>Les états du canevas sont stockés dans une pile. Chaque invocation de la méthode <code>save() </code>ajoute une copie de l'état courant du canevas en haut de la pile. L'état du dessin est constitué de :</p> + +<ul> + <li>les transformations qui ont été appliquées (exemples : déplacement, rotation, mise à l'échelle).</li> + <li>Les valeurs actuelles des attributs suivants : {{domxref("CanvasRenderingContext2D.strokeStyle", "strokeStyle")}}, {{domxref("CanvasRenderingContext2D.fillStyle", "fillStyle")}}, {{domxref("CanvasRenderingContext2D.globalAlpha", "globalAlpha")}}, {{domxref("CanvasRenderingContext2D.lineWidth", "lineWidth")}}, {{domxref("CanvasRenderingContext2D.lineCap", "lineCap")}}, {{domxref("CanvasRenderingContext2D.lineJoin", "lineJoin")}}, {{domxref("CanvasRenderingContext2D.miterLimit", "miterLimit")}}, {{domxref("CanvasRenderingContext2D.lineDashOffset", "lineDashOffset")}}, {{domxref("CanvasRenderingContext2D.shadowOffsetX", "shadowOffsetX")}}, {{domxref("CanvasRenderingContext2D.shadowOffsetY", "shadowOffsetY")}}, {{domxref("CanvasRenderingContext2D.shadowBlur", "shadowBlur")}}, {{domxref("CanvasRenderingContext2D.shadowColor", "shadowColor")}}, {{domxref("CanvasRenderingContext2D.globalCompositeOperation", "globalCompositeOperation")}}, {{domxref("CanvasRenderingContext2D.font", "font")}}, {{domxref("CanvasRenderingContext2D.textAlign", "textAlign")}}, {{domxref("CanvasRenderingContext2D.textBaseline", "textBaseline")}}, {{domxref("CanvasRenderingContext2D.direction", "direction")}}, {{domxref("CanvasRenderingContext2D.imageSmoothingEnabled", "imageSmoothingEnabled")}}.</li> + <li>Le chemin de découpe (<a href="/en-US/docs/Web/API/Canvas_API/Tutorial/Compositing#Clipping_paths">clipping path</a>) actuel, qu'on abordera plus loin.</li> +</ul> + +<p>La méthode <code>save()</code> peut être invoquée autant de fois que nécessaire. Chaque appel de <code>restore()</code> enlève le dernier état sauvegardé de la pile et tous les paramètres sauvegardés sont restaurés.</p> + +<h3 id="Un_exemple_de_sauvegarde_et_de_restauration_de_l_état_du_canevas">Un exemple de sauvegarde et de restauration de l état du canevas</h3> + +<p>Cet exemple tente d'illustrer comment fonctionne la pile d'états de dessin en dessinant un ensemble de rectangles consécutifs.</p> + +<pre class="brush: js; highlight:[5,10,15,18] notranslate">function draw() { + var ctx = document.getElementById('canvas').getContext('2d'); + + ctx.fillRect(0, 0, 150, 150); // Dessine un rectangle avec les réglages par défaut + ctx.save(); // Sauvegarde l'état par défaut + + ctx.fillStyle = '#09F'; // Fait des changements de réglages + ctx.fillRect(15, 15, 120, 120); // Dessine un rectangle avec les nouveaux réglages + + ctx.save(); // Sauvegarde l'état actuel + ctx.fillStyle = '#FFF'; // Fait des changements de réglages + ctx.globalAlpha = 0.5; + ctx.fillRect(30, 30, 90, 90); // Dessine un rectangle avec de nouveaux réglages + + ctx.restore(); // Restaure l'état précédent + ctx.fillRect(45, 45, 60, 60); // Dessine un rectangle avec les réglages restaurés + + ctx.restore(); // Restaure l'état d'origine + ctx.fillRect(60, 60, 30, 30); // Dessine un rectangle avec les réglages restaurés +}</pre> + +<div class="hidden"> +<pre class="brush: html notranslate"><canvas id="canvas" width="150" height="150"></canvas></pre> + +<pre class="brush: js notranslate">draw();</pre> +</div> + +<p>La première étape consiste à dessiner un grand rectangle avec les paramètres par défaut. Ensuite, nous sauvegardons cet état et modifions la couleur de remplissage. Nous dessinons ensuite le deuxième rectangle bleu et mettons l'état de côté. Encore une fois, nous modifions certains paramètres de dessin et dessinons le troisième rectangle blanc semi-transparent.</p> + +<p>Jusqu'à présent, cela ressemble beaucoup à ce que nous avons fait dans les sections précédentes. Cependant, une fois que nous appelons la première instruction <code>restore()</code>, l'état de dessin supérieur est supprimé de la pile et les paramètres sont restaurés. Si nous n'avions pas sauvegardé l'état en utilisant <code>save ()</code>, nous devrions modifier manuellement la couleur de remplissage et la transparence afin de revenir à l'état précédent. Cela serait facile pour deux propriétés, mais si nous avons plus que cela, notre code deviendrait très long très rapidement.</p> + +<p>Lorsque la deuxième instruction <code>restore()</code> est appelée, l'état d'origine (celui que nous avons configuré avant le premier appel à enregistrer) est restauré et le dernier rectangle est de nouveau tracé en noir.</p> + +<p>{{EmbedLiveSample("Un_exemple_de_sauvegarde_et_de_restauration_de_l_état_du_canevas", "180", "180", "https://mdn.mozillademos.org/files/249/Canvas_savestate.png")}}</p> + +<h2 id="Déplacement">Déplacement</h2> + +<p><img alt="" class="internal" src="https://mdn.mozillademos.org/files/234/Canvas_grid_translate.png" style="float: right;"> La première des méthodes de transformation que nous examinerons est <code>translate ()</code>. Cette méthode est utilisée pour déplacer la toile et son origine vers un autre point de la grille.</p> + +<dl> + <dt>{{domxref("CanvasRenderingContext2D.translate", "translate(x, y)")}}</dt> + <dd>Déplace la toile et son origine sur la grille. <code>x</code> indique la distance horizontale du déplacement, et <code>y</code> indique à quelle distance déplacer la grille verticalement.</dd> +</dl> + +<p>C'est une bonne idée de sauvegarder l'état du canevas avant d'effectuer des transformations. Dans la plupart des cas, il est plus facile d'appeler la méthode <code>restore</code> que d'avoir à effectuer un déplacement inverse pour revenir à l'état d'origine. De même, si vous déplacez à l'intérieur d'une boucle et que vous ne sauvegardez pas et ne restaurez pas l'état du canevas, il se peut qu'une partie de votre dessin soit manquante, car elle a été dessinée en dehors du bord du canevas.</p> + +<h3 id="Un_exemple_translate">Un exemple <code>translate</code></h3> + +<p>Cet exemple montre certains des avantages du déplacement de l'origine du canevas. Sans la méthode<code> translate ()</code>, tous les rectangles seraient dessinés à la même position (0,0). La méthode <code>translate ()</code> nous donne également la liberté de placer le rectangle n'importe où sur le canevas sans avoir à ajuster manuellement les coordonnées dans la fonction <code>fillRect ()</code>. Cela le rend un peu plus facile à comprendre et à utiliser.</p> + +<p>Dans la fonction <code>draw ()</code>, nous appelons la fonction <code>fillRect ()</code> neuf fois en utilisant deux boucles <code>for</code> . Dans chaque boucle, le canevas est déplacé, le rectangle est dessiné et le canevas est retourné à son état d'origine. Notez comment l'appel à <code>fillRect ()</code> utilise les mêmes coordonnées à chaque fois, en s'appuyant sur <code>translate ()</code> pour ajuster la position du dessin.</p> + +<pre class="brush: js; highlight:[7] language-js notranslate">function draw() { + var ctx = document.getElementById('canvas').getContext('2d'); + for (var i = 0; i < 3; i++) { + for (var j = 0; j < 3; j++) { + ctx.save(); + ctx.fillStyle = 'rgb(' + (51 * i) + ', ' + (255 - 51 * i) + ', 255)'; + ctx.translate(10 + j * 50, 10 + i * 50); + ctx.fillRect(0, 0, 25, 25); + ctx.restore(); + } + } +}</pre> + +<div class="hidden"> +<pre class="brush: html notranslate"><canvas id="canvas" width="150" height="150"></canvas></pre> + +<pre class="brush: js notranslate">draw();</pre> +</div> + +<p>{{EmbedLiveSample("Un_exemple_translate", "160", "160", "https://mdn.mozillademos.org/files/9857/translate.png")}}</p> + +<h2 id="Rotation">Rotation</h2> + +<p><img alt="" class="internal" src="https://mdn.mozillademos.org/files/233/Canvas_grid_rotate.png" style="float: right;">La seconde méthode de transformation est <code>rotate()</code>. Nous l'utilisons pour faire pivoter le canevas autour de l'origine actuelle.</p> + +<dl> + <dt>{{domxref("CanvasRenderingContext2D.rotate", "rotate(angle)")}}</dt> + <dd>Fait pivoter le canevas, dans le sens des aiguilles d'une montre autour de l'origine actuelle, par le nombre de radians de l'angle.</dd> +</dl> + +<p>Le point central de rotation est toujours l'origine de la toile. Pour changer le point central, nous devrons déplacer le canevas en utilisant la méthode <code>translate ()</code>.</p> + +<h3 id="Un_exemple_rotate">Un exemple <code>rotate</code></h3> + +<p>Dans cet exemple, nous utiliserons la méthode <code>rotate ()</code> pour faire d'abord tourner un rectangle à partir de l'origine du canevas, puis du centre du rectangle lui-même à l'aide de <code>translate ()</code>.</p> + +<div class="note"> +<p><strong>Rappel :</strong> Les angles sont en radians, pas en degrés. Pour convertir en degrés, nous utilisons : <code>radians = (Math.PI/180)*degrees</code>.</p> +</div> + +<pre class="brush: js; highlight:[9, 23] notranslate">function draw() { + var ctx = document.getElementById('canvas').getContext('2d'); + + // rectangles de gauche, rotation depuis l'origine du canevas + ctx.save(); + // rectangle bleu + ctx.fillStyle = '#0095DD'; + ctx.fillRect(30, 30, 100, 100); + ctx.rotate((Math.PI / 180) * 25); + // rectangle gris + ctx.fillStyle = '#4D4E53'; + ctx.fillRect(30, 30, 100, 100); + ctx.restore(); + + // rectangles de droite, rotation depuis le centre du rectangle + // dessine le rectangle bleu + ctx.fillStyle = '#0095DD'; + ctx.fillRect(150, 30, 100, 100); + + ctx.translate(200, 80); // déplace au centre du rectangle + // x = x + 0.5 * width + // y = y + 0.5 * height + ctx.rotate((Math.PI / 180) * 25); // rotation + ctx.translate(-200, -80); // déplace en arrière + + // dessine le rectangle gris + ctx.fillStyle = '#4D4E53'; + ctx.fillRect(150, 30, 100, 100); +}</pre> + +<p>Pour faire pivoter le rectangle autour de son propre centre, nous déplaçons le canevas au centre du rectangle, puis faisons pivoter le canevas, puis le déplaçons à 0,0, puis dessinons le rectangle.</p> + +<div class="hidden"> +<pre class="brush: html line-numbers notranslate"><canvas id="canvas" width="300" height="200"></canvas></pre> + +<pre class="brush: js notranslate">draw();</pre> +</div> + +<p>{{EmbedLiveSample("Un_exemple_rotate", "310", "210", "https://mdn.mozillademos.org/files/9859/rotate.png")}}</p> + +<h2 id="Mise_à_léchelle">Mise à l'échelle</h2> + +<p>La méthode de transformation suivante est la mise à l'échelle. Nous l'utilisons pour augmenter ou diminuer les unités de notre grille de canevas. Cela peut être utilisé pour dessiner des formes ou des bitmaps réduits ou agrandis.</p> + +<dl> + <dt>{{domxref("CanvasRenderingContext2D.scale", "scale(x, y)")}}</dt> + <dd>Met à l'échelle les unités du canevas avec x horizontalement et y verticalement. Les deux paramètres sont des nombres réels. Les valeurs inférieures à 1,0 réduisent la taille de l'unité et les valeurs supérieures à 1,0 augmentent la taille de l'unité. Les valeurs 1.0 laissent les unités à la même taille.</dd> +</dl> + +<p>En utilisant des nombres négatifs, vous pouvez faire une mise en miroir d'axe (par exemple en utilisant <code>translate (0, canvas.height), scale (1, -1)</code>, vous aurez le système de coordonnées cartésien bien connu, avec l'origine dans le coin inférieur gauche).</p> + +<p>Par défaut, une unité sur la toile est exactement un pixel. Si nous appliquons, par exemple, un facteur d'échelle de 0,5, l'unité résultante deviendrait 0,5 pixels et ainsi les formes seraient dessinées à la moitié de la taille. De la même façon, si nous définissons le facteur d'échelle sur 2.0, la taille de l'unité augmentera et une unité deviendra deux pixels. Cela donne des formes dessinées deux fois plus grandes.</p> + +<h3 id="Un_exemple_scale">Un exemple <code>scale</code></h3> + +<p>Dans ce dernier exemple, nous allons dessiner des formes avec différents facteurs d'échelle.</p> + +<pre class="brush: js; highlight:[6,11] notranslate">function draw() { + var ctx = document.getElementById('canvas').getContext('2d'); + + // dessine un rectangle simple, mais le met à l'échelle. + ctx.save(); + ctx.scale(10, 3); + ctx.fillRect(1, 10, 10, 10); + ctx.restore(); + + // mirror horizontally + ctx.scale(-1, 1); + ctx.font = '48px serif'; + ctx.fillText('MDN', -135, 120); +}</pre> + +<div class="hidden"> +<pre class="brush: html notranslate"><canvas id="canvas" width="150" height="150"></canvas></pre> + +<pre class="brush: js line-numbers language-js notranslate">draw();</pre> +</div> + +<p>{{EmbedLiveSample("Un_exemple_scale", "160", "160", "https://mdn.mozillademos.org/files/9861/scale.png")}}</p> + +<h2 id="Transformation">Transformation</h2> + +<p>Enfin, les méthodes de transformation suivantes appliquent des modifications directement à la matrice de transformation.</p> + +<dl> + <dt>{{domxref("CanvasRenderingContext2D.transform", "transform(a, b, c, d, e, f)")}}</dt> + <dd>Multiplie la matrice de transformation actuelle avec la matrice décrite par ses arguments. La matrice de transformation est décrite par : <math><semantics><mrow><mo>[</mo><mtable columnalign="center center center" rowspacing="0.5ex"><mtr><mtd><mi>a</mi></mtd><mtd><mi>c</mi></mtd><mtd><mi>e</mi></mtd></mtr><mtr><mtd><mi>b</mi></mtd><mtd><mi>d</mi></mtd><mtd><mi>f</mi></mtd></mtr><mtr><mtd><mn>0</mn></mtd><mtd><mn>0</mn></mtd><mtd><mn>1</mn></mtd></mtr></mtable><mo>]</mo></mrow><annotation encoding="TeX">\left[ \begin{array}{ccc} a & c & e \\ b & d & f \\ 0 & 0 & 1 \end{array} \right]</annotation></semantics></math></dd> +</dl> + +<dl> + <dd>Si l'un des arguments est <code>infini</code>, la matrice de transformation doit être marquée comme infinie, plutôt que d'utiliser la méthode qui lance une exception.</dd> +</dl> + +<p>Les paramètres de cette fonction sont :</p> + +<dl> + <dt><code>a (m11)</code></dt> + <dd>Mise à l'échelle horizontale.</dd> + <dt><em><code>b (m12)</code></em></dt> + <dd>Inclinaison horizontale.</dd> + <dt><code>c (m21)</code></dt> + <dd>Inclinaison verticale.</dd> + <dt><code>d (m22)</code></dt> + <dd>Mise à l'échelle verticale.</dd> + <dt><code>e (dx)</code></dt> + <dd>Déplacement horizontal.</dd> + <dt><code>f (dy)</code></dt> + <dd>Déplacement vertical.</dd> + <dt>{{domxref("CanvasRenderingContext2D.setTransform", "setTransform(a, b, c, d, e, f)")}}</dt> + <dd>Réinitialise la transformation en cours dans la matrice d'identité, puis appelle la méthode <code>transform ()</code> avec les mêmes arguments. Cela défait la transformation en cours, puis définit la transformation spécifiée, le tout en une seule étape.</dd> + <dt>{{domxref("CanvasRenderingContext2D.resetTransform", "resetTransform()")}}</dt> + <dd>Réinitialise la transformation en cours à la matrice d'identité. C'est la même chose que d'appeler : <code>ctx.setTransform (1, 0, 0, 1, 0, 0)</code>;</dd> +</dl> + +<h3 id="Exemple_pour_transform_et_setTransform">Exemple pour <code>transform</code> et <code>setTransform</code></h3> + +<pre class="brush: js; highlight:[12,15] notranslate">function draw() { + var ctx = document.getElementById('canvas').getContext('2d'); + + var sin = Math.sin(Math.PI / 6); + var cos = Math.cos(Math.PI / 6); + ctx.translate(100, 100); + var c = 0; + for (var i = 0; i <= 12; i++) { + c = Math.floor(255 / 12 * i); + ctx.fillStyle = 'rgb(' + c + ', ' + c + ', ' + c + ')'; + ctx.fillRect(0, 0, 100, 10); + ctx.transform(cos, sin, -sin, cos, 0, 0); + } + + ctx.setTransform(-1, 0, 0, 1, 100, 100); + ctx.fillStyle = 'rgba(255, 128, 255, 0.5)'; + ctx.fillRect(0, 50, 100, 100); +}</pre> + +<div class="hidden"> +<pre class="brush: html notranslate"><canvas id="canvas" width="200" height="250"></canvas></pre> + +<pre class="brush: js notranslate">draw();</pre> +</div> + +<p>{{EmbedLiveSample("Exemple_pour_transform_et_setTransform", "230", "280", "https://mdn.mozillademos.org/files/255/Canvas_transform.png")}}</p> + +<p>{{PreviousNext("Tutoriel_canvas/Utilisation_d'images", "Tutoriel_canvas/Composition")}}</p> diff --git a/files/fr/web/api/canvas_api/tutoriel_canvas/utilisation_d'images/index.html b/files/fr/web/api/canvas_api/tutoriel_canvas/utilisation_d'images/index.html new file mode 100644 index 0000000000..50a286e0fa --- /dev/null +++ b/files/fr/web/api/canvas_api/tutoriel_canvas/utilisation_d'images/index.html @@ -0,0 +1,320 @@ +--- +title: Utilisation d'images +slug: Web/API/Canvas_API/Tutoriel_canvas/Utilisation_d'images +tags: + - Canvas + - Graphismes + - HTML + - Tutoriels +translation_of: Web/API/Canvas_API/Tutorial/Using_images +--- +<p>{{CanvasSidebar}} {{PreviousNext("Dessin_de_texte_avec_canvas", "Tutoriel_canvas/Transformations" )}}</p> + +<p class="summary">Jusqu'à présent, nous avons créé nos propres <a href="https://developer.mozilla.org/fr/docs/Tutoriel_canvas/Formes_g%C3%A9om%C3%A9triques">formes</a> et <a href="https://developer.mozilla.org/fr/docs/Tutoriel_canvas/Ajout_de_styles_et_de_couleurs">styles appliqués</a>. L'une des fonctionnalités les plus intéressantes de {{HTMLElement ("canvas")}} est la possibilité d'utiliser des images. Celles-ci peuvent être utilisées pour faire de la composition dynamique de photos ou comme décors de graphes, pour des "sprites" dans des jeux, et ainsi de suite. Les images externes peuvent être utilisées dans n'importe quel format pris en charge par le navigateur, comme PNG, GIF ou JPEG. Vous pouvez même utiliser l'image produite par d'autres éléments du canevas sur la même page comme source !</p> + +<p>L'importation d'images est un processus en deux étapes :</p> + +<ol> + <li><span id="result_box" lang="fr"><span>obtenez une référence à un objet {{domxref ("HTMLImageElement")}} ou à un autre élément canvas en tant que source.</span> <span>Il est également possible d'utiliser des images en fournissant une URL.</span></span></li> + <li>l'image est dessinée sur le canevas à l'aide de la fonction <code>drawImage()</code> .</li> +</ol> + +<p><span class="short_text" id="result_box" lang="fr"><span>Jetons un oeil à la façon de le faire.</span></span></p> + +<h2 id="Obtenir_des_images_à_dessiner"><span class="short_text" id="result_box" lang="fr"><span>Obtenir des images à dessiner</span></span></h2> + +<p><span id="result_box" lang="fr"><span>L'API Canvas peut utiliser l'un des types de données suivants comme source d'image :</span></span></p> + +<dl> + <dt>{{domxref("HTMLImageElement")}}</dt> + <dd><span id="result_box" lang="fr"><span>Il s'agit d'images créées à l'aide du constructeur </span></span> <code>Image()</code> <span lang="fr"><span>, ainsi que de tout élément {{HTMLElement ("img")}}.</span></span></dd> + <dt>{{domxref("SVGImageElement")}}</dt> + <dd><span id="result_box" lang="fr"><span>Ce sont des images incorporées en utilisant l'élément {{SVGElement ("image")}}.</span></span></dd> + <dt>{{domxref("HTMLVideoElement")}}</dt> + <dd><span id="result_box" lang="fr"><span>L'utilisation d'un élément HTML </span></span> {{HTMLElement("video")}} <span lang="fr"><span> comme source d'image capture l'image actuelle de la vidéo et l'utilise comme une image.</span></span></dd> + <dt>{{domxref("HTMLCanvasElement")}}</dt> + <dd><span id="result_box" lang="fr"><span>Vous pouvez utiliser un autre élément </span></span> {{HTMLElement("canvas")}} <span lang="fr"><span> comme source d'image.</span></span></dd> +</dl> + +<p><span id="result_box" lang="fr"><span>Ces sources sont collectivement référencées par le type {{domxref ("CanvasImageSource")}}.</span></span></p> + +<p><span id="result_box" lang="fr"><span>Il existe plusieurs façons d'obtenir des images pour une utilisation sur une toile.</span></span></p> + +<h3 id="Utilisation_d.27images_pr.C3.A9sentes_sur_la_m.C3.AAme_page" name="Utilisation_d.27images_pr.C3.A9sentes_sur_la_m.C3.AAme_page">Utilisation d'images présentes sur la même page</h3> + +<p><span id="result_box" lang="fr"><span>Nous pouvons obtenir une référence aux images sur la même page que le canevas en utilisant l'un des éléments suivants :</span></span></p> + +<ul> + <li>la collection {{domxref("document.images")}} ;</li> + <li>la méthode {{domxref("document.getElementsByTagName()")}} ;</li> + <li>si vous connaissez l'ID de l'image spécifique que vous souhaitez utiliser, vous pouvez utiliser {{domxref("document.getElementById()")}} pour retrouver cette image.</li> +</ul> + +<h3 id="Utilisation_dimages_dun_autre_domaine"><span lang="fr"><span>Utilisation d'images d'un autre domaine</span></span></h3> + +<p><span id="result_box" lang="fr"><span>En utilisant l'attribut {{htmlattrxref ("crossorigin", "img")}} d'un élément {{HTMLElement ("img")}} (reflété par la propriété </span></span> {{domxref("HTMLImageElement.crossOrigin")}}), vous <span lang="fr"> <span>pouvez demander la permission de charger une image d'un autre domaine pour l'utiliser dans votre appel à <code>drawImage ()</code>.</span> <span>Si le domaine d'hébergement permet un accès interdomaine à l'image, l'image peut être utilisée dans votre canevas sans l'altérer;</span> <span>sinon utiliser l'image va <a href="https://developer.mozilla.org/fr/docs/Web/HTML/Images_avec_le_contr%C3%B4le_d_acc%C3%A8s_HTTP#What_is_a_.22tainted.22_canvas.3F">souiller le canevas</a>.</span></span></p> + +<h3 id="Utilisation_d.27autres_.C3.A9l.C3.A9ments_canvas" name="Utilisation_d.27autres_.C3.A9l.C3.A9ments_canvas">Utilisation d'autres éléments canvas</h3> + +<p><span id="result_box" lang="fr"><span>Comme pour les images normales, nous accédons aux autres éléments Canvas en utilisant la méthode {{domxref ("document.getElementsByTagName ()")}} ou {{domxref ("document.getElementById ()")}}.</span> <span>Assurez-vous d'avoir dessiné quelque chose sur le canevas source avant de l'utiliser dans votre canevas cible.</span></span></p> + +<p>Une des utilisations les plus pratiques de cette fonctionnalité serait d'utiliser un second élément canvas comme aperçu de taille réduite d'un canevas de grande taille.</p> + +<h3 id="Cr.C3.A9ation_d.27une_image_.C3.A0_partir_de_rien" name="Cr.C3.A9ation_d.27une_image_.C3.A0_partir_de_rien">Création d'une image à partir de rien</h3> + +<p>Une autre option est de créer de nouveaux objets {{domxref("HTMLImageElement")}} dans le script même. Pour ce faire, vous pouvez utiliser le constructeur <code>Image().</code></p> + +<pre class="eval notranslate">var img = new Image(); // Crée un nouvel élément Image +img.src = 'myImage.png'; // Définit le chemin vers sa source +</pre> + +<p>Lorsque ce script est exécuté, l'image commence à être chargée.</p> + +<p><span id="result_box" lang="fr"><span>Si vous essayez d'appeler <code>drawImage ()</code> avant le chargement de l'image, il ne fera rien (ou, dans les anciens navigateurs, cela peut même déclencher une exception).</span> <span>Vous devez donc être sûr d'utiliser l'événement <code>load</code> pour ne pas essayer avant que l'image ne soit chargée :</span></span></p> + +<pre class="brush: js line-numbers language-js notranslate"><code class="language-js"><span class="keyword token">var</span> img <span class="operator token">=</span> <span class="keyword token">new</span> <span class="class-name token">Image</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// Crée un nouvel élément img</span> +img<span class="punctuation token">.</span><span class="function token">addEventListener</span><span class="punctuation token">(</span><span class="string token">'load'</span><span class="punctuation token">,</span> <span class="keyword token">function</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="comment token">// </span></code> <span class="short_text" id="result_box" lang="fr"><span>exécute les instructions drawImage ici</span></span> <code class="language-js"> +<span class="punctuation token">}</span><span class="punctuation token">,</span> <span class="keyword token">false</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +img<span class="punctuation token">.</span>src <span class="operator token">=</span> <span class="string token">'myImage.png'</span><span class="punctuation token">;</span> <span class="comment token">// définit le chemin de la source</span></code></pre> + +<p><span id="result_box" lang="fr"><span>Si vous n'utilisez qu'une image externe, cela peut être une bonne approche, mais une fois que vous avez besoin de suivre plus d'une image, vous devez recourir à quelque chose de plus intelligent.</span> <span>Il est hors de portée de ce tutoriel de regarder les tactiques de préchargement d'images, mais vous devriez garder cela à l'esprit.</span></span></p> + +<h4 id="Int.C3.A9gration_d.27une_image_via_une_URL_data" name="Int.C3.A9gration_d.27une_image_via_une_URL_data:">Intégration d'une image via une data: URL</h4> + +<p><span id="result_box" lang="fr"><span>Un autre moyen possible d'inclure des images est via les </span></span> <a class="external external-icon" href="https://developer.mozilla.org/en-US/docs/Web/HTTP/data_URIs" rel="external" title="http://en.wikipedia.org/wiki/Data:_URL">data: url.</a><a href="https://developer.mozilla.org/fr/docs/Web/HTTP/Basics_of_HTTP/Data_URIs">.</a> <span lang="fr"><span>.</span> <span>Les URL de données vous permettent de définir complètement une image en tant que chaîne de caractères codée en Base64 directement dans votre code.</span></span></p> + +<pre class="brush: js line-numbers language-js notranslate"><code class="language-js"><span class="keyword token">var</span> img <span class="operator token">=</span> <span class="keyword token">new</span> <span class="class-name token">Image</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// Crée un nouvel élément img</span> +img<span class="punctuation token">.</span>src <span class="operator token">=</span> <span class="string token">'data:image/gif;base64,R0lGODlhCwALAIAAAAAA3pn/ZiH5BAEAAAEALAAAAAALAAsAAAIUhA+hkcuO4lmNVindo7qyrIXiGBYAOw=='</span><span class="punctuation token">;</span></code></pre> + +<p><span id="result_box" lang="fr"><span>L'un des avantages des URL de données est que l'image résultante est disponible immédiatement, sans autre aller-retour au serveur.</span> <span>Un autre avantage potentiel,'il est également possible d'encapsuler dans un fichier tous vos </span></span> <a href="https://developer.mozilla.org/fr/docs/Web/CSS" title="/en-US/docs/Web/CSS">CSS</a>, <a href="https://developer.mozilla.org/fr/docs/Web/JavaScript" title="/en-US/docs/Web/JavaScript">JavaScript</a>, <a href="https://developer.mozilla.org/fr/docs/Web/HTML" title="/en-US/docs/Web/HTML">HTML</a> <span lang="fr"><span> et images, ce qui les rend plus portable vers d'autres endroits.</span></span></p> + +<p><span id="result_box" lang="fr"><span>Certains inconvénients de cette méthode sont que votre image n'est pas mise en cache, et pour les grandes images, l'URL encodée peut devenir assez longue.</span></span></p> + +<h3 id="drawImage" name="drawImage"><span class="short_text" id="result_box" lang="fr"><span>Utilisation des images d'une vidéo</span></span></h3> + +<p><span id="result_box" lang="fr"><span>Vous pouvez également utiliser les images d'une vidéo présentée par un élément </span></span> {{HTMLElement("video")}} <span lang="fr"><span> (même si la vidéo n'est pas visible).</span> <span>Par exemple, si vous avez un élément </span></span> {{HTMLElement("video")}} <span lang="fr"><span> avec l'ID "myvideo", vous pouvez faire :</span></span></p> + +<pre class="brush: js line-numbers language-js notranslate"><code class="language-js"><span class="keyword token">function</span> <span class="function token">getMyVideo</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> canvas <span class="operator token">=</span> document<span class="punctuation token">.</span><span class="function token">getElementById</span><span class="punctuation token">(</span><span class="string token">'canvas'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">if</span> <span class="punctuation token">(</span>canvas<span class="punctuation token">.</span>getContext<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> ctx <span class="operator token">=</span> canvas<span class="punctuation token">.</span><span class="function token">getContext</span><span class="punctuation token">(</span><span class="string token">'2d'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="keyword token">return</span> document<span class="punctuation token">.</span><span class="function token">getElementById</span><span class="punctuation token">(</span><span class="string token">'myvideo'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> +<span class="punctuation token">}</span></code></pre> + +<p><span id="result_box" lang="fr"><span>Cela renvoie l'objet {{domxref ("HTMLVideoElement")}} pour la vidéo, qui, comme décrit précédemment, est l'un des objets pouvant être utilisé comme <code>CanvasImageSource</code>.</span></span></p> + +<h2 id="drawImage" name="drawImage">Dessin d'images</h2> + +<p>Une fois la référence à l'objet image source obtenue, on peut utiliser la méthode <code>drawImage()</code> pour l'afficher sur le canevas. Comme nous le verrons plus tard, la méthode <code>drawImage()</code> est surchargée et possède trois variantes différentes. Dans sa forme la plus basique, elle ressemble à ceci :</p> + +<dl> + <dt>{{domxref("CanvasRenderingContext2D.drawImage", "drawImage(image, x, y)")}}</dt> + <dd><span id="result_box" lang="fr"><span>Dessine le <code>CanvasImageSource</code> spécifié par le paramètre <code>image</code> aux coordonnées (<code>x</code>, <code>y</code>).</span></span></dd> +</dl> + +<div class="note"> +<p><span id="result_box" lang="fr"><span>Les images SVG doivent spécifier une largeur et une hauteur dans l'élément racine <svg>.</span></span></p> +</div> + +<h4 id="Example_A_simple_line_graph" name="Example_A_simple_line_graph">Exemple: un graphique linéaire simple</h4> + +<p>Dans l'exemple suivant, nous utiliserons une image externe comme fond pour un petit graphique linéaire. L'utilisation d'images de fond peut rendre vos scripts considérablement plus légers puisqu'il n'est alors pas nécessaire de dessiner des arrières-plans élaborés. Une seule image est utilisée ici, on utilise donc le gestionnaire d'évènement <code>load</code> de l'objet image pour lancer les instructions de dessin. La méthode <code>drawImage()</code> place l'image de fond aux coordonnées (0,0), soit le coin supérieur gauche du canevas.</p> + +<pre class="brush: html line-numbers language-html notranslate"><code class="language-html"><span class="tag token"><span class="tag token"><span class="punctuation token"><</span>html</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>body</span> <span class="attr-name token">onload</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>draw();<span class="punctuation token">"</span></span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>canvas</span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>canvas<span class="punctuation token">"</span></span> <span class="attr-name token">width</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>180<span class="punctuation token">"</span></span> <span class="attr-name token">height</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>150<span class="punctuation token">"</span></span><span class="punctuation token">></span></span><span class="tag token"><span class="tag token"><span class="punctuation token"></</span>canvas</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>body</span><span class="punctuation token">></span></span> +<span class="tag token"><span class="tag token"><span class="punctuation token"></</span>html</span><span class="punctuation token">></span></span></code></pre> + +<pre class="brush: js;highlight[5] line-numbers language-js notranslate"><code class="language-js"><span class="keyword token">function</span> <span class="function token">draw</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> ctx <span class="operator token">=</span> document<span class="punctuation token">.</span><span class="function token">getElementById</span><span class="punctuation token">(</span><span class="string token">'canvas'</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">getContext</span><span class="punctuation token">(</span><span class="string token">'2d'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">var</span> img <span class="operator token">=</span> <span class="keyword token">new</span> <span class="class-name token">Image</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + img<span class="punctuation token">.</span>onload <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + ctx<span class="punctuation token">.</span><span class="function token">drawImage</span><span class="punctuation token">(</span>img<span class="punctuation token">,</span> <span class="number token">0</span><span class="punctuation token">,</span> <span class="number token">0</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">beginPath</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">moveTo</span><span class="punctuation token">(</span><span class="number token">30</span><span class="punctuation token">,</span> <span class="number token">96</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">lineTo</span><span class="punctuation token">(</span><span class="number token">70</span><span class="punctuation token">,</span> <span class="number token">66</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">lineTo</span><span class="punctuation token">(</span><span class="number token">103</span><span class="punctuation token">,</span> <span class="number token">76</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">lineTo</span><span class="punctuation token">(</span><span class="number token">170</span><span class="punctuation token">,</span> <span class="number token">15</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + ctx<span class="punctuation token">.</span><span class="function token">stroke</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span><span class="punctuation token">;</span> + img<span class="punctuation token">.</span>src <span class="operator token">=</span> <span class="string token">'https://mdn.mozillademos.org/files/5395/backdrop.png'</span><span class="punctuation token">;</span> +<span class="punctuation token">}</span></code></pre> + +<p><span class="short_text" id="result_box" lang="fr"><span>Le graphique résultant ressemble à ceci :</span></span></p> + +<p>{{EmbedLiveSample("Example_A_simple_line_graph", 220, 160, "https://mdn.mozillademos.org/files/206/Canvas_backdrop.png")}}</p> + +<h2 id="Mise_.C3.A0_l.27.C3.A9chelle" name="Mise_.C3.A0_l.27.C3.A9chelle">Mise à l'échelle</h2> + +<p>La seconde variante de la méthode <code>drawImage()</code> ajoute deux paramètres supplémentaires et permet de placer des images redimensionnées sur le canevas.</p> + +<h4 id="Example_Tiling_an_image" name="Example_Tiling_an_image">Exemple: Tapissage d'une image</h4> + +<p>Dans cet exemple, nous utiliserons une image comme papier-peint en la répétant plusieurs fois sur le canevas. Cette opération est réalisée simplement en faisant une boucle plaçant plusieurs fois l'image redimensionnée à différentes positions. Dans le code ci-dessous, la première boucle <code>for</code> s'occupe des lignes alors que la seconde gère les colonnes. L'image est redimensionnée à un tiers de sa taille originale, ce qui fait 50×38 pixels.</p> + +<div class="note"> +<p><strong>Note</strong> : les images peuvent devenir floues lorsqu'elles sont agrandies ou granuleuses si elles sont réduites. Il vaut mieux ne pas redimensionner une image contenant du texte devant rester lisible.</p> +</div> + +<pre class="brush: html line-numbers language-html notranslate"><code class="language-html"><span class="tag token"><span class="tag token"><span class="punctuation token"><</span>html</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>body</span> <span class="attr-name token">onload</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>draw();<span class="punctuation token">"</span></span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>canvas</span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>canvas<span class="punctuation token">"</span></span> <span class="attr-name token">width</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>150<span class="punctuation token">"</span></span> <span class="attr-name token">height</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>150<span class="punctuation token">"</span></span><span class="punctuation token">></span></span><span class="tag token"><span class="tag token"><span class="punctuation token"></</span>canvas</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>body</span><span class="punctuation token">></span></span> +<span class="tag token"><span class="tag token"><span class="punctuation token"></</span>html</span><span class="punctuation token">></span></span></code></pre> + +<pre class="brush: js line-numbers language-js notranslate"><code class="language-js"><span class="keyword token">function</span> <span class="function token">draw</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> ctx <span class="operator token">=</span> document<span class="punctuation token">.</span><span class="function token">getElementById</span><span class="punctuation token">(</span><span class="string token">'canvas'</span><span class="punctuation token">)</span><span class="punctuation token">.</span><span class="function token">getContext</span><span class="punctuation token">(</span><span class="string token">'2d'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">var</span> img <span class="operator token">=</span> <span class="keyword token">new</span> <span class="class-name token">Image</span><span class="punctuation token">(</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + img<span class="punctuation token">.</span>onload <span class="operator token">=</span> <span class="keyword token">function</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">for</span> <span class="punctuation token">(</span><span class="keyword token">var</span> i <span class="operator token">=</span> <span class="number token">0</span><span class="punctuation token">;</span> i <span class="operator token"><</span> <span class="number token">4</span><span class="punctuation token">;</span> i<span class="operator token">++</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">for</span> <span class="punctuation token">(</span><span class="keyword token">var</span> j <span class="operator token">=</span> <span class="number token">0</span><span class="punctuation token">;</span> j <span class="operator token"><</span> <span class="number token">3</span><span class="punctuation token">;</span> j<span class="operator token">++</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + ctx<span class="punctuation token">.</span><span class="function token">drawImage</span><span class="punctuation token">(</span>img<span class="punctuation token">,</span> j <span class="operator token">*</span> <span class="number token">50</span><span class="punctuation token">,</span> i <span class="operator token">*</span> <span class="number token">38</span><span class="punctuation token">,</span> <span class="number token">50</span><span class="punctuation token">,</span> <span class="number token">38</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="punctuation token">}</span> + <span class="punctuation token">}</span> + <span class="punctuation token">}</span><span class="punctuation token">;</span> + img<span class="punctuation token">.</span>src <span class="operator token">=</span> <span class="string token">'https://mdn.mozillademos.org/files/5397/rhino.jpg'</span><span class="punctuation token">;</span> +<span class="punctuation token">}</span></code></pre> + +<p><span class="short_text" id="result_box" lang="fr"><span>Le canevas résultant ressemble à ceci :</span></span></p> + +<p>{{EmbedLiveSample("Example_Tiling_an_image", 160, 160, "https://mdn.mozillademos.org/files/251/Canvas_scale_image.png")}}</p> + +<h2 id="D.C3.A9coupage" name="D.C3.A9coupage">Découpage</h2> + +<p>La troisième et dernière variante de la méthode <code>drawImage()</code> possède huit nouveaux paramètres. On peut l'utiliser pour découper des parties d'une image source et les afficher sur le canevas.</p> + +<dl> + <dt>{{domxref("CanvasRenderingContext2D.drawImage", "drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)")}}</dt> + <dd><span id="result_box" lang="fr"><span>Cette fonction prend la zone de l'<code>image</code> source spécifiée par le rectangle dont le coin en haut à gauche est (<code>sx</code>, <code>sy</code>) et dont la largeur et la hauteur sont <code>sWidth</code> et <code>sHeight</code> et le dessine dans le canevas en le plaçant sur le canevas</span> <span>(<code>dx</code>, <code>dy</code>) et le redimensionner à la taille spécifiée par <code>dWidth</code> et <code>dHeight</code>.</span></span><img alt="" class="internal" src="/@api/deki/files/1203/=Canvas_drawimage.jpg" style="float: right;"></dd> +</dl> + +<p><span id="result_box" lang="fr"><span>Pour vraiment comprendre ce que cela fait, il peut être utile de regarder l'image à droite.</span> <span>Les quatre</span></span><span lang="fr"><span> premiers paramètres définissent l'emplacement et la taille du morceau de l'image source.</span> <span>Les quatre derniers paramètres définissent le rectangle dans lequel dessiner l'image sur le canevas de destination.</span></span></p> + +<p>Le découpage peut être un outil utile pour réaliser des compositions. Vous pouvez disposer tous les éléments dans un seul fichier image et utiliser cette méthode pour composer un dessin complet. Par exemple, si vous voulez réaliser un graphique, vous pouvez utiliser une image PNG contenant tout le texte nécessaire dans un seul fichier et, selon vos données, changer l'échelle de votre graphique sans trop de difficultés. Un autre avantage est qu'il n'est pas nécessaire de charger chaque image individuellement.</p> + +<h4 id="Example_Framing_an_image" name="Example_Framing_an_image">Exemple : encadrer une image</h4> + +<p>Dans cet exemple, nous utiliserons le même rhinocéros que plus haut, mais sa tête sera coupée et composée avec un cadre. L'image du cadre fournit une ombre portée qui a été enregistrée dans une image PNG 24 bits. Comme les images PNG 24 bits comportent un canal alpha complet de 8 bits, contrairement aux images GIF et PNG 8 bits, elle peut être placée sur n'importe quel fond sans avoir à se préoccuper de la couleur de transition.</p> + +<pre class="brush: html line-numbers language-html notranslate"><code class="language-html"><span class="tag token"><span class="tag token"><span class="punctuation token"><</span>html</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>body</span> <span class="attr-name token">onload</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>draw();<span class="punctuation token">"</span></span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>canvas</span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>canvas<span class="punctuation token">"</span></span> <span class="attr-name token">width</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>150<span class="punctuation token">"</span></span> <span class="attr-name token">height</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>150<span class="punctuation token">"</span></span><span class="punctuation token">></span></span><span class="tag token"><span class="tag token"><span class="punctuation token"></</span>canvas</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>div</span><span class="language-css style-attr token"><span class="attr-name token"> <span class="attr-name token">style</span></span><span class="punctuation token">="</span><span class="attr-value token"><span class="property token">display</span><span class="punctuation token">:</span>none<span class="punctuation token">;</span></span><span class="punctuation token">"</span></span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>img</span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>source<span class="punctuation token">"</span></span> <span class="attr-name token">src</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>https://mdn.mozillademos.org/files/5397/rhino.jpg<span class="punctuation token">"</span></span> <span class="attr-name token">width</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>300<span class="punctuation token">"</span></span> <span class="attr-name token">height</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>227<span class="punctuation token">"</span></span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"><</span>img</span> <span class="attr-name token">id</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>frame<span class="punctuation token">"</span></span> <span class="attr-name token">src</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>https://mdn.mozillademos.org/files/242/Canvas_picture_frame.png<span class="punctuation token">"</span></span> <span class="attr-name token">width</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>132<span class="punctuation token">"</span></span> <span class="attr-name token">height</span><span class="attr-value token"><span class="punctuation token">=</span><span class="punctuation token">"</span>150<span class="punctuation token">"</span></span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>div</span><span class="punctuation token">></span></span> + <span class="tag token"><span class="tag token"><span class="punctuation token"></</span>body</span><span class="punctuation token">></span></span> +<span class="tag token"><span class="tag token"><span class="punctuation token"></</span>html</span><span class="punctuation token">></span></span></code></pre> + +<pre class="brush: js line-numbers language-js notranslate"><code class="language-js"><span class="keyword token">function</span> <span class="function token">draw</span><span class="punctuation token">(</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> canvas <span class="operator token">=</span> document<span class="punctuation token">.</span><span class="function token">getElementById</span><span class="punctuation token">(</span><span class="string token">'canvas'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">var</span> ctx <span class="operator token">=</span> canvas<span class="punctuation token">.</span><span class="function token">getContext</span><span class="punctuation token">(</span><span class="string token">'2d'</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="comment token">// Draw slice</span> + ctx<span class="punctuation token">.</span><span class="function token">drawImage</span><span class="punctuation token">(</span>document<span class="punctuation token">.</span><span class="function token">getElementById</span><span class="punctuation token">(</span><span class="string token">'source'</span><span class="punctuation token">)</span><span class="punctuation token">,</span> + <span class="number token">33</span><span class="punctuation token">,</span> <span class="number token">71</span><span class="punctuation token">,</span> <span class="number token">104</span><span class="punctuation token">,</span> <span class="number token">124</span><span class="punctuation token">,</span> <span class="number token">21</span><span class="punctuation token">,</span> <span class="number token">20</span><span class="punctuation token">,</span> <span class="number token">87</span><span class="punctuation token">,</span> <span class="number token">104</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + + <span class="comment token">// Draw frame</span> + ctx<span class="punctuation token">.</span><span class="function token">drawImage</span><span class="punctuation token">(</span>document<span class="punctuation token">.</span><span class="function token">getElementById</span><span class="punctuation token">(</span><span class="string token">'frame'</span><span class="punctuation token">)</span><span class="punctuation token">,</span> <span class="number token">0</span><span class="punctuation token">,</span> <span class="number token">0</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="punctuation token">}</span></code></pre> + +<p><span id="result_box" lang="fr"><span>Nous avons pris une approche différente pour charger les images cette fois.</span> <span>Au lieu de les charger en créant de nouveaux objets {{domxref ("HTMLImageElement")}}, nous les avons incluses comme balises </span></span> {{HTMLElement("img")}} <span lang="fr"><span>directement dans notre source HTML et avons récupéré les images depuis ceux-ci.</span> <span>Les images sont masquées à partir de la sortie, en définissant la propriété CSS {{cssxref ("display")}} à aucune.</span></span></p> + +<p>{{EmbedLiveSample("Example_Framing_an_image", 160, 160, "https://mdn.mozillademos.org/files/226/Canvas_drawimage2.jpg")}}</p> + +<p><span id="result_box" lang="fr"><span>Le script lui-même est très simple.</span> <span>Chaque {{HTMLElement ("img")}} se voit attribuer un attribut ID, ce qui facilite leur sélection en utilisant {{domxref ("document.getElementById ()")}}.</span> <span>Nous utilisons simplement <code>drawImage ()</code> pour découper le rhinocéros de la première image et le mettre à l'échelle sur le canevas, puis dessiner le cadre par le haut en utilisant un deuxième appel <code>drawImage ()</code>.</span></span></p> + +<h2 id="Art_gallery_example" name="Art_gallery_example">Exemple d'une galerie d'art</h2> + +<p>Dans le dernier exemple de ce chapitre, nous présenterons une petite galerie d'art. Cette galerie est constituée d'un tableau contenant plusieurs images. Lorsque la page est chargée, un élément {{HTMLElement("canvas")}} est inséré pour chaque image et un cadre est dessiné autour.</p> + +<p>Dans notre cas, toutes les images ont une largeur et une hauteur fixes, ainsi que le cadre qui sera dessiné autour. Le script pourrait être amélioré afin d'utiliser la largeur et la hauteur de l'image pour que le cadre s'adapte parfaitement à ses dimensions.</p> + +<p>Le code ci-dessous devrait s'expliquer de lui-même. <span id="result_box" lang="fr"><span>Nous parcourons le conteneur {{domxref ("document.images")}}</span></span> et nous ajoutons de nouveaux éléments canvas. La seule chose notable est probablement, pour ceux qui ne sont pas familiers avec le DOM, l'utilisation de la méthode {{domxref("Node.insertBefore")}} . <code>insertBefore()</code> est une méthode du nœud parent (une cellule de tableau) de l'élément (l'image) avant lequel on désire insérer le nouveau nœud (l'élément canvas).</p> + +<pre class="brush: html notranslate"><html> + <body onload="draw();"> + <table> + <tr> + <td><img src="https://mdn.mozillademos.org/files/5399/gallery_1.jpg"></td> + <td><img src="https://mdn.mozillademos.org/files/5401/gallery_2.jpg"></td> + <td><img src="https://mdn.mozillademos.org/files/5403/gallery_3.jpg"></td> + <td><img src="https://mdn.mozillademos.org/files/5405/gallery_4.jpg"></td> + </tr> + <tr> + <td><img src="https://mdn.mozillademos.org/files/5407/gallery_5.jpg"></td> + <td><img src="https://mdn.mozillademos.org/files/5409/gallery_6.jpg"></td> + <td><img src="https://mdn.mozillademos.org/files/5411/gallery_7.jpg"></td> + <td><img src="https://mdn.mozillademos.org/files/5413/gallery_8.jpg"></td> + </tr> + </table> + <img id="frame" src="https://mdn.mozillademos.org/files/242/Canvas_picture_frame.png" width="132" height="150"> + </body> +</html> +</pre> + +<p><span id="result_box" lang="fr"><span>Et voici quelques CSS pour rendre les choses agréables :</span></span></p> + +<pre class="brush: css notranslate">body { + background: 0 -100px repeat-x url(https://mdn.mozillademos.org/files/5415/bg_gallery.png) #4F191A; + margin: 10px; +} + +img { + display: none; +} + +table { + margin: 0 auto; +} + +td { + padding: 15px; +} +</pre> + +<p><span id="result_box" lang="fr"><span>Le lien pour tout cela, c'est le JavaScript pour dessiner les images encadrées :</span></span></p> + +<pre class="brush: js notranslate">function draw() { + + // Boucle à travers toutes les images + for (var i = 0; i < document.images.length; i++) { + + // N'ajoute pas de canevas pour l'image du cadre + if (document.images[i].getAttribute('id') != 'frame') { + + // Crée un élément canvas + canvas = document.createElement('canvas'); + canvas.setAttribute('width', 132); + canvas.setAttribute('height', 150); + + // Insère avant l'image + document.images[i].parentNode.insertBefore(canvas,document.images[i]); + + ctx = canvas.getContext('2d'); + + // Dessine l'image sur canvas + ctx.drawImage(document.images[i], 15, 20); + + // Ajoute un cadre + ctx.drawImage(document.getElementById('frame'), 0, 0); + } + } +}</pre> + +<p>{{EmbedLiveSample("Art_gallery_example", 725, 400)}}</p> + +<h2 id="Contrôle_du_comportement_de_la_mise_à_léchelle_de_limage"><span id="result_box" lang="fr"><span>Contrôle du comportement de la mise à l'échelle de l'image</span></span></h2> + +<p><span id="result_box" lang="fr"><span>Comme mentionné précédemment, la mise à l'échelle des images peut entraîner des objets flous ou granuleux en raison du processus de mise à l'échelle.</span> <span>Vous pouvez utiliser la propriété </span></span> {{domxref("CanvasRenderingContext2D.imageSmoothingEnabled", "imageSmoothingEnabled")}} <span lang="fr"><span> du contexte de dessin pour contrôler l'utilisation des algorithmes de lissage d'image lors de la mise à l'échelle des images dans votre contexte.</span> <span>Par défaut, cela est vrai, ce qui signifie que les images seront lissées lors de la mise à l'échelle.</span> <span>Vous pouvez désactiver cette fonctionnalité comme ceci :</span></span></p> + +<pre class="brush: js line-numbers language-js notranslate"><code class="language-js">ctx<span class="punctuation token">.</span>mozImageSmoothingEnabled <span class="operator token">=</span> <span class="keyword token">false</span><span class="punctuation token">;</span> +ctx<span class="punctuation token">.</span>webkitImageSmoothingEnabled <span class="operator token">=</span> <span class="keyword token">false</span><span class="punctuation token">;</span> +ctx<span class="punctuation token">.</span>msImageSmoothingEnabled <span class="operator token">=</span> <span class="keyword token">false</span><span class="punctuation token">;</span> +ctx<span class="punctuation token">.</span>imageSmoothingEnabled <span class="operator token">=</span> <span class="keyword token">false</span><span class="punctuation token">;</span></code></pre> + +<p>{{PreviousNext("Dessin_de_texte_avec_canvas", "Tutoriel_canvas/Transformations" )}}</p> diff --git a/files/fr/web/api/canvas_api/tutoriel_canvas/utilisation_de_base/index.html b/files/fr/web/api/canvas_api/tutoriel_canvas/utilisation_de_base/index.html new file mode 100644 index 0000000000..6182dee589 --- /dev/null +++ b/files/fr/web/api/canvas_api/tutoriel_canvas/utilisation_de_base/index.html @@ -0,0 +1,149 @@ +--- +title: Utilisation de base des canvas +slug: Web/API/Canvas_API/Tutoriel_canvas/Utilisation_de_base +tags: + - Canvas + - Graphismes + - HTML + - Tutoriel_canvas + - Tutoriels +translation_of: Web/API/Canvas_API/Tutorial/Basic_usage +--- +<p>{{CanvasSidebar}} {{PreviousNext("Tutoriel_canvas", "Tutoriel_canvas/Formes_géométriques")}}</p> + +<h2 id="Lélément_<canvas>">L'élément <code><canvas></code></h2> + +<p>Commençons par regarder l'élément {{HTMLElement("canvas")}} lui-même.</p> + +<pre class="brush: html notranslate"><canvas id="tutoriel" width="150" height="150"></canvas> +</pre> + +<p>Ceci ressemble beaucoup à l'élément <img>. La seule différence est qu'il n'y a pas les attributs <code>src</code> et <code>alt</code>. L'élément <code><canvas></code> a seulement deux attributs : {{htmlattrxref ("width", "canvas")}} et {{htmlattrxref ("height", "canvas")}} (« largeur » et « hauteur »). Ces deux attributs sont optionnels et peuvent aussi être fixés à travers le <a href="/fr/docs/R%C3%A9f%C3%A9rence_du_DOM_Gecko">DOM</a>. Quand les attributs <strong>width</strong> et <strong>height</strong> ne sont pas spécifiés, le canvas sera initialement large de <strong>300 pixels</strong> et haut de <strong>150 pixels</strong>. Les dimensions du canvas peuvent être modifiés par du <a href="/fr/docs/Web/CSS">CSS</a>, mais l'image sera dessinée selon les valeurs <strong>width</strong> et <strong>height</strong> du canvas et ensuite étirée pour afficher dans l'espace donné par le CSS.</p> + +<div class="note"> +<p><strong>Note :</strong> Si l'image semble déformée, essayez de spécifier de manière explicite vos attributs <code>width</code> et <code>height</code> dans l'élément <code><canvas></code>, et de ne pas utiliser de CSS.</p> +</div> + +<p>L'attribut <code>id</code> n'est pas spécifique à l'élément <code><canvas></code>. C'est en fait un des attributs HTML de base qui peut être utilisé par presque tous les éléments HTML. C'est toujours mieux d'assigner une <code>id</code> car ça facilite beaucoup l'identification du <code>canvas</code> dans le code <code>javascript</code>.</p> + +<p>L'élément <code><canvas></code> peut être stylisé comme n'importe quelle image normale (marges, contours, arrière-plan, etc). Si aucun style n'est donné, le canvas sera par défaut complètement transparent. Il faut noter que peu importe quels styles sont utilisés, le style n'affectera pas l'acte de dessiner sur le canvas. Nous verrons en détail la stylisation des canvas plus tard dans ce tutoriel.</p> + +<div id="section_2"> +<h3 id="Contenu_de_repli">Contenu de repli</h3> + +<p>Puisque certains plus anciens navigateurs ne supportent pas l'élément {{HTMLElement("canvas")}} (les plus communs étant les versions d'Internet Explorer avant la version 9), il est mieux d'avoir du contenu de repli pour afficher.</p> + +<p>Heureusement, c'est très facile : il faut tout simplement mettre le contenu dans l'élément <code><canvas></code> lui-même. Les navigateurs qui ne supportent pas <code><canvas></code> vont afficher ce contenu de repli, et ceux qui supportent <code><canvas></code> vont l'ignorer et dessiner le canvas.</p> + +<p>Le contenu de repli pourrait, par exemple, donner une description texte du canvas, ou afficher une image fixe comme aperçu de ce que le canvas dessinerait de façon dynamique.</p> + +<pre class="brush: html notranslate"><canvas id="stockGraph" width="150" height="150"> + current stock price: $3.15 + 0.15 +</canvas> + +<canvas id="clock" width="150" height="150"> + <img src="images/clock.png" width="150" height="150" alt=""/> +</canvas></pre> + +<h2 id="La_nécessité_de_la_balise_<canvas>">La nécessité de la balise <code></canvas></code></h2> + +<p>Au contraire de l'élément {{HTMLElement("img")}}, l'élément {{HTMLElement("canvas")}} <strong>requiert</strong> la balise fermante (<code></canvas></code>).</p> + +<div class="note"> +<p><strong>Note :</strong> Bien que quelques unes des premières versions du navigateur Safari ne requièrent pas la balise fermante, la spécification HTML indique qu'elle est nécessaire, alors il est mieux de l'inclure pour avoir le plus de compatibilité possible. Ces anciennes versions de Safari (avant la version 2.0) affichent le contenu de repli en plus que le canvas lui-même, sauf si vous utilisez des trucs CSS pour le masquer. Heureusement, il y a très peu d'utilisateurs de ces vieilles versions de Safari de nos jours.</p> +</div> + +<p>Si vous n'avez pas besoin de contenu de repli, un simple <code><canvas id="foo" ...></canvas></code> est totalement compatible avec tous les navigateurs qui ont pris en charge la fonctionnalité canvas.</p> + +<h2 id="Le_contexte_de_rendu">Le contexte de rendu</h2> + +<p>L'élément {{HTMLElement("canvas")}} crée une surface pour dessiner à grandeur fixe. Cette surface expose un ou plusieurs <strong>contextes de rendu</strong>, qui sont utilisés pour créer et manipuler le contenu affiché. Ce tutoriel se concentrera sur le contexte de rendu 2D. D'autres contextes permettent d'autres types de rendu, tel que le contexte <a href="/fr/docs/Web/WebGL">WebGL</a>, qui utilise un contexte 3D ("experimental-webgl") inspiré de <a class="external" href="http://www.khronos.org/opengles/" rel="external" title="http://en.wikipedia.org/wiki/OpenGL_ES">OpenGL ES</a>.</p> + +<p>Initialement, le canvas est vide. Pour afficher quelque chose, un script doit commencer par accéder au contexte de rendu pour pouvoir dessiner dessus. L'élément {{HTMLElement("canvas")}} a une <a href="/fr/docs/Web/API/HTMLCanvasElement#M.C3.A9thodes">méthode</a> nommée <code>getContext()</code>, qui peut être utilisée pour obtenir le contexte de rendu et ses fonctions de dessin. <code>getContext()</code> a comme seul paramètre le type de contexte. Pour des graphiques 2D, comme ceux utilisés dans ce tutoriel, il faut spécifier "2d".</p> + +<pre class="brush: js notranslate">var canvas = document.getElementById('tutorial'); +var ctx = canvas.getContext('2d');</pre> + +<p>La première ligne obtient le {{HTMLElement("canvas")}} dans le DOM en appelant {{domxref("document.getElementById()")}}. Lorsque nous avons l'élément canvas, nous pouvons accéder au contexte de rendu en utilisant sa méthode <code>getContext()</code>.</p> + +<div id="section_5"> +<h2 id="Vérification_de_la_prise_en_charge">Vérification de la prise en charge</h2> + +<p>Le contenu de repli est affiché dans les navigateurs qui ne prennent pas en charge l'élément {{HTMLElement("canvas")}}. Les scripts peuvent aussi vérifier la prise en charge de manière programmatique en vérifiant la présence de la méthode <code>getContext()</code>. Notre extrait de code ci-dessus se transforme donc en ceci :</p> + +<pre class="brush: js notranslate">var canvas = document.getElementById('tutorial'); + +if (canvas.getContext) { + var ctx = canvas.getContext('2d'); + // code de dessin dans le canvas +} else { + // code pour le cas où canvas ne serait pas supporté +}</pre> +</div> +</div> + +<h2 id="Un_modèle_basique">Un modèle basique</h2> + +<p>Voici un modèle minimaliste, que nous allons utiliser comme point de départ dans des futurs exemples.</p> + +<pre class="brush: html notranslate"><!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <title>Canvas tutorial</title> + <script type="text/javascript"> + function draw() { + var canvas = document.getElementById('tutorial'); + if (canvas.getContext) { + var ctx = canvas.getContext('2d'); + } + } + </script> + <style type="text/css"> + canvas { border: 1px solid black; } + </style> + </head> + <body onload="draw();"> + <canvas id="tutorial" width="150" height="150"></canvas> + </body> +</html></pre> + +<p>Ce script contient une fonction <code>draw()</code>, qui est exécutée lorsque la page a fini de charger. Ce résultat est obtenu en utilisant l'événement de chargement du document. Cette fonction, ou une fonction similaire, pourrait aussi être appelé en utilisant {{domxref("window.setTimeout()")}}, {{domxref("window.setInterval()")}}, ou n'importe quel autre gestionnaire d'événement, tant que la page est chargée en premier.</p> + +<p>Voici à quoi le modèle ressemble :</p> + +<p>{{EmbedLiveSample("Un_modèle_basique", 160, 160)}}</p> + +<h2 id="Un_exemple_simple">Un exemple simple</h2> + +<p>Pour commencer, observons un exemple simple qui dessine deux rectangles qui s'intersectent, un d'entre eux ayant de la transparence alpha. Nous verrons plus en détail comment ça marche dans les exemples suivants.</p> + +<pre class="brush: html notranslate"><!DOCTYPE html> +<html> + <head> + <meta charset="utf-8"/> + <script type="application/javascript"> + function draw() { + var canvas = document.getElementById("canvas"); + if (canvas.getContext) { + var ctx = canvas.getContext("2d"); + + ctx.fillStyle = 'rgb(200, 0, 0)'; + ctx.fillRect(10, 10, 50, 50); + + ctx.fillStyle = 'rgba(0, 0, 200, 0.5)'; + ctx.fillRect(30, 30, 50, 50); + } + } + </script> + </head> + <body onload="draw();"> + <canvas id="canvas" width="150" height="150"></canvas> + </body> +</html></pre> + +<p>Cet exemple ressemble a ceci :</p> + +<p>{{EmbedLiveSample("Un_exemple_simple", 160, 160, "https://mdn.mozillademos.org/files/228/canvas_ex1.png")}}</p> + +<p>{{PreviousNext("Tutoriel_canvas", "Tutoriel_canvas/Formes_géométriques")}}</p> |