Utilização básica do Canvas - APIs da Web

Utilização básica do Canvas
===========================

 * « Previous
* Next »

Vamos começar este tutorial olhando para o elemento `<canvas>` HTML em si. No final desta página, você saberá como configurar um contexto de canvas 2D e desenhar um primeiro exemplo em seu navegador.O elemento `<canvas>`
---------------------

Vamos começar esse tutorial olhando o elemento `<canvas>` em si.

```html
<canvas id="tutorial" width="150" height="150"></canvas>
```

Se parece muito com o elemento `<img>`com a diferença de não possuir os atributos `src` e `alt`. O elemento `<canvas>` tem apenas dois atributos - **width** e **height**. Ambos são opcionais e podem ser aplicados utilizando as propriedades DOM (en-US) respectivas. Se não forem especificados, o canvas será iniciado com **300 *pixels*** de largura por **150 *pixels*** de altura. O elemento pode ser redimensionado por CSS, mas durante a renderização a imagem é escalonada para caber no tamanho do layout.

**Nota:** Se as suas renderizações parecerem distorcidas, tente especificar os atributos `width` e `height` no `<canvas>` e não usando CSS.

O atributo `id` não é específico do elemento `<canvas>` mas um dos atributos padrão do HTML que pode ser aplicado em (quase) todos os elementos HTML (como o *`class`* por exemplo). É sempre uma boa ideia inserir um `id` pois fica muito mais fácil de capturar o elemento no seu *script.*

O elemento `<canvas>` pode ser estilizado como qualquer imagem (margem, borda, fundo, etc). Contudo, essas regras não afetarão o desenho no canvas. Nós veremos como isso é feito a seguir nesse tutorial. Quando nenhuma regra de estilo for aplicada, o canvas iniciará totalmente transparente.

### Conteúdo alternativo

Uma vez que alguns navegadores mais antigos (em particular, versões do Internet Explorer anteriores a 9) não suportam o elemento `<canvas>`, você precisará prover um conteúdo alternativo para ser mostrado nesses navegadores.

Isto é muito simples: basta inserir o conteúdo alternativo dentro do elemento `<canvas>`. Navegadores que não suportam o `<canvas>` irão renderizar o conteúdo alternativo. Já os navegadores que suportam `<canvas>` irão ignorar o conteúdo alternativo, renderizando o canvas normalmente.

Por exemplo, podemos prover um texto descritivo do canvas ou uma imagem estática do conteúdo. Algo como isto:

```html
<canvas id="stockGraph" width="150" height="150">
  preço das ações: $3.15 +0.15
</canvas>

<canvas id="clock" width="150" height="150">
  <img src="images/clock.png" width="150" height="150" alt="" />
</canvas>
```

### Tag `</canvas>` é necessária

Ao contrário do elemento `<img>`, o elemento `<canvas>` a tag de fechamento (`</canvas>`) é necessária.

**Nota:** Embora as primeiras versões do navegador Safari da Apple não exijam a tag de fechamento, a especificação indica que ela é necessária para que haja maior compatibilidade, portanto não se esqueça de incluí-la. Essas versões do Safari (antes da versão 2.0) irão processar o conteúdo do alternativo, além da própria tela, a menos que você use o CSS para mascará-lo. Felizmente, os usuários dessas versões do Safari são raros hoje em dia.

Se o conteúdo alternativo não for necessário, um simples `<canvas id="foo" ...></canvas>` é totalmente compatível com todos os navegadores que suportam canvas.

O contexto de renderização
--------------------------

`<canvas>` cria uma superfície de desenho de tamanho fixo que expõe um ou mais contextos de renderização, que são usados para criar e manipular o conteúdo mostrado. Vamos nos concentrar no contexto de renderização 2D. Outros contextos podem fornecer diferentes tipos de renderização; por exemplo, WebGL usa um contexto 3D ("experimental-WebGL") baseado em OpenGL ES.

Inicialmente o canvas é branco. Para mostrar alguma coisa, primeiro um *script* precisa acessar o contexto de renderização e desenhar sobre ele. O elemento `<canvas>` tem um método (en-US) chamado `getContext()`, usado para obter o contexto de renderização e suas funções de desenho. `getContext()` recebe o tipo de contexto como parâmetro. Para gráficos 2D, que serão abrangidos nesse tutorial, deverá ser especificado "2d".

```js
var canvas = document.getElementById("tutorial");
var ctx = canvas.getContext("2d");
```

A primeira linha recupera o nó DOM do elemento `<canvas>` chamando o método `document.getElementById()`. Depois de ter o nó do elemento, podemos acessar o contexto de desenho usando o método `getContext()`.

Verificação de suporte
----------------------

O conteúdo alternativo é mostrado nos navegadores que não suportam o elemento `<canvas>`, mas essa checagem pode ser feita através de um *script* simplesmente testando a presença do método `getContext()`:

```js
var canvas = document.getElementById("tutorial");

if (canvas.getContext) {
  var ctx = canvas.getContext("2d");
  // codigo de desenho aqui
} else {
  // codigo para quando o canvas nao for suportado aqui
}
```

Um modelo de estrutura
----------------------

Aqui, um modelo minimalista, que vamos usar como ponto de partida para os exemplos posteriores:

**Nota:** não é uma boa prática incorporar um script dentro do HTML. Nós fazemos isso aqui para manter o exemplo conciso.

```html
<html>
  <head>
    <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>
```

O *script* inclui a função chamada draw(), que é executada uma vez ao término do carregamento da página; este exemplo usa o evento *onload* do documento. Essa função, ou uma parecida, poderia usar `window.setTimeout()` (en-US), `window.setInterval()` (en-US), ou qualquer outro manipulador de evento, contanto que a página tenha sido carregada primeiro.

Um simples exemplo
------------------

Para começar, vamos dar uma olhada num exemplo simples que desenha a interseção de dois retângulos, dos quais um deles tem uma transparência. Exploraremos em mais detalhes o funcionamento nos exemplos posteriores.

```html
<html>
  <head>
    <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, 55, 50);

 ctx.fillStyle = "rgba(0, 0, 200, 0.5)";
 ctx.fillRect(30, 30, 55, 50);
 }
 }
 </script>
  </head>
  <body onload="draw();">
    <canvas id="canvas" width="150" height="150"></canvas>
  </body>
</html>
```

Este exemplo parece assim:

| Screenshot | Live sample |
| --- | --- |
|  |  |

* « Previous
* Next »


Compositing and clipping - APIs da Web

Compositing and clipping
========================

* « Previous (en-US)
* Next »

Em todo os nossos exemplos prévios (en-US), formas estavam sempre desenhadas uma em cima das outras. Este é mais do que adequado para a maioria das situações, mas é limita a ordem no qual a composição das formas são construídas.

Nós podemos, no entanto, mudar este comportamento por configurar a propriedade `globalCompositeOperation`. Além disto, a propriedade clipe permite-nos esconder indesejáveis partes da forma.

`globalCompositeOperation`
--------------------------

Nós podemos somente desenhar novas formas atrás das existentes formas mas nós podemos também usar isto para mascarar certas áreas, limpar seções do canvas(não limitado para retângulos como o `clearRect()` métodos faz) e mais.

`globalCompositeOperation = type`

Este conjunto de operações compostas para aplicar quando desenha novas formas, onde type é uma string identificando quais das 12 operações compostas usar.

Veja os seguintes exemplos de composição para o código dos seguintes exemplos.

Caminhos de recorte (Clipping path)
-----------------------------------

![](/pt-BR/docs/Web/API/Canvas_API/Tutorial/Compositing/canvas_clipping_path.png)Um caminho de recorte (Clipping path) é como uma forma normal canvas mas isto age como uma máscara para esconder indesejáveis partes de formas. Isto é visualizado na imagem na direita. A forma da estrela vermelha é nosso caminho de recorte. Tudo que cai do lado de fora deste caminho não sai desenhado no canvas.

Se nós compararmos caminho de recorte para a propriedade `globalCompositeOperation` nós temos visto acima, nós veremos dois modelos de composição que alcança mais ou menos o mesmo efeito no source-in e source-atop. A mais importante diferença entre os dois é que o caminho de recorte nunca desenha algo na tela e o caminho de recorte nunca afeta por adicionar novas formas. Isto faz o caminho do recorte ideal para desenhar múltiplos na área restrita.

No capítulo sobre formas de desenho (drawing shapes) eu somente mencionei os métodos stroke() e fill(), mas há um método que nós podemos usar com caminhos chamado clip().

`clip()`

Volta o caminho atualmente sendo construído no caminho de recorte atual.

Você usou clip() em vez de closePath() para fechar um caminho e voltar para dentro de um caminho de recorte em vez de contornar (stroking) ou completar (filling) o caminho.

Por padrão o elemento `<canvas>` tem um caminho de recorte que é exatamente o mesmo tamanho do canvas em si. Em outras palavras, nenhum recorte ocorreu.

### Um exemplo do recorte

Neste exemplo, Nós usaremos um recorte circular para restringir o desenho do conjunto de inícios randômicos para uma região particular

```js
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();
}
```

```
canvas id="canvas" width="150" height="150" /canvas
```

```
draw();
```

Nas primeiras linhas de código, nós desenhamos um retângulo negro do tamanho do canvas como um pano de fundo, então traduzido da origem para o centro. Próximo, nós criamos o recorte circular do caminho recortado para desenhar um arco e chamá-lo clip(). Caminho de recortes são também parte do canvas com estado salvo. Se nós procuramos guardar o caminho do recorte original nós podemos ter salvo o estado do canvas antes de criar mais um.

Tudo que for desenhado depois de criado o caminho de recorte somente aparecerá dentro daquele caminho. Você pode ver isto claramente no gradiente linear que está desenhado adiante. Depois deste conjunto de de 50 randomicamente posicionadas e escaladas estrelas for desenhada. Usando a função customizada drawStar(). De novo as estrelas somente aparecerão dentro do caminho de recorte definido.

Um exemplo de recorte:

![](/pt-BR/docs/Web/API/Canvas_API/Tutorial/Compositing/canvas_clip.png)

| Screenshot | Live sample |
| --- | --- |
|  |  |

* « Previous (en-US)
* Next »


Drawing text - APIs da Web

Drawing text
============

* « Previous
* Next »

Após entender como aplicar estilos e cores no capítulo anterior, nós veremos agora como desenhar texto dentro do contexto de uma canvas.

Desenhando texto
----------------

O context de renderização da canvas fornece dois métodos para renderização textual:

`fillText(text, x, y [, maxWidth])` (en-US)

Preenche com um determinado texto as cordenadas (x,y) recebidas. Opcionalmente com uma largura máxima para o desenho.

`strokeText(text, x, y [, maxWidth])` (en-US)

Traçeja um determinado texto nas cordenadas (x,y) recebidas. Opcionalmente com uma largura máxima para o desenho.

### Um exemplo com `fillText`

O texto a seguir é rederizado utilizando `fillStyle`.

```js
function draw() {
  var ctx = document.getElementById("canvas").getContext("2d");
  ctx.font = "48px serif";
  ctx.fillText("Hello world", 10, 50);
}
```

```
<canvas id="canvas" width="300" height="100"></canvas>
```

```
draw();
```

### Um exemplo com `strokeText`

O texto é preenchido usando o strokeStyle atual.

```js
function draw() {
  var ctx = document.getElementById("canvas").getContext("2d");
  ctx.font = "48px serif";
  ctx.strokeText("Hello world", 10, 50);
}
```

```
<canvas id="canvas" width="300" height="100"></canvas>
```

```
draw();
```

Estilo de Texto
---------------

Nos exemplos anteriores, já usamos a propriedade font para tornar o texto um pouco maior que o tamanho padrão. Existem mais algumas propriedades que permitem ajustar a maneira como o texto é exibido no canvas:

`font = value` (en-US)

The current text style being used when drawing text. This string uses the same syntax as the CSS `font` (en-US) property. The default font is 10px sans-serif.

`textAlign = value` (en-US)

Text alignment setting. Possible values: `start`, `end`, `left`, `right` or `center`. The default value is `start`.

`textBaseline = value` (en-US)

Baseline alignment setting. Possible values: `top`, `hanging`, `middle`, `alphabetic`, `ideographic`, `bottom`. The default value is `alphabetic`.

`direction = value` (en-US)

Directionality. Possible values: `ltr`, `rtl`, `inherit`. The default value is `inherit`.

Essas propriedades podem ser similares para você, se você trabalhou com CSS antes.

O diagrama seguinte do WHATWG demonstra as várias baselines suportadas pela propriedade do `textBaseline`
![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.](http://www.whatwg.org/specs/web-apps/current-work/images/baselines.png)

### O exemplo de uma textBaseline

Edite o código abaixo e veja as atualizações em tempo real no canvas.

```js
ctx.font = "48px serif";
ctx.textBaseline = "hanging";
ctx.strokeText("Hello world", 0, 100);
```

```
<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.font = "48px serif";
ctx.textBaseline = "hanging";
ctx.strokeText("Hello world", 0, 100);</textarea
>
```

```
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);
```

Advanced text measurements
--------------------------

In the case you need to obtain more details about the text, the following method allows you to measure it.

`measureText()` (en-US)

Returns a `TextMetrics` (en-US) object containing the width, in pixels, that the specified text will be when drawn in the current text style.

The following code snippet shows how you can measure a text and get its width.

```js
function draw() {
  var ctx = document.getElementById("canvas").getContext("2d");
  var text = ctx.measureText("foo"); // TextMetrics object
  text.width; // 16;
}
```

Notas específicas - Gecko
-------------------------

No Gecko (a engine de renderização do Firefox, Firefox OS e outras aplicações Mozilla), algumas APIs prefixadas foram implementadas em versões anteriores para escrever texto em um canvas. Essas APIs agora estão depreciadas e removidas, e não são mais garantidas para uso.

* « Previous
* Next »


Conclusão - APIs da Web

Conclusão
=========

* « Previous

Parabéns! Você terminou o Canvas tutorial! Este conhecimento ajudará você a fazer ótimos gráficos 2D na web.

Mais exemplos e tutoriais
-------------------------

Há uma variedade de demonstrações e mais explicações sobre canvas nesses sites:

Codepen.io

Front End Developer Playground & Code Editor no navegador.

HTML5CanvasTutorials

Exemplos para a maioria das APIs canvas.

31 days of Canvas tutorials

Uma ótima fundação para codificação visual em JavaScript .

Game development

O jogo é uma das atividades de computador mais populares. Novas tecnologias estão chegando constantemente para possibilitar o desenvolvimento de jogos melhores e mais poderosos que podem ser executados em qualquer navegador da Web compatível com os padrões.

Outras Web APIs
---------------

Essas APIs podem ser úteis, quando trabalhando mais com canvas e gráficos:

WebGL

API para renderização interativa de gráficos 3D.

SVG

Scalable Vector Graphics permitem que você descreva imagens como conjuntos de vetores (linhas) e formas, a fim de permitir que eles sejam redimensionados sem problemas, independentemente do tamanho em que são desenhados.

Web Audio

A Web Audio API fornece um sistema poderoso e versátil para controlar o áudio na Web, permitindo que os desenvolvedores escolham fontes de áudio, adicionem efeitos ao áudio, criem visualizações de áudio, apliquem efeitos espaciais (como panning) e muito mais.

Questions
---------

Stackoverflow

Perguntas marcadas como "canvas".

Comentários sobre esse tutorial – A comunidade MDN de documentação

Se você tiver algum comentário sobre este tutorial ou quiser nos agradecer, fique à vontade para entrar em contato conosco!

* « Previous


Otimizando canvas - APIs da Web

Otimizando canvas
=================

* « Previous
* Next »

O elemento `<canvas>` é um dos padrões mais largamente utilizados para renderização de gráficos 2D na Web. É muito usado em jogos e em visualizações complexas. Porém, quando sítios web e aplicativos utilizam canvas até seus limites, começam a surgir problemas de perda de performance. Este artigo tem o objetivo de prover sugestões de otimização de seu elemento canvas e garantir que seu site ou aplicativo funcione melhor.

Dicas de performance
--------------------

O que segue é uma coleção de dicas para melhorar a performance.

### Pre-render similar primitives or repeating objects on an off-screen canvas

If you find yourself with complex drawing operations on each frame, consider creating an offscreen canvas, draw to it once (or whenever it changes) on the offscreen canvas, then on each frame draw the offscreen canvas.

```js
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);
```

### Avoid floating-point coordinates and use integers instead

Sub-pixel rendering occurs when you render objects on a canvas without whole values.

```js
ctx.drawImage(myImage, 0.3, 0.5);
```

This causes the browser to do extra calculations to create the anti-aliasing effect. To avoid this, make sure to round all co-ordinates used in calls to `drawImage()` (en-US) using `Math.floor()`, for example.

### Don't scale images in `drawImage`

Cache various sizes of your images on an offscreen canvas when loading as opposed to constantly scaling them in `drawImage()` (en-US).

### Use multiple layered canvases for complex scenes

You may find you have some elements that are frequently changing and moving around whereas other things (like UI) never change. An optimization in this situation is to create layers using multiple canvas elements.

For example you could create a UI layer that sits on top of everything and is only drawn during user input. You could create game layer where the frequently updating entities exist and a background layer for entities that rarely update.

```html
<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>
```

### CSS for large background images

If like most games you have a static background image, use a plain `<div>` element with a CSS `background` property and position it under the canvas. This will avoid drawing a large image to the canvas on every tick.

### Scaling canvas using CSS transforms

CSS transforms (en-US) are faster by using the GPU. Best case is to not scale the canvas or have a smaller canvas and scale up rather than a bigger canvas and scale down. For Firefox OS, target 480 x 320 px.

```js
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 + ")";
```

### Turn off transparency

If your game uses canvas and doesn't need to be transparent, set the `alpha` option to `false` when creating a drawing context with `HTMLCanvasElement.getContext()`. This information can be used internally to optimize rendering.

```js
var ctx = canvas.getContext("2d", { alpha: false });
```

### More tips

* Batch canvas calls together (for example, draw a poly-line instead of multiple separate lines).
* Avoid unnecessary canvas state changes.
* Render screen differences only, not the whole new state.
* Avoid the `shadowBlur` (en-US) property whenever possible.
* Avoid text rendering whenever possible.
* Try different ways to clear the canvas (`clearRect()` vs. `fillRect()` vs. resizing the canvas)
* With animations, use `window.requestAnimationFrame()` instead of `window.setInterval()` (en-US) .
* Be careful with heavy physics libraries
See also
--------

* Improving HTML5 Canvas Performance – HTML5 Rocks
* Optimizing your JavaScript game for Firefox OS – Mozilla Hacks
* « Previous
* Next »


Desenhando formas com canvas - APIs da Web

Desenhando formas com canvas
============================

* « Previous
* Next »

Agora que criamos nosso ambiente em canvas, podemos entrar nos detalhes de como desenhar no canvas. No final deste artigo, você terá aprendido a desenhar retângulos, triângulos, linhas, arcos e curvas, proporcionando familiaridade com algumas das formas básicas. Trabalhar com caminhos (*shapes*) é essencial ao desenhar objetos na tela e veremos como isso pode ser feito.

A grade
-------

![](/pt-BR/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes/canvas_default_grid.png)Antes que possamos começar a desenhar, precisamos falar sobre a grade de tela ou **espaço de coordenadas**. O modelo HTML na página anterior tinha um elemento canvas de 150 pixels de largura e 150 pixels de altura. À direita, você verá este canvas com a grade padrão sobreposta. Normalmente 1 unidade na grade corresponde a um pixel na tela. A origem desta grade está posicionada no canto superior esquerdo (coordenadas (0,0)). Todos os elementos são colocados em relação a esta origem. Assim, a posição do canto superior esquerdo do quadrado azul, se torna x pixels dos pixels da esquerda e y a partir do topo (coordenadas (x,y)). Mais tarde nesse tutorial vamos ver como podemos traduzir a origem para uma posição diferente, girar a grade e até mesmo escaloná-la. Por enquanto vamos ficar com o padrão.

Desenhando retângulos
---------------------

Diferente do SVG , o `<canvas>` suporta somente formas primitivas: retângulos. Todas as outras formas são criadas a partir da combinação de um ou mais caminhos (*paths*), lista de pontos conectados por uma linha. Felizmente, temos uma variedade de funções de desenho que tornam possíveis criar formas muito complexas.

Primeiramente vamos olhar o retângulo. Aqui está listado três funções para desenhar retângulos pelo canvas:

`fillRect(x, y, width, height)`

Desenha um retângulo preenchido.

`strokeRect(x, y, width, height)`

Desenha a borda do retângulo.

`clearRect(x, y, width, height)`

Limpa um retângulo específico, tornando-o totalmente transparente.

Cada umas das funções recebem os mesmos parâmetros. `x` e `y` determinam a posição no canvas (em relação a origem) no canto superior esquerdo do retângulo. O `width` (largura) e o `height` (altura) definem o tamanho do retângulo.

Abaixo esta listado a função `draw()` da página anterior, porém utilizando as três funções.

### Exemplo de forma retangular
```

<html>
  <body onload="draw();">
    <canvas id="canvas" width="150" height="150"></canvas>
  </body>
</html>
```

```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);
  }
}
```

O resultado desse exemplo é mostrado abaixo.

| Screenshot | Live sample |
| --- | --- |
|  |  |

A função `fillRect()` desenha um grande quadrado preto de 100 pixels. A função `clearRect()` por sua vez apaga um quadrado de 60x60 pixels a partir do centro, por fim, a função `strokeRect()` é chamada para criar uma borda de 50x50 pixels em volta do quadrado apagado.

Posteriormente veremos duas alternativas à função `clearRect()`, nós também aprenderemos como alterar a cor e o estilo das linhas nas camadas renderizadas.

Ao contrário das funções de *paths* que veremos na próxima seção, todas as três funções de retângulo desenham imediatamente no canvas.

Desenhando caminhos/regiões (paths)
-----------------------------------

Para criar uma camada usando caminhos (regiões ou *paths*) é necessário alguns passos extras. Primeiro, cria-se a região de desenho. Depois usa-se comandos de desenho para desenhar nesta região. Por fim, você limita a região (path). Uma vez que a região de desenho está criada, você pode traçar ou preencher o caminho para que seja renderizado. Aqui estão as funções utilizadas para isso:

`beginPath()`

Cria um novo path. Uma vez criado, futuros comandos de desenho são direcionados do path atual para a construção de um novo path no canvas.

Métodos de Caminhos (Path)

Métodos para manipuliar diferentes paths para objetos.

`closePath()`

Finaliza o path para futuros comandos de desenho, fazendo com que voltem a ser direcionados ao contexto.

`stroke()`

Desenha uma borda na camada.

`fill()`

Desenha uma forma sólida através de preenchimento.

O primeiro passo para criar um caminho é chamar o `beginPath()`. Internamente, caminhos são armazenados como uma lista de sub-caminhos (linhas, arcos, etc.) que juntos formam uma forma (*shape*). Sempre que esse método é chamado, a lista é redefinida e podemos começar a desenhar novas formas.

**Nota:** Quando o caminho atual está vazio, assim como imediatamente depois de chamar `beginPath()`, ou em uma tela recém-criada, o primeiro comando de construção de caminho é sempre tratado como um `moveTo()`, independentemente do que ele seja realmente. Por essa razão, você quase sempre vai precisar definir especificamente sua posição inicial após redefinir um caminho.

A segunda etapa é chamar os métodos que realmente especificam os caminhos a serem desenhados. Vamos ver isso em breve.

O terceiro, e um passo opcional, é chamar `closePath()`. Este método tenta fechar a forma desenhando uma linha reta do ponto atual para o início. Se a forma (*shape*) já foi fechada ou existe apenas um ponto na lista, esta função não faz nada.

**Nota:** Quando você chama `fill()`, todas as formas abertas são fechadas automaticamente, assim você não precisa chamar `closePath()`. Isso **não acontece** quando você chamar `stroke()`.

### Desenhando um triângulo

Por exemplo, o código para desenhar um triângulo seria algo parecido com isto:
```

<html>
  <body onload="draw();">
    <canvas id="canvas" width="150" height="150"></canvas>
  </body>
</html>
```

```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();
  }
}
```

O resultado se parece com isso:

| Screenshot | Live sample |
| --- | --- |
|  |  |

### Desenhando

Uma função muito útil, que na verdade não desenha nada, mas torna-se parte da lista de caminhos descritos acima, é a função `moveTo()`. Você provavelmente pode imaginar melhor isso como se fosse o levantar uma caneta ou lápis de um ponto em um pedaço de papel e colocá-lo no próximo ponto.

`moveTo(x, y)`

Move a caneta (*pen*) para as coordenadas especificadas por `x` e `y`.

Quando o canvas é inicializado ou `beginPath()` é chamado, você normalmente vai querer usar a função `moveTo()` para colocar o ponto inicial em outro lugar. Poderíamos também usar `moveTo()` para desenhar caminhos não conectados. Dê uma olhada no rosto sorridente abaixo. Eu marquei os lugares onde eu usei o método `moveTo()` (as linhas vermelhas).

Caso queira tentar fazer isso, você pode usar o snippet de código abaixo. Basta colá-lo na função `draw()` que vimos anteriormente.
```

<html>
  <body onload="draw();">
    <canvas id="canvas" width="150" height="150"></canvas>
  </body>
</html>
```

```js
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); // Círculo exterior
    ctx.moveTo(110, 75);
    ctx.arc(75, 75, 35, 0, Math.PI, false); // Boca (sentido horário)
    ctx.moveTo(65, 65);
    ctx.arc(60, 65, 5, 0, Math.PI \* 2, true); // Olho esquerdo
    ctx.moveTo(95, 65);
    ctx.arc(90, 65, 5, 0, Math.PI \* 2, true); // Olho direito
    ctx.stroke();
  }
}
```

O resultado aparece como:

| Screenshot | Live sample |
| --- | --- |
|  |  |

Se você não gosta de ver linhas conectadas, você pode remover as linhas que chamam a função `moveTo()`.

**Nota:** Para aprender mais sobre a função `arc()`, veja sobre Arcos.

### Linhas

Para desenhar linhas retas, use o método `lineTo().`

`lineTo(x, y)`

Desenha uma linha do ponto atual a até a posição especificada por `x` e `y`.

Esse método recebe dois argumentos, `x` e `y`, que são as coordenadas do ponto final da linha. O ponto inicial é dependente de caminhos previamente desenhados, onde o ponto final do caminho anterior é o ponto inicial para o seguinte, e assim por diante. O ponto inicial também pode ser alterado usando o método `moveTo()`.

O exemplo abaixo desenha dois triângulos, um preenchido e um delineado.
```

<html>
  <body onload="draw();">
    <canvas id="canvas" width="150" height="150"></canvas>
  </body>
</html>
```

```js
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();
  }
}
```

Isso começa chamando o método `beginPath()` para iniciar um novo *shape path*. Em seguida, usamos o método `moveTo()` para mover o ponto inicial para a posição desejada. Logo abaixo, duas linhas, que compõem os dois lados do triângulo, são desenhadas.

| Screenshot | Live sample |
| --- | --- |
|  |  |

Você notará a diferença entre o triângulo preenchido (*filled*) e não prenchido (*stroked*). Isto ocorre, como mencionado acima, porque as formas são automaticamente fechadas quando um caminho é preenchido, mas não quando são não preenchidos. Se deixássemos de fora o `closePath()` para os triângulos não preenchidos, apenas duas linhas teriam sido desenhadas, não um triângulo completo.

### Arcos

Para desenhar arcos, nós usamos os métodos `arc()` ou `arcTo()`.

`arc(x, y, radius, startAngle, endAngle, anticlockwise)`

Desenha um arco centralizado na posição *(x, y)* com um raio *r* iniciando em *startAngle e* terminando em *endAngle* apontando na direção indicada pelo sentido anti-horário (padronizando para o sentido horário).

`arcTo(x1, y1, x2, y2, radius)`

Desenha um arco com os pontos de controle e raio, conectados ao ponto anterior por uma linha reta.

Vamos dar uma olhada mais detalhada sobre o método `arc`, que tem seis parâmetros: `x` e `y` são as coordenadas do centro do círculo em que o arco deve ser desenhado. `radius` é o raio. Os parâmetros `startAngle` e `endAngle` definem os pontos inicial e final do arco em radianos, ao longo da curva do círculo. Estes são medidos a partir do eixo `x`. O parâmetro `anticlockwise` é um valor Booleano que, quando verdadeiro, desenha o arco no sentido anti-horário; Caso contrário, o arco é desenhado no sentido horário.

**Nota:** Os ângulos na função `arc` são medidos em radianos, não em graus. Para converter graus em radianos você pode usar a seguinte expressão JavaScript: `radians = (Math.PI/180)*degrees`.

O exemplo a seguir é um pouco mais complexo do que os que vimos anteriormente. Ele desenha 12 arcos diferentes, todos com diferentes ângulos e preenchimentos.

Os dois laços `for` são para iterar através das linhas e colunas de arcos. Para cada arco, é criado um novo caminho chamando `beginPath()`. No código, cada um dos parâmetros para o arco estão em uma variável somente para demonstração, assim você não precisa fazer isso na vida real.

As coordenadas `x` e `y` devem ser suficientemente claras. O parâmetros `radius` e `startAngle` são fixos. O `endAngle` começa em 180 graus (metade de um círculo) na primeira coluna e aumenta gradualmente em 90 graus, culminando em um círculo completo na última coluna.

A manipulação do parâmetro `clockwise` faz com que a primeira e terceira linhas sejam desenhadas como arcos no sentido horário, e a segunda e quarta linhas como arcos no sentido anti-horário. Finalmente, a instrução `if` faz com que a metade superior dos arcos não sejam preenchidos e a metade inferior dos arcos sejam.

**Nota:** Este exemplo requer um canvas um pouco maior que as outras desta página: 150 x 200 pixels.
```

<html>
  <body onload="draw();">
    <canvas id="canvas" width="150" height="200"></canvas>
  </body>
</html>
```

```js
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; // coordenada x
        var y = 25 + i \* 50; // coordenada y
        var radius = 20; // Raio do Arco
        var startAngle = 0; // Ponto inicial no círculo
        var endAngle = Math.PI + (Math.PI \* j) / 2; // Ponto final no círculo
        var anticlockwise = i % 2 == 0 ? false : true; // horário ou anti-horário

        ctx.arc(x, y, radius, startAngle, endAngle, anticlockwise);

        if (i > 1) {
          ctx.fill();
        } else {
          ctx.stroke();
        }
      }
    }
  }
}
```

| Screenshot | Live sample |
| --- | --- |
|  |  |

### Curvas de Bézier Cúbicas e Quadráticas

O próximo tipo de caminhos disponíveis são as Curvas de Bézier, disponíveis nas variedades cubícas e quadráticas. Elas são geralmente usadas para desenhar complexas formas orgânicas.

`quadraticCurveTo(cp1x, cp1y, x, y)`

Desenha uma curva de Bézier quadrática da posição atual indicada pelo cursor, até a posição final especificada por `x` e `y`, usando o controle de pontos guiados por `cp1x` `e cp1y`.

`bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y)` (en-US)

Desenha uma curva de Bézier cúbica partindo da posição atual indicada pelo cursor, até a posição final especificada por `x` e `y`, usando o controle de pontos guiados por (`cp1x`, `cp1y`) e (cp2x, cp2y).

![](/pt-BR/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes/canvas_curves.png)A diferença entre estes métodos pode ser descrita de forma melhor usando a imagem à direita. Uma curva quadrática de Bézier tem um ponto inicial e final (pontos azuis) e apenas um ponto de controle (indicado pelo ponto vermelho) enquanto que uma curva cúbica de Bézier utiliza dois pontos de controles.

Os parâmetros `x` e `y` em ambos os métodos são as coordenadas do ponto final. `cp1x` e `cp1y` são as coordenadas do primeiro ponto de controle, e `cp2x` e `cp2y` são as coordenadas do segundo ponto de controle.

Usando curvas de Bézier quadráticas e cúbicas pode ser algo bastante desafiador, porque ao contrário de um software de desenho vetorial, como o Adobe Illustrator, não temos resultados visuais imediatos sobre o que estamos fazendo. Isso torna bastante difícil desenhar formas complexas. No exemplo a seguir, vamos desenhar algumas formas orgânicas simples, mas se você tiver tempo e, acima de tudo, paciência, formas muito mais complexas podem ser criadas.

Não há nada muito difícil nestes exemplos. Em ambos os casos vemos uma sucessão de curvas sendo desenhadas, resultando no fim, em uma forma (*shape*) completa.

#### Curvas de Bézier Quadráticas

Este exemplo usa múltiplas curvas de Bézier quadráticas para renderizar um balão de fala.
```

<html>
  <body onload="draw();">
    <canvas id="canvas" width="150" height="150"></canvas>
  </body>
</html>
```

```js
function draw() {
  var canvas = document.getElementById("canvas");
  if (canvas.getContext) {
    var ctx = canvas.getContext("2d");

    // Exemplo de curvas de Bézier quadráticas
    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();
  }
}
```

| Screenshot | Live sample |
| --- | --- |
|  |  |

#### Curvas de Bézier Cúbicas

Este exemplo desenha um coração usando curvas de Bézier cúbicas.
```

<html>
  <body onload="draw();">
    <canvas id="canvas" width="150" height="150"></canvas>
  </body>
</html>
```

```js
function draw() {
  var canvas = document.getElementById("canvas");
  if (canvas.getContext) {
    var ctx = canvas.getContext("2d");

    // Exemplo de curvas de Bézier cúbicas
    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();
  }
}
```

| Screenshot | Live sample |
| --- | --- |
|  |  |

### Retângulos

Além dos três métodos que vimos em Desenhando retângulos, que desenham formas retangulares diretamente no canvas, há também o método `rect()`, que adiciona uma forma retangular a um caminho (*path*) atualmente aberto.

`rect(x, y, width, height)`

Desenha um retângulo cujo canto superior esquerdo é especificado por (`x`, `y`) com base em uma largura (`width`) e uma altura (`height`).

Quando este método é executado, o método `moveTo()` é automaticamente chamado com os parâmetros (0,0). Em outras palavras, a posição atual do cursor é automaticamente redefinida para as coordenadas padrões.

### Combinando Elementos

Até agora, em cada exemplo dessa página foi usada apenas um tipo de função de caminho (*path*) para cada forma (*shape*). No entanto, não há nenhuma limitação para o número ou tipos de caminhos que você pode usar para criar um *shape*. Então, neste exemplo final, vamos combinar todas as funções de caminho para fazer um conjunto de personagens de jogo muito conhecido.
```

<html>
  <body onload="draw();">
    <canvas id="canvas" width="150" height="150"></canvas>
  </body>
</html>
```

```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();
  }
}

// Uma função útil para desenhar um retângulo com cantos arredondados.

function roundedRect(ctx, x, y, width, height, radius) {
  ctx.beginPath();
  ctx.moveTo(x, y + radius);
  ctx.lineTo(x, y + height - radius);
  ctx.quadraticCurveTo(x, y + height, x + radius, y + height);
  ctx.lineTo(x + width - radius, y + height);
  ctx.quadraticCurveTo(x + width, y + height, x + width, y + height - radius);
  ctx.lineTo(x + width, y + radius);
  ctx.quadraticCurveTo(x + width, y, x + width - radius, y);
  ctx.lineTo(x + radius, y);
  ctx.quadraticCurveTo(x, y, x, y + radius);
  ctx.stroke();
}
```

O resultado é:

| Screenshot | Live sample |
| --- | --- |
|  |  |

Não vamos discutir isso em detalhes, uma vez que é realmente muito simples. As coisas mais importantes a serem observadas são o uso da propriedade `fillStyle` no contexto de desenho e o uso de uma função auxiliar (neste caso `roundedRect()`). Usando funções auxiliares para construir um desenho frequentemente pode ser muito útil, além de reduzir a quantidade de código que você precisa, bem como a sua complexidade.

Vamos dar uma nova olhada em `fillStyle`, em mais detalhes, mais adiante neste tutorial. Aqui, tudo o que estamos fazendo é apenas usando-o para alterar sucessivamente a cor de preenchimento dos caminhos (*paths*) de cor preta (padrão) para branca.

Path2D
------

 Como vimos no último exemplo, pode haver uma série de *paths* e comandos de desenho para desenhar objetos em sua tela. Para simplificar o código e melhorar o desempenho, o objeto `Path2D`, disponível em versões recentes dos navegadores, permite armazenar em cache ou gravar esses comandos de desenho. Com ele, você pode construir seus *paths* rapidamente.
 Vamos ver como podemos construir um objeto de `Path2D`:

`Path2D()` (en-US)

O construtor de **`Path2D()`** retorna um objeto `Path2D` instanciado recentemente, opcionalmente através de um outro objeto `Path2D` como argumento (cria uma cópia) ou, opcionalmente, com uma *string* que representam dados de *paths* em SVG (en-US).

```js
new Path2D(); // objeto vazio de Path2D
new Path2D(path); // cópia de outro objeto de Path2D
new Path2D(d); // objeto criado a partir de paths em SVG
```

Todos os métodos de caminho (path methods) como `moveTo`, `rect`, `arc` ou `quadraticCurveTo`, etc., que temos de saber acima, estão disponíveis em `Path2D`.

A API `Path2D` também adiciona uma maneira de combinar caminhos usando o método `addPath`. Isso pode ser útil quando você deseja criar objetos com vários componentes, por exemplo.

`Path2D.addPath(path [, transform])` (en-US)

Adiciona um `path` para o `path` atual através de uma matriz de transformação opcional.

### Exemplo de Path2D

Neste exemplo, estamos criando um retângulo e um círculo. Ambos são armazenados como um objeto de `Path2D`, de modo que eles estão disponíveis para uso posterior. Com a nova API `Path2D`, vários métodos foram atualizados como, por exemplo, opcionalmente usar um objeto `Path2D` em vez do `path` atual. Aqui, os métodos `stroke` e `fill` são usados, com um argumento de *path*, para desenhar ambos os objetos na tela, por exemplo.
```

<html>
  <body onload="draw();">
    <canvas id="canvas" width="130" height="100"></canvas>
  </body>
</html>
```

```js
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);
  }
}
```

| Screenshot | Live sample |
| --- | --- |
|  |  |

### Usando *paths* em SVG

Outro recurso poderoso da nova API de Path2D é a utilização de dados de *path* em SVG para inicializar caminhos (*paths*) no canvas. Isso permite que você crie dados de *paths* que possam ser utilizados tanto no SVG como no canvas.

O caminho se moverá para o ponto `(M10 10)` e então se moverá horizontalmente 80 pontos para a direita `(h 80)`, depois 80 pontos para baixo `(v 80)`, então 80 pontos para a esquerda (h -80) e, por fim, volta para o início (`z`). Você pode ver este exemplo na página do construtor do Path2D (en-US).

```js
var p = new Path2D("M10 10 h 80 v 80 h -80 Z");
```

* « Previous
* Next »


Using images - APIs da Web

Using images
============

* « Previous
* Next » (en-US)

Até agora nós criamos nossos próprios shapes e aplicamos estilos(applied styles) a eles. Um dos recursos mais interessantes do `<canvas>` é a capacidade de usar imagens. Eles podem ser usados para composição dinâmica de fotos ou como pano de fundo de gráficos, como sprites em jogos e assim por diante. Imagens externas podem ser usadas em qualquer formato suportado pelo navegador, tais como PNG, GIF, ou JPEG. Você pode até usar a imagem produzida por outros elementos da tela na mesma página que a fonte!

A importação de imagens para o canvas é basicamente um processo de duas etapas:

1. Obter uma referência a um objeto `HTMLImageElement` (en-US) ou a outro elemento do canvas como fonte. Também é possível usar imagens fornecendo uma URL.
2. Desenhar a imagem no canvas usando a função `drawImage()` .

Vamos dar uma olhada em como fazer isso.

Getting images to draw
----------------------

The canvas API is able to use any of the following data types as an image source:

`HTMLImageElement` (en-US)

These are images created using the `Image()` constructor, as well as any `<img>` element.

`SVGImageElement` (en-US)

These are images embedded using the `<image>` element.

`HTMLVideoElement` (en-US)

Using an HTML `<video>` element as your image source grabs the current frame from the video and uses it as an image.

`HTMLCanvasElement` (en-US)

You can use another `<canvas>` element as your image source.

These sources are collectively referred to by the type `CanvasImageSource` (en-US).

There are several ways to get images for use on a canvas.

### Using images from the same page

We can obtain a reference to images on the same page as the canvas by using one of:

* The `document.images` collection
* The `document.getElementsByTagName()` (en-US) method
* If you know the ID of the specific image you wish to use, you can use `document.getElementById()` to retrieve that specific image
### Using images from other domains

Using the `crossorigin` attribute of an `<img>` element (reflected by the `HTMLImageElement.crossOrigin` (en-US) property), you can request permission to load an image from another domain for use in your call to `drawImage()`. If the hosting domain permits cross-domain access to the image, the image can be used in your canvas without tainting it; otherwise using the image will taint the canvas (en-US).

### Using other canvas elements

Just as with normal images, we access other canvas elements using either the `document.getElementsByTagName()` (en-US) or `document.getElementById()` method. Be sure you've drawn something to the source canvas before using it in your target canvas.

One of the more practical uses of this would be to use a second canvas element as a thumbnail view of the other larger canvas.

### Creating an image from scratch

Another option is to create new `HTMLImageElement` (en-US) objects in our script. To do this, you can use the convenient `Image()` constructor:

```js
var img = new Image(); // Create new img element
img.src = "myImage.png"; // Set source path
```

When this script gets executed, the image starts loading.

If you try to call `drawImage()` before the image has finished loading, it won't do anything (or, in older browsers, may even throw an exception). So you need to be sure to use the load event so you don't try this before the image has loaded:

```js
var img = new Image(); // Create new img element
img.addEventListener(
  "load",
  function () {
    // execute drawImage statements here
  },
  false,
);
img.src = "myImage.png"; // Set source path
```

If you're only using one external image this can be a good approach, but once you need to track more than one we need to resort to something more clever. It's beyond the scope of this tutorial to look at image pre-loading tactics, but you should keep that in mind.

### Embedding an image via data: URL

Another possible way to include images is via the data: url (en-US). Data URLs allow you to completely define an image as a Base64 encoded string of characters directly in your code.

```js
var img = new Image(); // Create new img element
img.src =
  "data:image/gif;base64,R0lGODlhCwALAIAAAAAA3pn/ZiH5BAEAAAEALAAAAAALAAsAAAIUhA+hkcuO4lmNVindo7qyrIXiGBYAOw==";
```

One advantage of data URLs is that the resulting image is available immediately without another round trip to the server. Another potential advantage is that it is also possible to encapsulate in one file all of your CSS, JavaScript, HTML, and images, making it more portable to other locations.

Some disadvantages of this method are that your image is not cached, and for larger images the encoded url can become quite long.

### Using frames from a video

You can also use frames from a video being presented by a `<video>` element (even if the video is not visible). For example, if you have a `<video>` element with the ID "myvideo", you can do this:

```js
function getMyVideo() {
  var canvas = document.getElementById("canvas");
  if (canvas.getContext) {
    var ctx = canvas.getContext("2d");

    return document.getElementById("myvideo");
  }
}
```

This returns the `HTMLVideoElement` (en-US) object for the video, which, as covered earlier, is one of the objects that can be used as a `CanvasImageSource`.

Drawing images
--------------

Once we have a reference to our source image object we can use the `drawImage()` method to render it to the canvas. As we will see later the `drawImage()` method is overloaded and has several variants. In its most basic form it looks like this:

`drawImage(image, x, y)` (en-US)

Draws the `CanvasImageSource` specified by the `image` parameter at the coordinates (`x`, `y`).

**Nota:** SVG images must specify a width and height in the root <svg> element.

### Example: A simple line graph

In the following example, we will use an external image as the backdrop for a small line graph. Using backdrops can make your script considerably smaller because we can avoid the need for code to generate the background. In this example, we're only using one image, so I use the image object's `load` event handler to execute the drawing statements. The `drawImage()` method places the backdrop at the coordinate (0, 0), which is the top-left corner of the canvas.
```

<html>
  <body onload="draw();">
    <canvas id="canvas" width="180" height="150"></canvas>
  </body>
</html>
```

```js
function draw() {
  var ctx = document.getElementById("canvas").getContext("2d");
  var img = new Image();
  img.onload = function () {
    ctx.drawImage(img, 0, 0);
    ctx.beginPath();
    ctx.moveTo(30, 96);
    ctx.lineTo(70, 66);
    ctx.lineTo(103, 76);
    ctx.lineTo(170, 15);
    ctx.stroke();
  };
  img.src = "backdrop.png";
}
```

The resulting graph looks like this:

| Screenshot | Live sample |
| --- | --- |
|  |  |

Scaling
-------

The second variant of the `drawImage()` method adds two new parameters and lets us place scaled images on the canvas.

`drawImage(image, x, y, width, height)` (en-US)

This adds the `width` and `height` parameters, which indicate the size to which to scale the image when drawing it onto the canvas.

### Example: Tiling an image

In this example, we'll use an image as a wallpaper and repeat it several times on the canvas. This is done simply by looping and placing the scaled images at different positions. In the code below, the first `for` loop iterates over the rows. The second `for` loop iterates over the columns. The image is scaled to one third of its original size, which is 50x38 pixels.

**Nota:** Images can become blurry when scaling up or grainy if they're scaled down too much. Scaling is probably best not done if you've got some text in it which needs to remain legible.
```

<html>
  <body onload="draw();">
    <canvas id="canvas" width="150" height="150"></canvas>
  </body>
</html>
```

```js
function draw() {
  var ctx = document.getElementById("canvas").getContext("2d");
  var img = new Image();
  img.onload = function () {
    for (var i = 0; i < 4; i++) {
      for (var j = 0; j < 3; j++) {
        ctx.drawImage(img, j \* 50, i \* 38, 50, 38);
      }
    }
  };
  img.src = "rhino.jpg";
}
```

The resulting canvas looks like this:

| Screenshot | Live sample |
| --- | --- |
|  |  |

Slicing
-------

The third and last variant of the `drawImage()` method has eight parameters in addition to the image source. It lets us cut out a section of the source image, then scale and draw it on our canvas.

`drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)` (en-US)

Given an `image`, this function takes the area of the source image specified by the rectangle whose top-left corner is (`sx`, `sy`) and whose width and height are `sWidth` and `sHeight` and draws it into the canvas, placing it on the canvas at (`dx`, `dy`) and scaling it to the size specified by `dWidth` and `dHeight`.

![](/pt-BR/docs/Web/API/Canvas_API/Tutorial/Using_images/canvas_drawimage.jpg)To really understand what this does, it may help to look at the image to the right. The first four parameters define the location and size of the slice on the source image. The last four parameters define the rectangle into which to draw the image on the destination canvas.

Slicing can be a useful tool when you want to make compositions. You could have all elements in a single image file and use this method to composite a complete drawing. For instance, if you want to make a chart you could have a PNG image containing all the necessary text in a single file and depending on your data could change the scale of your chart fairly easily. Another advantage is that you don't need to load every image individually, which can improve load performance.

### Example: Framing an image

In this example, we'll use the same rhino as in the previous example, but we'll slice out its head and composite it into a picture frame. The picture frame image is a 24-bit PNG which includes a drop shadow. Because 24-bit PNG images include a full 8-bit alpha channel, unlike GIF and 8-bit PNG images, it can be placed onto any background without worrying about a matte color.

```html
<html>
  <body onload="draw();">
    <canvas id="canvas" width="150" height="150"></canvas>
    <div style="display:none;">
      <img id="source" src="rhino.jpg" width="300" height="227" />
      <img id="frame" src="canvas\_picture\_frame.png" width="132" height="150" />
    </div>
  </body>
</html>
```

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

  // Draw slice
  ctx.drawImage(
    document.getElementById("source"),
    33,
    71,
    104,
    124,
    21,
    20,
    87,
    104,
  );

  // Draw frame
  ctx.drawImage(document.getElementById("frame"), 0, 0);
}
```

We took a different approach to loading the images this time. Instead of loading them by creating new `HTMLImageElement` (en-US) objects, we included them as `<img>` tags directly in our HTML source and retrieved the images from those. The images are hidden from output by setting the CSS property `display` to none for those images.

| Screenshot | Live sample |
| --- | --- |
|  |  |

The script itself is very simple. Each `<img>` is assigned an ID attribute, which makes them easy to select using `document.getElementById()`. We then simply use `drawImage()` to slice the rhino out of the first image and scale him onto the canvas, then draw the frame on top using a second `drawImage()` call.

Art gallery example
-------------------

In the final example of this chapter, we'll build a little art gallery. The gallery consists of a table containing several images. When the page is loaded, a `<canvas>` element is inserted for each image and a frame is drawn around it.

In this case, every image has a fixed width and height, as does the frame that's drawn around them. You could enhance the script so that it uses the image's width and height to make the frame fit perfectly around it.

The code below should be self-explanatory. We loop through the `document.images` container and add new canvas elements accordingly. Probably the only thing to note, for those not so familiar with the DOM, is the use of the `Node.insertBefore` method. `insertBefore()` is a method of the parent node (a table cell) of the element (the image) before which we want to insert our new node (the canvas element).

```html
<html>
  <body onload="draw();">
    <table>
      <tr>
        <td><img src="gallery\_1.jpg" /></td>
        <td><img src="gallery\_2.jpg" /></td>
        <td><img src="gallery\_3.jpg" /></td>
        <td><img src="gallery\_4.jpg" /></td>
      </tr>
      <tr>
        <td><img src="gallery\_5.jpg" /></td>
        <td><img src="gallery\_6.jpg" /></td>
        <td><img src="gallery\_7.jpg" /></td>
        <td><img src="gallery\_8.jpg" /></td>
      </tr>
    </table>
    <img id="frame" src="canvas\_picture\_frame.png" width="132" height="150" />
  </body>
</html>
```

And here's some CSS to make things look nice:

```css
body {
  background: 0 -100px repeat-x url(bg\_gallery.png) #4f191a;
  margin: 10px;
}

img {
  display: none;
}

table {
  margin: 0 auto;
}

td {
  padding: 15px;
}
```

Tying it all together is the JavaScript to draw our framed images:

```js
function draw() {
  // Loop through all images
  for (var i = 0; i < document.images.length; i++) {
    // Don't add a canvas for the frame image
    if (document.images[i].getAttribute("id") != "frame") {
      // Create canvas element
      canvas = document.createElement("canvas");
      canvas.setAttribute("width", 132);
      canvas.setAttribute("height", 150);

      // Insert before the image
      document.images[i].parentNode.insertBefore(canvas, document.images[i]);

      ctx = canvas.getContext("2d");

      // Draw image to canvas
      ctx.drawImage(document.images[i], 15, 20);

      // Add frame
      ctx.drawImage(document.getElementById("frame"), 0, 0);
    }
  }
}
```

Controlling image scaling behavior
----------------------------------

As mentioned previously, scaling images can result in fuzzy or blocky artifacts due to the scaling process. You can use the drawing context's `imageSmoothingEnabled` (en-US) property to control the use of image smoothing algorithms when scaling images within your context. By default, this is `true`, meaning images will be smoothed when scaled. You can disable this feature like this:

```js
ctx.mozImageSmoothingEnabled = false;
ctx.webkitImageSmoothingEnabled = false;
ctx.msImageSmoothingEnabled = false;
ctx.imageSmoothingEnabled = false;
```

* « Previous
* Next » (en-US)


Basic animations - APIs da Web

Basic animations
================

Já que estamos usando JavaScript para controlar `<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.

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.

Passos para animação básica
---------------------------

Estes são os passos que você precisa para desenhar um frame:

1. **Limpe o canvas**
 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().
2. **Salve o estado da tela**
 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.
3. **Desenhe formas animadas**
 A etapa em que você faz a renderização real do quadro.
4. **Restaure o estado do canvas**
 Se você salvou o estado, restaure-o antes de desenhar um novo quadro.
Controlando uma animação
------------------------

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.

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.

### Atualizações agendadas

Primeiramente há as funções `window.setInterval()` (en-US) e `window.setTimeout()` (en-US), que podem ser usadas para chamar uma função específica durante um certo período definido de tempo.

**Nota:** Nota: O método `window.requestAnimationFrame()` agora é a maneira recomendada de programar animações. Vamos atualizar esse tutorial para abortar isso em breve.

`setInterval(função,atraso)`

Inicia repetidamente executando a função específica pela função a cada milissegundo de atraso.

`setTimeout(função,atraso)`

Executa a função especificada pela função em milissegundos de atraso.

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

### Atualizar na interação do usuário

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 `EventListener`s, nós pegamos qualquer interação do usuário e executamos nossas funções da animação.

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:
```

var myAnimation = new MiniDaemon(null, animateShape, 500, Infinity);
```

ou
```

var myAnimation = new Daemon(null, animateShape, 500, Infinity);
```

Nos exemplos abaixo, no entanto, usamos o método `window.setInterval()` (en-US) para controlar a animação. Na parte inferior dessa página há alguns links de exemplos que usam `window.setTimeout()` (en-US).

#### Um sistema solar animado

Esse exemplo anima um pequeno modelo do nosso sistema solar.

```js
var sun = new Image();
var moon = new Image();
var earth = new Image();
function init() {
  sun.src = "canvas\_sun.png";
  moon.src = "canvas\_moon.png";
  earth.src = "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);
}
```

```
<canvas id="canvas" width="300" height="300"></canvas>
```

```
init();
```

| Screenshot | Live sample |
| --- | --- |
|  |  |

#### Um relógio animado

Esse exemplos desenha um relógio animado, mostrando sua hora atual.

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

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

```
<canvas id="canvas" width="150" height="150"></canvas>
```

```
init();
```

| Screenshot | Live sample |
| --- | --- |
|  |  |

#### Um panorama em loop

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.

```js
var img = new Image();

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

img.src = "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 > CanvasXSize) {
    x = CanvasXSize - imgW;
  } // image larger than canvas
  if (imgW > CanvasXSize) {
    clearX = imgW;
  } // image larger than canvas
  else {
    clearX = CanvasXSize;
  }
  if (imgH > 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 <= Canvas Size
  if (imgW <= CanvasXSize) {
    //reset, start from beginning
    if (x > CanvasXSize) {
      x = 0;
    }
    //draw aditional image
    if (x > CanvasXSize - imgW) {
      ctx.drawImage(img, x - CanvasXSize + 1, y, imgW, imgH);
    }
  }
  //If image is > Canvas Size
  else {
    //reset, start from beginning
    if (x > CanvasXSize) {
      x = CanvasXSize - imgW;
    }
    //draw aditional image
    if (x > 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;
}
```

Abaixo é o `<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.

```html
<canvas id="canvas" width="800" height="200"></canvas>
```

##### Live sample

Outros exemplos
---------------

Gartic

Jogo de desenho para multiplayers.

Canvascape

Um jogo de aventura 3D (tiro em primeira pessoa).

A basic ray-caster

Um bom exemplo de como fazer animações usando os controles do teclado.

canvas adventure

Outro bom exemplo que usa controles de teclado.

An interactive Blob

Divirta-se com Blob.

Flying through a starfield

Voe através de estrelas, círculos ou quadrados.

iGrapher

Um exemplo que ilustra os dados do mercado de ações.

Veja também
-----------

* JavaScript timers
* `setInterval` – A little framework (en-US)
* JavaScript Daemons Management
* HTMLCanvasElement (en-US)
* « Previous
* Next » (en-US)