diff options
author | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:41:15 -0500 |
---|---|---|
committer | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:41:15 -0500 |
commit | 4b1a9203c547c019fc5398082ae19a3f3d4c3efe (patch) | |
tree | d4a40e13ceeb9f85479605110a76e7a4d5f3b56b /files/ca/web/api/canvas_api/tutorial/drawing_shapes | |
parent | 33058f2b292b3a581333bdfb21b8f671898c5060 (diff) | |
download | translated-content-4b1a9203c547c019fc5398082ae19a3f3d4c3efe.tar.gz translated-content-4b1a9203c547c019fc5398082ae19a3f3d4c3efe.tar.bz2 translated-content-4b1a9203c547c019fc5398082ae19a3f3d4c3efe.zip |
initial commit
Diffstat (limited to 'files/ca/web/api/canvas_api/tutorial/drawing_shapes')
-rw-r--r-- | files/ca/web/api/canvas_api/tutorial/drawing_shapes/index.html | 579 |
1 files changed, 579 insertions, 0 deletions
diff --git a/files/ca/web/api/canvas_api/tutorial/drawing_shapes/index.html b/files/ca/web/api/canvas_api/tutorial/drawing_shapes/index.html new file mode 100644 index 0000000000..6e8162ac44 --- /dev/null +++ b/files/ca/web/api/canvas_api/tutorial/drawing_shapes/index.html @@ -0,0 +1,579 @@ +--- +title: Dibuix de formes amb canvas +slug: Web/API/Canvas_API/Tutorial/Drawing_shapes +tags: + - Canvas + - Graphics + - HTML + - HTML Canvas + - HTML5 + - Intermediate + - Tutorial +translation_of: Web/API/Canvas_API/Tutorial/Drawing_shapes +--- +<div>{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Basic_usage", "Web/API/Canvas_API/Tutorial/Applying_styles_and_colors")}}</div> + +<div class="summary"> +<p>Ara que hem configurat el nostre <a href="https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Basic_usage">entorn canvas</a>, podem entrar en els detalls de com dibuixar sobre el llenç. Al final d'aquest article, haureu après a dibuixar rectangles, triangles, línies, arcs i corbes, proporcionant-vos familiaritat amb algunes de les formes bàsiques. Treballar amb camins és essencial a l'hora de dibuixar objectes sobre el llenç i veurem com fer-ho.</p> +</div> + +<h2 id="La_graella">La graella</h2> + +<p><img alt="" class="internal" src="https://mdn.mozillademos.org/files/224/Canvas_default_grid.png" style="float: right; height: 220px; width: 220px;">Abans de poder començar a dibuixar, hem de parlar sobre la graella canvas o <strong>coordinar l'espai</strong>. El nostre esquelet HTML de la pàgina anterior tenia un element canvas amb 150 píxels d'amplada i 150 píxels d'alçada. A la dreta, veureu aquest llenç amb la graella predeterminada superposada. Normalment, una unitat de la graella correspon a 1 píxel sobre el llenç. L'origen d'aquesta graella es posiciona a la cantonada <em>superior esquerra</em> a la coordenada (0,0). Tots els elements es col·loquen en relació amb aquest origen. Per tant, la posició de la cantonada superior esquerra del quadrat blau es converteix en x pixels des de l'esquerra i y pixels des de la part superior, en la coordenada (x,y). Més endavant, en aquest tutorial veurem com podem traduir l'origen a una posició diferent, girar la graella i fins i tot escalar-la, però de moment ens quedarem amb el valor predeterminat.</p> + +<h2 id="Dibuixar_rectangles">Dibuixar rectangles</h2> + +<p>A diferència de {{Glossary("SVG")}}, {{HTMLElement("canvas")}} només suporta una forma primitiva: rectangles. Totes les altres formes han de crear-se combinant una o més trajectòries, llistes de punts connectats per línies. Afortunadament, tenim una gran varietat de funcions de dibuix de trajectòria que permeten compondre formes molt complexes.</p> + +<p>Primer vegem el rectangle. Hi ha tres funcions que dibuixen rectangles en canvas:</p> + +<dl> + <dt>{{domxref("CanvasRenderingContext2D.fillRect", "fillRect(x, y, width, height)")}}</dt> + <dd>Dibuixa un rectangle ple.</dd> + <dt>{{domxref("CanvasRenderingContext2D.strokeRect", "strokeRect(x, y, width, height)")}}</dt> + <dd>Dibuixa un contorn rectangular.</dd> + <dt>{{domxref("CanvasRenderingContext2D.clearRect", "clearRect(x, y, width, height)")}}</dt> + <dd>Esborra l'àrea rectangular especificada, fent-la completament transparent</dd> +</dl> + +<p>Cadascuna d'aquestes tres funcions pren els mateixos paràmetres. <code>x</code> i <code>y</code> indiquen la posició en el llenç (relativa a l'origen) de la cantonada superior esquerra del rectangle. <code>width</code> i <code>height</code> proporcionen la grandària del rectangle</p> + +<p>A sota hi ha la funció <code>draw()</code> de la pàgina anterior, però ara fa ús d'aquestes tres funcions.</p> + +<h3 id="Exemple_de_forma_rectangular">Exemple de forma rectangular</h3> + +<div class="hidden"> +<pre class="brush: html"><html> + <body onload="draw();"> + <canvas id="canvas" width="150" height="150"></canvas> + </body> +</html> +</pre> +</div> + +<pre class="brush: js">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><span id="result_box" lang="ca"><span>La sortida d'aquest exemple es mostra a continuació</span></span>.</p> + +<p>{{EmbedLiveSample("Rectangular_shape_example", 160, 160, "https://mdn.mozillademos.org/files/245/Canvas_rect.png")}}</p> + +<p>La funció <code>fillRect()</code> dibuixa un quadrat negre de 100 píxels a cada costat. La funció <code>clearRect()</code> esborra un quadrat de 60x60 píxels del centre, i a continuació es crida a <code>strokeRect()</code> per crear un contorn rectangular de 50x50 píxels dins del quadrat buidat.</p> + +<p>A les properes pàgines veurem dos mètodes alternatius per <code>clearRect()</code>, i també veurem com canviar l'estil de color i traç de les formes representades.</p> + +<p>A diferència de les funcions de trajectòria, que veurem en la següent secció, les tres funcions rectangulars dibuixen immediatament al llenç.</p> + +<h2 id="Dibuixar_trajectories">Dibuixar trajectories</h2> + +<p>Les úniques altres formes primitives són les <em>trajectòries</em>. Una trajectòria és una llista de punts, connectats per segments de línies que poden ser de diferents formes, corbes o no, de diferent amplària i de diferent color. Un trajectòria, o fins i tot una subtrajecte, pot ser tancada. Per fer formes utilitzant trajectòries, es prenen alguns passos addicionals:</p> + +<ol> + <li>Primer, crea la trajectòria.</li> + <li>A continuació, utilitzar <a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D#Paths">ordres de dibuix</a> per dibuixar en la trajectòria.</li> + <li>Després, tancar la trajectòria.</li> + <li>Una vegada que s'ha creat la trajectòria, podeu traçar o omplir la trajectòria per representar-la</li> +</ol> + +<p>A continuació, es detallen les funcions que s'utilitzen per realitzar aquests passos:</p> + +<dl> + <dt>{{domxref("CanvasRenderingContext2D.beginPath", "beginPath()")}}</dt> + <dd>Crea una trajectòria nova. Una vegada creada, les futures ordres de dibuix s'aplican a la trajectòria i són utilitzades per construir-la.</dd> + <dt><a href="/en-US/docs/Web/API/CanvasRenderingContext2D#Paths">Mètodes de trajectòria</a></dt> + <dd>Mètodes per establir diferentes trajectòries d'objectes.</dd> + <dt>{{domxref("CanvasRenderingContext2D.closePath", "closePath()")}}</dt> + <dd>Afegeix una línia recta a la trajectòria, anant a l'inici de la subruta actual.</dd> + <dt>{{domxref("CanvasRenderingContext2D.stroke", "stroke()")}}</dt> + <dd>Dibuixa la forma traçant el seu contorn.</dd> + <dt>{{domxref("CanvasRenderingContext2D.fill", "fill()")}}</dt> + <dd>Dibuixa una forma sòlida emplenant l'àrea de contingut de la trajectòria.</dd> +</dl> + +<p>El primer pas per crear una trajectòria és cridar a <code>beginPath()</code>. Internament, les trajectòries s'emmagatzemen com una llista de subtrayectes (línies, arcs, etc.) que formen una forma. Cada vegada que es crida a aquest mètode, la llista es reinicia i podem començar a dibuixar noves formes.</p> + +<div class="note"><strong>Nota:</strong> Quan la trajectòria actual està buida, com immediatament després de cridar <code>beginPath()</code>, o en un llenç recentment creat, la primera ordre de construcció de la trajectòria sempre es tractarà com <code>moveTo()</code>, independentment del que realment sigui. Per aquesta raó, gairebé sempre voldreu establir específicament la seva posició inicial després de restablir una trajectòria.</div> + +<p>El segon pas és cridar als mètodes que realment especifiquen les trajectòries que s'han de dibuixar. Ho veurem en breu.</p> + +<p>El tercer, i com a pas opcional, és cridar <code>closePath()</code>. Aquest mètode intenta tancar la forma, dibuixant una recta des del punt actual fins al començament. Si la forma ja s'ha tancat o només hi ha un punt a la llista, aquesta funció no fa res.</p> + +<div class="note"><strong>Nota:</strong> Quan crideu <code>fill()</code>, totes les formes obertes es tanquen automàticament, de manera que no heu de cridar <code>closePath()</code>. Aquest <strong>no</strong> és el cas quan es crida <code>stroke()</code>.</div> + +<h3 id="Dibuixar_un_triangle">Dibuixar un triangle</h3> + +<p>Per exemple, el codi per dibuixar un triangle es veuria així:</p> + +<div class="hidden"> +<pre class="brush: html"><html> + <body onload="draw();"> + <canvas id="canvas" width="100" height="100"></canvas> + </body> +</html> +</pre> +</div> + +<pre class="brush: js">function draw() { + var canvas = document.getElementById('canvas'); + if (canvas.getContext) { + var ctx = canvas.getContext('2d'); + + ctx.beginPath(); + ctx.moveTo(75, 50); + ctx.lineTo(100, 75); + ctx.lineTo(100, 25); + ctx.fill(); + } +} +</pre> + +<p><span class="short_text" id="result_box" lang="ca"><span>El resultat és així</span></span>:</p> + +<p>{{EmbedLiveSample("Drawing_a_triangle", 110, 110, "https://mdn.mozillademos.org/files/9847/triangle.png")}}</p> + +<h3 id="Moure_el_llapis">Moure el llapis</h3> + +<p>Una funció molt útil, que en realitat no dibuixa res però es converteix en part de la llista de trajectòries descrita anteriorment, és la funció <code>moveTo()</code>. Probablement el millor sigui pensar en això com aixecar un bolígraf o un llapis d'un lloc en un tros de paper i col·locar-ho en el següent.</p> + +<dl> + <dt>{{domxref("CanvasRenderingContext2D.moveTo", "moveTo(x, y)")}}</dt> + <dd>Mou el llapis a les coordenades especificades per <code>x</code> i <code>y</code>.</dd> +</dl> + +<p>Quan s'inicialitza el llenç o es crida <code>beginPath()</code> normalment voldreu utilitzar la funció <code>moveTo()</code> per col·locar el punt de partida en un altre lloc. També podrieu utilitzar <code>moveTo()</code> per dibuixar trajectòries no connectades. Feu un cop d'ull a la cara somrient d'a baix</p> + +<p>Proveu-ho vosaltres mateixos, podeu utilitzar el fragment de codi que es mostra a continuació. Simplement enganxeu-lo a la funció <code>draw()</code> que vam veure anteriorment.</p> + +<div class="hidden"> +<pre class="brush: html"><html> + <body onload="draw();"> + <canvas id="canvas" width="150" height="150"></canvas> + </body> +</html> +</pre> +</div> + +<pre class="brush: js;highlight:[8,10,12]">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); // Outer circle + ctx.moveTo(110, 75); + ctx.arc(75, 75, 35, 0, Math.PI, false); // Mouth (clockwise) + ctx.moveTo(65, 65); + ctx.arc(60, 65, 5, 0, Math.PI * 2, true); // Left eye + ctx.moveTo(95, 65); + ctx.arc(90, 65, 5, 0, Math.PI * 2, true); // Right eye + ctx.stroke(); + } +} +</pre> + +<p><span class="short_text" id="result_box" lang="ca"><span>El resultat és així</span></span>:</p> + +<p>{{EmbedLiveSample("Moving_the_pen", 160, 160, "https://mdn.mozillademos.org/files/252/Canvas_smiley.png")}}</p> + +<p>Si voleu veure les línies de connexió, podeu eliminar les línies que criden <code>moveTo()</code>.</p> + +<div class="note"> +<p><strong>Nota:</strong> Per obtenir més informació sobre la funció <code>arc()</code>, vegeu {{anch("Arcs")}} a continuació.</p> +</div> + +<h3 id="Línies">Línies</h3> + +<p>Per dibuixar línies rectes, utilitzeu el mètode <code>lineTo()</code>.</p> + +<dl> + <dt>{{domxref("CanvasRenderingContext2D.lineTo", "lineTo(x, y)")}}</dt> + <dd>Dibuixa una línia des de la posició del dibuix actual fins a la posició especificada per <code>x</code> i <code>y</code>.</dd> +</dl> + +<p>Aquest mètode pren dos arguments, <code>x</code> i <code>y</code>, que són les coordenades del punt final de la línia. El punt de partida depèn de les trajectòries prèviament traçades, on el punt final de la trajectòria anterior és el punt de partida de la següent, etc. El punt de partida també es pot canviar utilitzant el mètode <code>moveTo()</code>.</p> + +<p>L'exemple següent dibuixa dos triangles, un omplert i un altre delineat.</p> + +<div class="hidden"> +<pre class="brush: html"><html> + <body onload="draw();"> + <canvas id="canvas" width="150" height="150"></canvas> + </body> +</html> +</pre> +</div> + +<pre class="brush: js;highlight[9,10,16,17]">function draw() { + var canvas = document.getElementById('canvas'); + if (canvas.getContext) { + var ctx = canvas.getContext('2d'); + + // Filled triangle + ctx.beginPath(); + ctx.moveTo(25, 25); + ctx.lineTo(105, 25); + ctx.lineTo(25, 105); + ctx.fill(); + + // Stroked triangle + ctx.beginPath(); + ctx.moveTo(125, 125); + ctx.lineTo(125, 45); + ctx.lineTo(45, 125); + ctx.closePath(); + ctx.stroke(); + } +} +</pre> + +<p>Això comença cridant <code>beginPath()</code> per iniciar una nova trajectòria de forma. Seguidament, utilitzem el mètode <code>moveTo()</code> per moure el punt de partida a la posició desitjada. A continuació, es dibuixen dues línies que formen dues cares del triangle.</p> + +<p>{{EmbedLiveSample("Lines", 160, 160, "https://mdn.mozillademos.org/files/238/Canvas_lineTo.png")}}</p> + +<p>Notareu la diferència entre el triangle emplenat i traçat. Això és, com es va esmentar anteriorment, perquè les formes es tanquen automàticament quan s'omple una trajectòria, però no quan es tracen. Si deixem de costat <code>closePath()</code> per al triangle traçat, només s'haurien dibuixat dues línies, no un triangle complet.</p> + +<h3 id="Arcs">Arcs</h3> + +<p>Per dibuixar arcs o cercles, utilitzem els mètodes <code>arc()</code> o <code>arcTo()</code>.</p> + +<dl> + <dt>{{domxref("CanvasRenderingContext2D.arc", "arc(x, y, radius, startAngle, endAngle, anticlockwise)")}}</dt> + <dd>Dibuixa un arc que està centrat en la posició (<em>x, y</em>) amb un radi <em>r</em> que comença en <em>startAngle</em> i acaba en <em>endAngle</em> que va en la direcció donada, indicada per el <em>sentit antihorari</em> (predeterminat en <em>sentit horari</em>)</dd> + <dt>{{domxref("CanvasRenderingContext2D.arcTo", "arcTo(x1, y1, x2, y2, radius)")}}</dt> + <dd>Dibuixa un arc amb els punts de control i radi donats, connectats al punt anterior per una línia recta.</dd> +</dl> + +<p>Vegem amb més detall el mètode <code>arc</code>, que pren sis paràmetres: <code>x</code> i <code>y</code> són les coordenades del centre del cercle en el qual s'ha de dibuixar l'arc. <code>radius</code> és autoexplicatiu. Els paràmetres <code>startAngle</code> i <code>endAngle</code> defineixen els punts inicial i final de l'arc en radiants, al llarg de la corba del cercle. Aquests es mesuren des de l'eix x. El paràmetre <code>anticlockwise</code> és un valor booleà, que quan és <code>true</code>, dibuixa l'arc en sentit contrari a les agulles del rellotge; en cas contrari, l'arc es dibuixa en sentit horari.</p> + +<div class="note"> +<p><strong>Nota</strong>: Els angles en la funció <code>arc</code> es mesuren en radiants, no en graus. Per convertir graus a radiants es pot utilitzar la següent expressió Javascript: <code>radians = (Math.PI/180)*graus</code>.</p> +</div> + +<p>El següent exemple és una mica més complex que el que hem vist anteriorment. Dibuixa 12 arcs diferents, tots amb diferents angles i omplerts.</p> + +<p>Els dos <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for">bucles (loops) </a><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for"><code>for</code></a> són per recórrer les files i columnes dels arcs. Per a cada arc, iniciem una nova trajectòria cridant <code>beginPath()</code>. En el codi, cadascun dels paràmetres de l'arc es troba en una variable per a major claredat, però no necessàriament ho fareu en la vida real.</p> + +<p>Les coordenades <code>x</code> i <code>y</code> han de ser suficientment clares. <code>radius</code> i <code>startAngle</code> són fixes. <code>endAngle</code> comença a 180 graus (mig cercle) en la primera columna i s'incrementa per passos de 90 graus, culminant en un cercle complet en l'última columna</p> + +<p>La instrucció per al paràmetre <code>clockwise</code> (sentit horari), resulti en la primera i la tercera fila que es dibuixin com a arcs en sentit horari i la segona i quarta fila com a arcs en sentit antihorari. Finalment, la sentència <code>if</code> fa que la meitat superior traci els arcs i la meitat inferior ompli els arcs.</p> + +<div class="note"> +<p><strong>Nota:</strong> Aquest exemple requereix un llenç una mica més gran que els altres, en aquesta pàgina: 150 x 200 píxels.</p> +</div> + +<div class="hidden"> +<pre class="brush: html"><html> + <body onload="draw();"> + <canvas id="canvas" width="150" height="200"></canvas> + </body> +</html> +</pre> +</div> + +<pre class="brush: js;highlight[16]">function draw() { + var canvas = document.getElementById('canvas'); + if (canvas.getContext) { + var ctx = canvas.getContext('2d'); + + for (var i = 0; i < 4; i++) { + for (var j = 0; j < 3; j++) { + ctx.beginPath(); + var x = 25 + j * 50; // x coordinate + var y = 25 + i * 50; // y coordinate + var radius = 20; // Arc radius + var startAngle = 0; // Starting point on circle + var endAngle = Math.PI + (Math.PI * j) / 2; // End point on circle + var anticlockwise = i % 2 !== 0; // clockwise or anticlockwise + + ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise); + + if (i > 1) { + ctx.fill(); + } else { + ctx.stroke(); + } + } + } + } +} +</pre> + +<p>{{EmbedLiveSample("Arcs", 160, 210, "https://mdn.mozillademos.org/files/204/Canvas_arc.png")}}</p> + +<h3 id="Corbes_bézier_i_quadràtiques">Corbes bézier i quadràtiques</h3> + +<p>El següent tipus de trajectòries disponibles són les <a href="http://en.wikipedia.org/wiki/B%C3%A9zier_curve">corbes de Bézier</a>, disponibles en varietats cúbiques i quadràtiques. Aquests s'utilitzen generalment per dibuixar formes orgàniques complexes.</p> + +<dl> + <dt>{{domxref("CanvasRenderingContext2D.quadraticCurveTo", "quadraticCurveTo(cp1x, cp1y, x, y)")}}</dt> + <dd>Dibuixa una corba Bézier quadràtica des de la posició actual del llapis fins al punt final especificat per <code>x</code> i <code>y</code>, utilitzant els punts de control especificats per <code>cp1x</code> i <code>cp1y</code>.</dd> + <dt>{{domxref("CanvasRenderingContext2D.bezierCurveTo", "bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)")}}</dt> + <dd>Dibuixa una corba Bézier cúbica des de la posició actual del llapis fins al punt final especificat per <code>x</code> i <code>y</code>, utilitzant els punts de control especificats per (<code>cp1x</code>, <code>cp1y</code>) i (cp2x, cp2y).</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 millor manera de descriure la diferència entre aquestes dues opcions és usant la imatge de la dreta. Una corba Bézier quadràtica té un punt inicial i un punt final (punts blaus) i només un <strong>punt de control</strong> (indicat pel punt vermell), mentre que una corba Bézier cúbica utilitza dos punts de control.</p> + +<p>Els paràmetres <code>x</code> i <code>y</code> de tots dos mètodes són les coordenades del punt final. <code>cp1x</code> i <code>cp1y</code> són les coordenades del primer punt de control, i <code>cp2x</code> i <code>cp2y</code> són les coordenades del segon punt de control.</p> + +<p>L'ús de corbes de Bézier cúbiques i quadràtiques pot ser tot un repte, perquè a diferència del programari de dibuix vectorial com Adobe Illustrator, no tenim respostes visuals directes sobre el que estem fent. Això fa que sigui bastant difícil dibuixar formes complexes. En el següent exemple, dibuixarem algunes formes orgàniques senzilles, però si teniu el temps i, sobretot paciència, es poden crear formes molt més complexes.</p> + +<p>No hi ha res molt difícil en aquests exemples. En tots dos casos veiem una successió de corbes dibuixades que finalment donen com a resultat una forma completa.</p> + +<h4 id="Corbes_de_Bezier_quadràtiques">Corbes de Bezier quadràtiques</h4> + +<p>Aquest exemple usa múltiples corbes de Bézier quadràtiques per representar un globus de diàleg .</p> + +<div class="hidden"> +<pre class="brush: html"><html> + <body onload="draw();"> + <canvas id="canvas" width="150" height="150"></canvas> + </body> +</html> +</pre> +</div> + +<pre class="brush: js;highlight[9,10,11,12,13,14]">function draw() { + var canvas = document.getElementById('canvas'); + if (canvas.getContext) { + var ctx = canvas.getContext('2d'); + + // Quadratric curves example + 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("Quadratic_Bezier_curves", 160, 160, "https://mdn.mozillademos.org/files/243/Canvas_quadratic.png")}}</p> + +<h4 id="Corbes_de_Bezier_cúbiques">Corbes de Bezier cúbiques</h4> + +<p><span id="result_box" lang="ca"><span>Aquest exemple dibuixa un cor utilitzant corbes Bézier cúbiques</span></span>.</p> + +<div class="hidden"> +<pre class="brush: html"><html> + <body onload="draw();"> + <canvas id="canvas" width="150" height="150"></canvas> + </body> +</html> +</pre> +</div> + +<pre class="brush: js;highlight[9,10,11,12,13,14]">function draw() { + var canvas = document.getElementById('canvas'); + if (canvas.getContext) { + var ctx = canvas.getContext('2d'); + + // Cubic curves example + 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("Cubic_Bezier_curves", 160, 160, "https://mdn.mozillademos.org/files/207/Canvas_bezier.png")}}</p> + +<h3 id="Rectangles">Rectangles</h3> + +<p>A més dels tres mètodes que vam veure en {{anch("Drawing rectangles")}}, que dibuixen formes rectangulars directament al llenç, també està el mètode <code>rect()</code>, que afegeix una trajectòria rectangular a una trajectòria actualment oberta.</p> + +<dl> + <dt>{{domxref("CanvasRenderingContext2D.rect", "rect(x, y, width, height)")}}</dt> + <dd>Dibuixa un rectangle a la cantonada superior esquerra especificada per (<code>x</code>, <code>y</code>) amb <code>width</code> i <code>height</code> especificats.</dd> +</dl> + +<p>Quan s'executa aquest mètode, el mètode <code>moveTo()</code> es crida automàticament amb els paràmetres (0,0). En altres paraules, la posició actual del llapis es restableix automàticament a les coordenades predeterminades.</p> + +<h3 id="Fer_combinacions">Fer combinacions</h3> + +<p>Fins ara, cada exemple d'aquesta pàgina només ha utilitzat un tipus de funció de trajectòria per forma. No obstant això, no hi ha limitació en el nombre o tipus de trajectòries que podeu utilitzar per crear una forma. Així, en aquest últim exemple, combinem totes les funcions de trajectòria per crear un conjunt de personatges de joc molt famosos.</p> + +<div class="hidden"> +<pre class="brush: html"><html> + <body onload="draw();"> + <canvas id="canvas" width="150" height="150"></canvas> + </body> +</html> +</pre> +</div> + +<pre class="brush: js">function draw() { + var canvas = document.getElementById('canvas'); + if (canvas.getContext) { + var ctx = canvas.getContext('2d'); + + roundedRect(ctx, 12, 12, 150, 150, 15); + roundedRect(ctx, 19, 19, 150, 150, 9); + roundedRect(ctx, 53, 53, 49, 33, 10); + roundedRect(ctx, 53, 119, 49, 16, 6); + roundedRect(ctx, 135, 53, 49, 33, 10); + roundedRect(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(); + } +} + +// A utility function to draw a rectangle with rounded corners. + +function roundedRect(ctx, x, y, width, height, radius) { + ctx.beginPath(); + ctx.moveTo(x, y + radius); + ctx.lineTo(x, y + height - radius); + ctx.arcTo(x, y + height, x + radius, y + height, radius); + ctx.lineTo(x + width - radius, y + height); + ctx.arcTo(x + width, y + height, x + width, y + height-radius, radius); + ctx.lineTo(x + width, y + radius); + ctx.arcTo(x + width, y, x + width - radius, y, radius); + ctx.lineTo(x + radius, y); + ctx.arcTo(x, y, x, y + radius, radius); + ctx.stroke(); +} +</pre> + +<p><span class="short_text" id="result_box" lang="ca"><span>La imatge resultant és així:</span></span></p> + +<p>{{EmbedLiveSample("Making_combinations", 160, 160, "https://mdn.mozillademos.org/files/9849/combinations.png")}}</p> + +<p>No anem a repassar això detalladament, ja que en realitat és sorprenentment senzill. La cosa més important a destacar és l'ús de la propietat <code>fillStyle</code> en el context del dibuix, i l'ús d'una funció d'utilitat (en aquest cas <code>roundedRect()</code>). L'ús de funcions d'utilitat per als bits del dibuix sovint pot ser molt útil i reduir la quantitat de codi que necessiteu, així com la seva complexitat.</p> + +<p>Tornarem a fer un cop d'ull a <code>fillStyle</code>, en més detall, més endavant en aquest tutorial. Aquí, tot el que fem és usar-ho per canviar el color d'emplenament de les trajectòries del color predeterminat de negre a blanc, i viceversa .</p> + +<h2 id="Objectes_Path2D">Objectes Path2D</h2> + +<p>Com hem vist en l'últim exemple, pot haver-hi una sèrie de trajectories i ordres de dibuix per dibuixar objectes sobre el llenç. Per simplificar el codi i millorar el rendiment, l'objecte {{domxref("Path2D")}} disponible en versions recents dels navegadors, permet emmagatzemar en la memòria cau o gravar aquestes ordres de dibuix. Podeu reproduir les vostres trajectòries ràpidament.<br> + Vegem com podem construir un objecte <code>Path2D</code>:</p> + +<dl> + <dt>{{domxref("Path2D.Path2D", "Path2D()")}}</dt> + <dd>El constructor <code><strong>Path2D()</strong></code> retorna un objecte <code>Path2D</code> recentment instanciat, opcionalment amb una altra trajectòria com a argument (crea una còpia), o opcionalment amb una cadena consistent en dades de <a href="https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths">trajectòria SVG</a>.</dd> +</dl> + +<pre class="brush: js">new Path2D(); // empty path object +new Path2D(path); // copy from another Path2D object +new Path2D(d); // path from SVG path data</pre> + +<p>Tots els <a href="https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D#Paths">mètodes de trajectòria</a> com <code>moveTo</code>, <code>rect</code>, <code>arc</code> o <code>quadraticCurveTo</code>, etc., que hem conegut anteriorment, estan disponibles en els objectes <code>Path2D</code>.</p> + +<p>L'API de <code>Path2D</code> també afegeix una forma de combinar trajectòries utilitzant el mètode <code>addPath</code>. Això pot ser útil quan es desitja construir objectes a partir de diversos components, per exemple.</p> + +<dl> + <dt>{{domxref("Path2D.addPath", "Path2D.addPath(path [, transform])")}}</dt> + <dd>Afegeix una trajectòria a la trajectòria actual amb una matriu de transformació opcional.</dd> +</dl> + +<h3 id="Exemple_de_Path2D">Exemple de Path2D</h3> + +<p>En aquest exemple, estem creant un rectangle i un cercle. Tots dos s'emmagatzemen com un objecte <code>Path2D</code>, de manera que estan disponibles per al seu ús posterior. Amb la nova API <code>Path2D</code>, es van actualitzar diversos mètodes per acceptar opcionalment un objecte <code>Path2D</code> que s'utilitzarà en comptes de la trajectòria actual. Aquí, <code>stroke</code> i <code>fill</code> s'utilitzen amb un argument de trajectòria per dibuixar tots dos objectes sobre el llenç, per exemple.</p> + +<div class="hidden"> +<pre class="brush: html"><html> + <body onload="draw();"> + <canvas id="canvas" width="130" height="100"></canvas> + </body> +</html> +</pre> +</div> + +<pre class="brush: js;highlight[6,9]">function draw() { + var canvas = document.getElementById('canvas'); + if (canvas.getContext) { + var ctx = canvas.getContext('2d'); + + var rectangle = new Path2D(); + rectangle.rect(10, 10, 50, 50); + + var circle = new Path2D(); + circle.moveTo(125, 35); + circle.arc(100, 35, 25, 0, 2 * Math.PI); + + ctx.stroke(rectangle); + ctx.fill(circle); + } +} +</pre> + +<p>{{EmbedLiveSample("Path2D_example", 130, 110, "https://mdn.mozillademos.org/files/9851/path2d.png")}}</p> + +<h3 id="Ús_de_trajectòries_SVG">Ús de trajectòries SVG</h3> + +<p>Una altra característica poderosa de la nova API <code>Path2D</code> de canvas és l'ús de <a href="https://developer.mozilla.org/en-US/docs/Web/SVG/Tutorial/Paths">dades de trajectòria SVG</a> per inicialitzar trajectòries en el seu llenç. Això podria permetre-li passar les dades de trajectòria i reutilitzar-les tant en SVG com en canvas.</p> + +<p>La trajectòria es mourà al punt (<code>M10 10</code>) i després es mourà horitzontalment 80 punts a la dreta (<code>h 80</code>), després 80 punts cap avall (<code>v 80</code>), després 80 punts a l'esquerra (<code>h -80</code>), i després de tornada al principi (<code>z</code>). Podeu veure aquest exemple a la pàgina <a href="/en-US/docs/Web/API/Path2D.Path2D#Using_SVG_paths">constructor</a> <a href="/en-US/docs/Web/API/Path2D.Path2D#Using_SVG_paths"><code>Path2D</code></a>.</p> + +<pre class="brush: js;">var p = new Path2D('M10 10 h 80 v 80 h -80 Z');</pre> + +<div>{{PreviousNext("Web/API/Canvas_API/Tutorial/Basic_usage", "Web/API/Canvas_API/Tutorial/Applying_styles_and_colors")}}</div> |