aboutsummaryrefslogtreecommitdiff
path: root/files/pt-br/web/api/canvas_api/tutorial/basic_animations/index.html
blob: c98ebe0625a245f4f691436f20a393b4cacefddc (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
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
---
title: Basic animations
slug: Web/API/Canvas_API/Tutorial/Basic_animations
translation_of: Web/API/Canvas_API/Tutorial/Basic_animations
original_slug: Web/Guide/HTML/Canvas_tutorial/Basic_animations
---
<p>Já que estamos usando JavaScript para controlar {{HTMLElement("canvas")}} elementos, também é muito fácil criar animações interativas. Fazer animações mais complexas pode levar um tempo extra; esperamos introduzir um novo artigo para auxiliar sobre isso em breve.</p>

<p>Provavelmente a maior limitação é que uma vez que uma forma é desenhada, ela permanece assim. Se precisarmos mover, temos que redesenhar-lá e tudo que foi desenhado antes. Demora muito tempo pra redesenhar frames complexos e a desempenho depende altamente da velocidade do computador em que está rodando.</p>

<h2 id="Basic_animation_steps" name="Basic_animation_steps">Passos para animação básica</h2>

<p>Estes são os passos que você precisa para desenhar um frame:</p>

<ol>
 <li><strong>Limpe o canvas</strong><br>
  A menos que a forma que você vai desenhar preencha o canvas completo(por exemplo, uma imagem de fundo), você precisa limpar todas as formas que foram desenhadas anteriormente. O caminho mais fácil para fazer isso é usando o método clearRect().</li>
 <li><strong>Salve o estado da tela</strong><br>
  Se você estiver mudando alguma configuração(como estilos, transformações, etc.) que afete o estado do canvas e você quer garantir que o estado original seja usado sempre que um quadro é desenhado, você precisa salvar esse estado original.</li>
 <li><strong>Desenhe formas animadas</strong><br>
  A etapa em que você faz a renderização real do quadro.</li>
 <li><strong>Restaure o estado do canvas</strong><br>
  Se você salvou o estado, restaure-o antes de desenhar um novo quadro.</li>
</ol>

<h2 id="Controlling_an_animation" name="Controlling_an_animation">Controlando uma animação</h2>

<p>Formas são desenhos na tela usando os canvas métodos diretamente ou chamando personalizadas. Em circunstancias normais, nós somente vemos esses resultados aparecerem na tela quando o script termina de ser executado. Por exemplo, não é possível fazer uma animação dentro de um loop for.</p>

<p>Isso significa que precisamos de um jeito para executar nossas funções de desenho durante um período de tempo. Existem dois jeitos para controlar uma animação como essa.</p>

<h3 id="Atualizações_agendadas">Atualizações agendadas</h3>

<p>Primeiramente há as funções {{domxref("window.setInterval()")}} e {{domxref("window.setTimeout()")}}, que podem ser usadas para chamar uma função específica durante um certo período definido de tempo.</p>

<div class="note">
<p>Nota: O método {{domxref("window.requestAnimationFrame()")}} agora é a maneira recomendada de programar animações. Vamos atualizar esse tutorial para abortar isso em breve.</p>
</div>

<dl>
 <dt><code>setInterval(<em>função</em>,<em>atraso</em>)</code></dt>
 <dd>Inicia repetidamente executando a função específica pela função a cada milissegundo de atraso.</dd>
 <dt><code>setTimeout(<em>função</em>,<em>atraso</em>)</code></dt>
 <dd>Executa a função especificada pela função em milissegundos de atraso.</dd>
</dl>

<p>Se você não quer nenhuma interação do usuário, é melhor usar a função setInterval() que executa repeditamente o código fornecido.</p>

<h3 id="Atualizar_na_interação_do_usuário">Atualizar na interação do usuário</h3>

<p>O segundo método que nós podemos usar para controlar uma animação é a entrada do usuário. Se nós quiséssimos criar um jogo, nós poderiamos usar os eventos do teclado ou mouse para controlar a animação. Ao definir {{domxref("EventListener")}}s, nós pegamos qualquer interação do usuário e executamos nossas funções da animação. </p>

<p>Se você quer a interação do usuário, você pode usar uma versão menor ou a versão principal do nosso framework pra animação:</p>

<pre>var myAnimation = new MiniDaemon(null, animateShape, 500, Infinity);</pre>

<p>ou</p>

<pre>var myAnimation = new Daemon(null, animateShape, 500, Infinity);</pre>

<p>Nos exemplos abaixo, no entanto, usamos o método {{domxref("window.setInterval()")}} para controlar a animação. Na parte inferior dessa página há alguns links de exemplos que usam {{domxref("window.setTimeout()")}}.</p>

<h4 id="Um_sistema_solar_animado">Um sistema solar animado</h4>

<p>Esse exemplo anima um pequeno modelo do nosso sistema solar.</p>

<pre class="brush: js">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';
  setInterval(draw,100);
}

function draw() {
  var ctx = document.getElementById('canvas').getContext('2d');

  ctx.globalCompositeOperation = 'destination-over';
  ctx.clearRect(0,0,300,300); // clear canvas

  ctx.fillStyle = 'rgba(0,0,0,0.4)';
  ctx.strokeStyle = 'rgba(0,153,255,0.4)';
  ctx.save();
  ctx.translate(150,150);

  // Earth
  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); // Shadow
  ctx.drawImage(earth,-12,-12);

  // Moon
  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); // Earth orbit
  ctx.stroke();

  ctx.drawImage(sun,0,0,300,300);
}
</pre>

<div class="hidden">
<pre class="brush: html">&lt;canvas id="canvas" width="300" height="300"&gt;&lt;/canvas&gt;</pre>

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

<p>{{EmbedLiveSample("An_animated_solar_system", "310", "310", "https://mdn.mozillademos.org/files/202/Canvas_animation1.png")}}</p>

<h4 id="Um_relógio_animado">Um relógio animado</h4>

<p>Esse exemplos desenha um relógio animado, mostrando sua hora atual.</p>

<pre class="brush: js">function init(){
  clock();
  setInterval(clock,1000);
}

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";

  // Hour marks
  ctx.save();
  for (var i=0;i&lt;12;i++){
    ctx.beginPath();
    ctx.rotate(Math.PI/6);
    ctx.moveTo(100,0);
    ctx.lineTo(120,0);
    ctx.stroke();
  }
  ctx.restore();

  // Minute marks
  ctx.save();
  ctx.lineWidth = 5;
  for (i=0;i&lt;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&gt;=12 ? hr-12 : hr;

  ctx.fillStyle = "black";

  // write Hours
  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();

  // write 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();

  // Write seconds
  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();
}</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">init();</pre>
</div>

<p>{{EmbedLiveSample("An_animated_clock", "180", "180", "https://mdn.mozillademos.org/files/203/Canvas_animation2.png")}}</p>

<h4 id="Um_panorama_em_loop">Um panorama  em loop</h4>

<p>Nesse exemplos, um panorama é rolado da esquerda pra direita. Nós estamos usando uma imagem do Parque Nacional de Yosemite que tiramos da Wikipedia, mas você pode usar qualquer imagem que fosse maior que a tela.</p>

<pre class="brush: js">var img = new Image();

// User Variables - customize these to change the image being scrolled, its
// direction, and the speed.

img.src = 'https://mdn.mozillademos.org/files/4553/Capitan_Meadows,_Yosemite_National_Park.jpg';
var CanvasXSize = 800;
var CanvasYSize = 200;
var speed = 30; //lower is faster
var scale = 1.05;
var y = -4.5; //vertical offset

// Main program

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 &gt; CanvasXSize) { x = CanvasXSize-imgW; } // image larger than canvas
    if (imgW &gt; CanvasXSize) { clearX = imgW; } // image larger than canvas
    else { clearX = CanvasXSize; }
    if (imgH &gt; CanvasYSize) { clearY = imgH; } // image larger than canvas
    else { clearY = CanvasYSize; }
    //Get Canvas Element
    ctx = document.getElementById('canvas').getContext('2d');
    //Set Refresh Rate
    return setInterval(draw, speed);
}

function draw() {
    //Clear Canvas
    ctx.clearRect(0,0,clearX,clearY);
    //If image is &lt;= Canvas Size
    if (imgW &lt;= CanvasXSize) {
        //reset, start from beginning
        if (x &gt; (CanvasXSize)) { x = 0; }
        //draw aditional image
        if (x &gt; (CanvasXSize-imgW)) { ctx.drawImage(img,x-CanvasXSize+1,y,imgW,imgH); }
    }
    //If image is &gt; Canvas Size
    else {
        //reset, start from beginning
        if (x &gt; (CanvasXSize)) { x = CanvasXSize-imgW; }
        //draw aditional image
        if (x &gt; (CanvasXSize-imgW)) { ctx.drawImage(img,x-imgW+1,y,imgW,imgH); }
    }
    //draw image
    ctx.drawImage(img,x,y,imgW,imgH);
    //amount to move
    x += dx;
}
</pre>

<p>Abaixo é o {{HTMLElement("canvas")}} em que a imagem é rolada. Note que a largura e a altura especificadas aqui devem corresponder aos valores das variáveis ​​CanvasXZSize e CanvasYSize no código JavaScript. </p>

<pre class="brush: html">&lt;canvas id="canvas" width="800" height="200"&gt;&lt;/canvas&gt;</pre>

<p><strong>Live sample</strong></p>

<p>{{EmbedLiveSample("A_looping_panorama", "830", "230")}}</p>

<h2 id="Other_examples" name="Other_examples">Outros exemplos</h2>

<dl>
 <dt><a class="external" href="http://www.gartic.net/">Gartic</a></dt>
 <dd>Jogo de desenho para multiplayers.</dd>
 <dt><a class="external" href="http://www.abrahamjoffe.com.au/ben/canvascape/">Canvascape</a></dt>
 <dd>Um jogo de aventura 3D (tiro em primeira pessoa).</dd>
 <dt><a href="/en-US/docs/Web/Guide/HTML/A_basic_ray-caster" title="/en-US/docs/Web/Guide/HTML/A_basic_ray-caster">A basic ray-caster</a></dt>
 <dd>Um bom exemplo de como fazer animações usando os controles do teclado.</dd>
 <dt><a class="external" href="http://andrewwooldridge.com/canvas/canvasgame001/canvasgame002.html">canvas adventure</a></dt>
 <dd>Outro bom exemplo que usa controles de teclado.</dd>
 <dt><a class="external" href="http://www.blobsallad.se/">An interactive Blob</a></dt>
 <dd>Divirta-se com Blob.</dd>
 <dt><a class="external" href="http://arapehlivanian.com/wp-content/uploads/2007/02/canvas.html">Flying through a starfield</a></dt>
 <dd>Voe através de estrelas, círculos ou quadrados.</dd>
 <dt><a class="external" href="http://igrapher.com/">iGrapher</a></dt>
 <dd>Um exemplo que ilustra os dados do mercado de ações.</dd>
</dl>

<h2 id="Veja_também">Veja também</h2>

<ul>
 <li><a href="/en-US/docs/JavaScript/Timers" title="/en-US/docs/JavaScript/Timers">JavaScript timers</a></li>
 <li><a href="/en-US/docs/DOM/window.setInterval#A_little_framework" title="/en-US/docs/DOM/window.setInterval#A_little_framework"><code>setInterval</code> – A little framework</a></li>
 <li><a href="/en-US/docs/JavaScript/Timers/Daemons" title="/en-US/docs/JavaScript/Timers/Daemons">JavaScript Daemons Management</a></li>
 <li><a href="/en-US/docs/DOM/HTMLCanvasElement" title="/en-US/docs/DOM/HTMLCanvasElement">HTMLCanvasElement</a></li>
</ul>

<p>{{PreviousNext("Web/Guide/HTML/Canvas_tutorial/Compositing", "Web/Guide/HTML/Canvas_tutorial/Optimizing_canvas")}}</p>