aboutsummaryrefslogtreecommitdiff
path: root/files/es/web/api/canvas_api/tutorial/compositing/index.html
blob: 1d45712fd4090f5c6d37342af62047563e4f96e2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
---
title: Compositing and clipping
slug: Web/API/Canvas_API/Tutorial/Compositing
tags:
  - Canvas
  - Graphics
  - HTML
  - HTML5
  - Intermediate
  - Lienzo
  - NeedsTranslation
  - Recorte
  - TopicStub
  - Tutorial
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>En todos nuestros <a href="/en-US/docs/Web/API/Canvas_API/Tutorial/Transformations">ejemplos a</a>nteriores, las formas siempre fueron dibujadas una encima de la anterior. Estos es más que adecuado para la mayoría de las situaciones pero se limita al orden compuesto de las figuras. Podemos, sin embargo, cambiar este comportamiento estableciendo  el valor de la propiedad <code>globalCompositeOperation</code>. Además, la proeidad <code>clip</code> nos permite ocultar partes de figuras que no queremos mostrar.</p>
</div>

<h2 id="globalCompositeOperation" name="globalCompositeOperation"><code>globalCompositeOperation</code></h2>

<p>No solo podemos dibujar formas nuevas detrás de las ya existentes sino que las podemos utilizar para enmascarar ciertas áreas, limpiar secciones del lienzo (canvas no se limita a utilizar rectángulos como en el método {{domxref("CanvasRenderingContext2D.clearRect", "clearRect()")}}) y algunas cosas más.</p>

<dl>
 <dt>{{domxref("CanvasRenderingContext2D.globalCompositeOperation", "globalCompositeOperation = type")}}</dt>
 <dd>Esto establece el tipo de operación compuesta a aplicar cuando se dibujan nuevas figuras, en donde tipo (type) es una cadena de caracteres que identifica cual de las doce operaciones compuestas se utilizará.</dd>
</dl>

<p>Vea <a href="/en-US/docs/Web/API/Canvas_API/Tutorial/Compositing/Example">ejemplos de composición</a> para el código de los siguientes ejemplos.</p>

<p>{{EmbedLiveSample("Compositing_example", 750, 6750, "" ,"Web/API/Canvas_API/Tutorial/Compositing/Example")}}</p>

<h2 id="Clipping_paths" name="Clipping_paths">Trazado de Recorte</h2>

<p><img alt="" class="internal" src="https://mdn.mozillademos.org/files/209/Canvas_clipping_path.png" style="float: right;">Un trazado de recoirte es como una figura normal en el lienzo pero actúa como una máscara para ocultar las partes de la misma que no se quieren mostrar. Este efecto se muestra en la figura de la derecha. La estrella roja es nuestro trazado de recorte. Todo lo que cae fuera de este trazado no se dibujará en el lienzo.</p>

<p>Si comparamos el trazado de recorte con la propiedad <code>globalCompositeOperation</code> que hemos visto antes, vemos dos modos compuestos que logran mas o menos los mismos efectos en <code>source-in</code> y <code>source-atop</code>. Las diferencias mas importantes entre éstos dos son que el trazado de recorte no dibujan nunca en el lienzo y que nunca se afecta por agregar nuevas figuras. Esto vuelve al trazado de recorte ideal para dibujar múltiples figuras en un área delimitada.</p>

<p>En el capítulo acerca de <a href="/en-US/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes" title="Web/Guide/HTML/Canvas_tutorial/Drawing_shapes#Drawing_paths">dibujo de figuras</a> solo menciono a los métodos <code>stroke()</code> y <code>fill()</code> pero existe un tercer método que se usa para trazados llamado <code>clip()</code>.</p>

<dl>
 <dt>{{domxref("CanvasRenderingContext2D.clip", "clip()")}}</dt>
 <dd>Convierte al trazado en ejecución a un trazado de recorte.</dd>
</dl>

<p>Se utiliza <code>clip()</code> en lugar de <code>closePath()</code> para cerrar el trazado y volverlo uno de recorte, en vez de marcar (stroke) o rellenar el trazado.</p>

<p>Por edfecto el elemento {{HTMLElement("canvas")}} tiene un trazado de recorte que es de extacamente el mismo tamaño del propio lienzo. En otras palabras, la máscara de recorte (clipping) no se da.</p>

<h3 id="A_clip_example" name="A_clip_example">Un ejemplo de <code>clip</code></h3>

<p>En este ejemplo, utilizamos un trazado de recorte de forma circular para restringir el dibujo de un conjunto de estrellas aleatorias dentro de una región particular del lienzo.</p>

<pre class="brush: js;highlight[9] notranslate">function dibuja() {
  var ctx = document.getElementById('lienzo').getContext('2d');
  ctx.fillRect(0, 0, 150, 150);
  ctx.translate(75, 75);

  // crear un trazado de corte de forma circular
  ctx.beginPath();
  ctx.arc(0, 0, 60, 0, Math.PI * 2, true);
  ctx.clip();

  // pinta el fondo
  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);

  // dibuja las estrellas
  for (var j = 1; j &lt; 50; j++) {
    ctx.save();
    ctx.fillStyle = '#fff';
    ctx.translate(75 - Math.floor(Math.random() * 150),
                  75 - Math.floor(Math.random() * 150));
    dibulaEstrella(ctx, Math.floor(Math.random() * 4) + 2);
    ctx.restore();
  }

}

function dibujaEstrella(ctx, r) {
  ctx.save();
  ctx.beginPath();
  ctx.moveTo(r, 0);
  for (var i = 0; i &lt; 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">&lt;canvas id="lienzo" width="150" height="150"&gt;&lt;/canvas&gt;</pre>

<pre class="brush: js notranslate">dibuja();</pre>
</div>

<p>En las primeras líneas de código, dibujamos un rectángulo negro del tamaño del lienzo como telón de fondo, luego trasladamos el origen del mismo al centro. A continuación, creamos un trazado de recorte de forma circular, a través de dibujar un arco y mediante la llamada a <code>clip()</code>. El recorte también es parte del estado guardado del lienzo. Si queremos mantener el recorte original, podríamos haber guardado el estado anterior del lienzo justo antes de que creamos el nuevo.</p>

<p>Todo lo que se dibuja después de crear un recorte aparecerá dentro de su trazado. Se puede ver claramente esto en el dibujo de gradiente lineal que realizamos a continuación. Después se ubican estrellas en 50 posiciones alteatorias y escaladas utilizando la función <code>drawStar()</code>. Una vez más, las estrellas solo aparecen dentro del recorte trazado  en el lienzo.</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>