aboutsummaryrefslogtreecommitdiff
path: root/files/ca/web/api/canvas_api/tutorial/transformacions
diff options
context:
space:
mode:
authorPeter Bengtsson <mail@peterbe.com>2020-12-08 14:41:15 -0500
committerPeter Bengtsson <mail@peterbe.com>2020-12-08 14:41:15 -0500
commit4b1a9203c547c019fc5398082ae19a3f3d4c3efe (patch)
treed4a40e13ceeb9f85479605110a76e7a4d5f3b56b /files/ca/web/api/canvas_api/tutorial/transformacions
parent33058f2b292b3a581333bdfb21b8f671898c5060 (diff)
downloadtranslated-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/transformacions')
-rw-r--r--files/ca/web/api/canvas_api/tutorial/transformacions/index.html290
1 files changed, 290 insertions, 0 deletions
diff --git a/files/ca/web/api/canvas_api/tutorial/transformacions/index.html b/files/ca/web/api/canvas_api/tutorial/transformacions/index.html
new file mode 100644
index 0000000000..2958d40498
--- /dev/null
+++ b/files/ca/web/api/canvas_api/tutorial/transformacions/index.html
@@ -0,0 +1,290 @@
+---
+title: Transformacions
+slug: Web/API/Canvas_API/Tutorial/Transformacions
+tags:
+ - Canvas
+ - Graphics
+ - Guide
+ - HTML
+ - HTML5
+ - Intermediate
+ - Web
+translation_of: Web/API/Canvas_API/Tutorial/Transformations
+---
+<div>{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Using_images", "Web/API/Canvas_API/Tutorial/Compositing")}}</div>
+
+<div class="summary">Anteriorment en aquest tutorial hem après sobre la graella de canvas i l'<strong>espai de coordenades</strong>. Fins ara, només usàvem la graella per defecte i canviàvem la grandària del llenç per a les nostres necessitats. Amb les transformacions, hi ha formes més poderoses de traslladar l'origen a una posició diferent, girar la graella i fins i tot escalar-la.</div>
+
+<h2 id="Saving_and_restoring_state" name="Saving_and_restoring_state">Guardar i restaurar l'estat</h2>
+
+<p>Abans de veure els mètodes de transformació, vegem altres dos mètodes que són indispensables una vegada que comencem a generar dibuixos cada vegada més complexos.</p>
+
+<dl>
+ <dt>{{domxref("CanvasRenderingContext2D.save", "save()")}}</dt>
+ <dd>Guarda tot l'estat del llenç.</dd>
+ <dt>{{domxref("CanvasRenderingContext2D.restore", "restore()")}}</dt>
+ <dd>Restaura l'estat del llenç guardat més recent.</dd>
+</dl>
+
+<p>Els estats del llenç s'emmagatzemen en una pila. Cada vegada que es crida al mètode <code>save()</code> l'estat del dibuix actual es mou a la pila. L'estat d'un dibuix consisteix de</p>
+
+<ul>
+ <li>Les transformacions que s'han aplicat (i.e. <code>translate</code>, <code>rotate</code> i <code>scale</code> – vegeu a continuació).</li>
+ <li>Els valors actuals dels següents atributs: {{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>La <a href="https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Compositing#Clipping_paths">trajectòria de retall</a> actual, que veurem a la següent secció.</li>
+</ul>
+
+<p>Es pot cridar al mètode <code>save()</code> tantes vegades com es vulgui. Cada vegada que es crida al mètode <code>restore()</code> l'últim estat desat s'elimina de la pila i es restauren tots les configuracions guardades.</p>
+
+<h3 id="A_save_and_restore_canvas_state_example" name="A_save_and_restore_canvas_state_example">Un exemple de <code>save</code> i <code>restore</code> de l'estat del llenç</h3>
+
+<p>Aquest exemple intenta il·lustrar com funciona la pila d'estats del dibuix en dibuixar un conjunt de rectangles consecutius.</p>
+
+<pre class="brush: js; highlight:[5,10,15,18]">function draw() {
+ var ctx = document.getElementById('canvas').getContext('2d');
+
+ ctx.fillRect(0, 0, 150, 150); // Dibuixa un rectangle amb la configuració per defecte
+ ctx.save(); // Guarda el estat predeterminat
+
+ ctx.fillStyle = '#09F'; // Es fan canvis a la configuració
+ ctx.fillRect(15, 15, 120, 120); // Es dibuixa un rectangle amb la nova configuració
+
+ ctx.save(); // Es guarda el estat actual
+ ctx.fillStyle = '#FFF'; // Es fan canvis a la configuració
+ ctx.globalAlpha = 0.5;
+ ctx.fillRect(30, 30, 90, 90); // Es dibuixa un rectangle amb la nova configuració
+
+ ctx.restore(); // Es restaura el estat anterior
+ ctx.fillRect(45, 45, 60, 60); // Es dibuixa un rectangle amb la configuració restaurada
+
+ ctx.restore(); // Es restaura el estat original
+ ctx.fillRect(60, 60, 30, 30); // Es dibuixa un rectangle amb la configuració restaurada</pre>
+
+<div class="hidden">
+<pre class="brush: html">&lt;canvas id="canvas" width="150" height="150"&gt;&lt;/canvas&gt;</pre>
+
+<pre class="brush: js">draw();</pre>
+</div>
+
+<p>El primer pas és dibuixar un gran rectangle amb la configuració predeterminada.  A continuació guardem aquest estat i fem canvis en el color de farcit. Després dibuixem el segon rectangle blau i més petit i guardem l'estat. De nou canviem algunes configuracions de dibuix i dibuixem el tercer rectangle blanc semitransparent.</p>
+
+<p>Fins ara, això és bastant similar al que hem fet en les seccions anteriors. No obstant això, una vegada que cridem a la primera instrucció <code>restore()</code> l'estat del dibuix superior s'elimina de la pila i es restaura la configuració. Si no haguéssim guardat l'estat usant <code>save()</code>, hauríem de canviar el color de farcit i la transparència manualment, per tornar a l'estat anterior. Això seria fàcil per a dues propietats, però si tenim més que això, el nostre codi es faria molt llarg, molt ràpid.</p>
+
+<p>Quan es crida a la segona instrucció <code>restore()</code>, es restaura l'estat original (el que hem configurat abans de la primera crida <code>save</code>) i l'últim rectangle es dibuixa de nou en negre.</p>
+
+<p>{{EmbedLiveSample("A_save_and_restore_canvas_state_example", "180", "180", "https://mdn.mozillademos.org/files/249/Canvas_savestate.png")}}</p>
+
+<h2 id="Translating" name="Translating">Traslladar</h2>
+
+<p><img alt="" class="internal" src="https://mdn.mozillademos.org/files/234/Canvas_grid_translate.png" style="float: right;">El primer dels mètodes de transformació que veurem és <code>translate()</code>. Aquest mètode s'utilitza per moure el llenç i el seu origen a un punt diferent de la graella.</p>
+
+<dl>
+ <dt>{{domxref("CanvasRenderingContext2D.translate", "translate(x, y)")}}</dt>
+ <dd>Mou el llenç i el seu origen en la graella. <code>x</code> indica la distància horitzontal a moure, i <code>y</code> indica quanta distància s'ha de moure la graella verticalment.</dd>
+</dl>
+
+<p>És una bona idea guardar l'estat del llenç abans de fer qualsevol transformació. En la majoria dels casos, és més fàcil cridar al mètode <code>restore</code>, que haver de fer una traslació inversa per tornar a l'estat original. També, si estem trasladant dins d'un bucle i no guardem i restaurem l'estat del llenç, pot ser que acabem perdent part del dibuix, ja que es va dibuixar fora de la vora del llenç.</p>
+
+<h3 id="A_translate_example" name="A_translate_example">Un exemple de <code>translate</code></h3>
+
+<p>Aquest exemple demostra alguns dels beneficis de traslladar l'origen del llenç. Sense el mètode <code>translate()</code>, tots els rectangles es dibuixarien en la mateixa posició (0,0). El mètode <code>translate()</code>, també ens dóna la llibertat de col·locar el rectangle en qualsevol lloc del llenç, sense haver d'ajustar manualment les coordenades en la funció <code>fillRect()</code>. Això fa que sigui una mica més fàcil d'entendre i usar.</p>
+
+<p>En la funció <code>draw()</code>, cridem a la funció <code>fillRect()</code> nou vegades, usant dos  bucles <code>for</code>. En cada bucle, el llenç es trasllada, es dibuixa el rectangle i el llenç torna al seu estat original. Observem com la crida a <code>fillRect()</code> usa les mateixes coordenades cada vegada, confiant en <code>translate()</code> per ajustar la posició del dibuix.</p>
+
+<pre class="brush: js; highlight:[7]">function draw() {
+ var ctx = document.getElementById('canvas').getContext('2d');
+ for (var i = 0; i &lt; 3; i++) {
+ for (var j = 0; j &lt; 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">&lt;canvas id="canvas" width="150" height="150"&gt;&lt;/canvas&gt;</pre>
+
+<pre class="brush: js">draw();</pre>
+</div>
+
+<p>{{EmbedLiveSample("A_translate_example", "160", "160", "https://mdn.mozillademos.org/files/9857/translate.png")}}</p>
+
+<h2 id="Rotating" name="Rotating">Girar</h2>
+
+<p><img alt="" class="internal" src="https://mdn.mozillademos.org/files/233/Canvas_grid_rotate.png" style="float: right;">El segon mètode de transformació és <code>rotate()</code>. Se usa per girar el llenç al voltant de l'origen actual.</p>
+
+<dl>
+ <dt>{{domxref("CanvasRenderingContext2D.rotate", "rotate(angle)")}}</dt>
+ <dd>Gira el llenç en sentit horari, al voltant de l'origen actual pel nombre d'<code>angle</code> de radiants.</dd>
+</dl>
+
+<p>El punt central de gir és sempre l'origen del llenç. Per canviar el punt central, necessitarem moure el llenç usant el mètode <code>translate()</code>.</p>
+
+<h3 id="A_rotate_example" name="A_rotate_example">Un exemple de <code>rotate</code></h3>
+
+<p>En aquest exemple, usarem el mètode <code>rotate()</code> para girar primer un rectangle des de l'origen del llenç, i després des del centre del rectangle mateix amb l'ajuda de <code>translate()</code>.</p>
+
+<div class="note">
+<p><strong>Recordatori</strong>: Els angles estan en radiants, no en graus. Per fer la conversació, estem usant: <code>radians = (Math.PI/180)*degrees</code>.</p>
+</div>
+
+<pre class="brush: js; highlight:[9, 23]">function draw() {
+ var ctx = document.getElementById('canvas').getContext('2d');
+
+ // <span class="s3gt_translate_tooltip_variant" id="s3gt_translate_tooltip_variant_to_id_0">rectangles esquerra, giren a partir d'origen del llenç</span>
+ ctx.save();
+ // rect blau
+ ctx.fillStyle = '#0095DD';
+ ctx.fillRect(30, 30, 100, 100);
+ ctx.rotate((Math.PI / 180) * 25);
+ // grey rect
+ ctx.fillStyle = '#4D4E53';
+ ctx.fillRect(30, 30, 100, 100);
+ ctx.restore();
+
+ // <span class="s3gt_translate_tooltip_variant" id="s3gt_translate_tooltip_variant_to_id_0">rectangles drets, giren des del centre del rectangle</span>
+ // dibuixa rect blau
+ ctx.fillStyle = '#0095DD';
+ ctx.fillRect(150, 30, 100, 100);
+
+ ctx.translate(200, 80); // trasllada al rectangle central
+ // x = x + 0.5 * width
+ // y = y + 0.5 * height
+ ctx.rotate((Math.PI / 180) * 25); // gira
+ ctx.translate(-200, -80); // traslladar de nou
+
+ // dibuixa rect gris
+ ctx.fillStyle = '#4D4E53';
+ ctx.fillRect(150, 30, 100, 100);
+}
+</pre>
+
+<p>Per girar el rectangle al voltant del seu propi centre, traslladem el llenç al centre del rectangle, després girem el llenç i tornem a traslladar el llenç a 0,0, i a continuació dibuixem el rectangle.</p>
+
+<div class="hidden">
+<pre class="brush: html">&lt;canvas id="canvas" width="300" height="200"&gt;&lt;/canvas&gt;</pre>
+
+<pre class="brush: js">draw();</pre>
+</div>
+
+<p>{{EmbedLiveSample("A_rotate_example", "310", "210", "https://mdn.mozillademos.org/files/9859/rotate.png")}}</p>
+
+<h2 id="Scaling" name="Scaling">Escalar</h2>
+
+<p>El següent mètode de transformació és l'escalat. Ho usem per augmentar o disminuir les unitats en la graella del llenç. Això es pot utilitzar per dibuixar formes i mapes de bits reduïts o ampliats.</p>
+
+<dl>
+ <dt>{{domxref("CanvasRenderingContext2D.scale", "scale(x, y)")}}</dt>
+ <dd>Escala les unitats del llenç, per x horitzontalment i per y verticalment. Tots dos paràmetres són nombres reals. Els valors inferiors a 1.0 redueixen la grandària de la unitat i els valors superiors a 1.0 augmenten la grandària de la unitat. Els valors a 1.0 deixen les unitats de la mateixa grandària.</dd>
+</dl>
+
+<p>Usant nombres negatius es pot fer la replica d'eixos (per exemple, usant <code>translate(0,canvas.height); scale(1,-1);</code> tindrem el conegut sistema de coordenades cartesianes, amb l'origen en la cantonada inferior esquerra).</p>
+
+<p>Per defecte, una unitat en el llenç és exactament un píxel. Si apliquem, per exemple, un factor d'escala de 0.5, la unitat resultant es convertirà en 0.5 píxels i per tant les formes es dibuixaran a meitat de la seva grandària. De manera similar, si s'ajusta el factor d'escala a 2.0, la grandària de la unitat augmentarà i una unitat ara es converteix en dos píxels. Això dona com a resultat que les formes es dibuixin dues vegades més grans.</p>
+
+<h3 id="A_scale_example" name="A_scale_example">Un exemple de <code>scale</code></h3>
+
+<p><span class="s3gt_translate_tooltip_variant" id="s3gt_translate_tooltip_variant_to_id_0">En aquest últim exemple, dibuixarem formes amb diferents factors d'escala.</span></p>
+
+<pre class="brush: js; highlight:[6,11]">function draw() {
+ var ctx = document.getElementById('canvas').getContext('2d');
+
+ // <span class="short_text" id="result_box" lang="ca"><span>dibuixar un rectangle senzill, però escalar-lo</span></span>.
+ 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">&lt;canvas id="canvas" width="150" height="150"&gt;&lt;/canvas&gt;</pre>
+
+<pre class="brush: js">draw();</pre>
+</div>
+
+<p>{{EmbedLiveSample("A_scale_example", "160", "160", "https://mdn.mozillademos.org/files/9861/scale.png")}}</p>
+
+<h2 id="Transforms" name="Transforms">Transformar</h2>
+
+<p>Finalment, els següents mètodes de transformació permeten modificar directament la matriu de transformació.</p>
+
+<dl>
+ <dt>{{domxref("CanvasRenderingContext2D.transform", "transform(a, b, c, d, e, f)")}}</dt>
+ <dd>Multiplica la matriu de transformació actual amb la matriu descrita pels seus arguments. La matriu de transformació és descrita per: <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 &amp; c &amp; e \\ b &amp; d &amp; f \\ 0 &amp; 0 &amp; 1 \end{array} \right]</annotation></semantics></math></dd>
+</dl>
+
+<dl>
+ <dd>Si qualsevol dels arguments és <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Infinity" title="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Infinity">Infinity</a></code>, la matriu de transformació ha de ser marcada com a infinita en lloc que el mètode llanci una excepció.</dd>
+</dl>
+
+<p>Els paràmetres d'aquesta funció són:</p>
+
+<dl>
+ <dt><code>a (m11)</code></dt>
+ <dd>Escalat horitzontal.</dd>
+ <dt><em><code>b (m12)</code></em></dt>
+ <dd>Desviació Horizontal.</dd>
+ <dt><code>c (m21)</code></dt>
+ <dd>Desviació Vertical.</dd>
+ <dt><code>d (m22)</code></dt>
+ <dd>Escalat Vertical.</dd>
+ <dt><code>e (dx)</code></dt>
+ <dd>Moviment Horizontal.</dd>
+ <dt><code>f (dy)</code></dt>
+ <dd>Moviment Vertical.</dd>
+ <dt>{{domxref("CanvasRenderingContext2D.setTransform", "setTransform(a, b, c, d, e, f)")}}</dt>
+ <dd>Reinicia la transformació actual a la matriu d'identitat i, a continuació, invoca el mètode <code>transform()</code> amb els mateixos arguments. Això, bàsicament, desfà la transformació actual, i després estableix la transformació especificada, tot en un sol pas.</dd>
+ <dt>{{domxref("CanvasRenderingContext2D.resetTransform", "resetTransform()")}}</dt>
+ <dd>Reinicia la transformació actual a la matriu d'identitat. Això és el mateix que cridar: <code>ctx.setTransform(1, 0, 0, 1, 0, 0);</code></dd>
+</dl>
+
+<h3 id="Exemple_de_transform_i_setTransform">Exemple de <code>transform</code> i <code>setTransform</code></h3>
+
+<pre class="brush: js; highlight:[12,15]">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 &lt;= 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">&lt;canvas id="canvas" width="200" height="250"&gt;&lt;/canvas&gt;</pre>
+
+<pre class="brush: js">draw();</pre>
+</div>
+
+<p>{{EmbedLiveSample("Example_for_transform_and_setTransform", "230", "280", "https://mdn.mozillademos.org/files/255/Canvas_transform.png")}}</p>
+
+<p>{{PreviousNext("Web/API/Canvas_API/Tutorial/Using_images", "Web/API/Canvas_API/Tutorial/Compositing")}}</p>
+
+<div class="s3gt_translate_tooltip_mini_box" id="s3gt_translate_tooltip_mini" style="position: absolute; left: 224px; top: 1401px; opacity: 0;">
+<div class="s3gt_translate_tooltip_mini" id="s3gt_translate_tooltip_mini_logo" title="Traducir texto seleccionado"> </div>
+
+<div class="s3gt_translate_tooltip_mini" id="s3gt_translate_tooltip_mini_sound" title="Reproducir"> </div>
+
+<div class="s3gt_translate_tooltip_mini" id="s3gt_translate_tooltip_mini_copy" title="Copy text to Clipboard"> </div>
+</div>