Canvas - Paths (caminhos)

Descobrindo os caminhos (paths) do Canvas (HTML5).

Cada objeto que implementa a interface CanvasPathMethods possui um path (caminho).

São eles:

Um path (caminho) tem uma lista de zero ou mais subpaths (subcaminhos).

Cada subpath consiste de uma lista de um ou mais pontos, ligados por segmentos de linhas retas ou curvas, e um sinalizador que indica se o subpath está fechado ou não.

Criando caminhos (paths)

A documentação da MDN diz que é preciso 3 passos para criar um caminho (path):

1 passo

O primeiro passo para criar um caminho (path) é chamar o método beginPath().

Internamente, os caminhos são armazenados como uma lista de sub-caminhos (linhas, arcos, etc) que juntos formam uma forma (shape).

2 passo

O segundo passo é chamar os métodos que realmente especificam os caminhos a ser desenhado.

3 passo

A terceira (opcional), é chamar a função closePath().

Este método tenta fechar a forma (shape) desenhando uma linha reta do ponto atual para o início.

Se a forma já foi fechada ou há apenas um ponto na lista, esta função não faz nada.

Uso básico de beginPath() e closePath()

O caminho (path) está entre as chamadas das funções beginPath() e closePath() e desenhar um triângulo é o exemplo que mais ilustra o caminho (path).

Primeira coisa é tentar entender as coordenadas (veja os comentários).

Segunda coisa, repare que só traçamos duas linhas (lineTo). O método closePath() executou a última linha, ou seja, fechou nosso caminho.

Ele pintou a linha até o ponto inicial (beginPath) que era x=30 e y=120.

fig exemplo de canvas

var canvas = document.getElementById('ex01');
var context = canvas.getContext('2d');

context.beginPath();     // iniciamos o path
context.moveTo(30, 120); // movemos a pena para x=30 e y=120 (canto esquerdo)
context.lineTo(45, 90);  // traçamos uma diagonal até x=45 e y=90 (canto superiror)
context.lineTo(60, 120); // diagonal até x=60 e y=120 (canto direito)
context.closePath();     // fecha o caminho (traça uma reta até x=30 e y=120 - beginPath)
context.stroke();        // pinta o caminho

Importante

Outro triângulo

Este triângulo começa no canto esquerdo em x=75, y=50.

Traçamos uma diagonal até x=100, y=75, canto inferior.

E então subimos com uma reta até x=100, y=25, canto superior.

Novamente, o método closePath() completa nosso triângulo.

fig exemplo de canvas

var canvas = document.getElementById('ex02');
var context = canvas.getContext('2d');

context.beginPath();
context.moveTo(75,50);
context.lineTo(100,75);
context.lineTo(100,25);
context.closePath();
context.stroke();

Exemplo do método fill()

Esse triângulo começa em x=30, y=30, canto esquerdo.

Pinta uma reta até x=90, y=30.

Uma diagonal até x=30, y=90.

O método fill() desenha a última reta e preenche o triângulo.

fig exemplo de canvas

var canvas = document.getElementById('ex03');
var context = canvas.getContext('2d');

context.beginPath();
context.moveTo(30, 30);
context.lineTo(90, 30);
context.lineTo(30, 90);
context.fill();

Importante

Exemplo com método bezierCurveTo()

Ok, ainda não falamos (e continuaremos não falando) do método bezierCurveTo().

Mas não pude deixar de mostrar o exemplo.

fig exemplo de canvas

var canvas = document.getElementById('ex04');
var context = canvas.getContext('2d');

context.beginPath();
context.moveTo(10, 10);
context.lineTo(90, 90);
context.bezierCurveTo(30, 30, 30, 60, 60, 150);
context.fill();

O que as linhas tem a nos ensinar?

Quanto será que o path influencia nosso paint? Muito, compare os exemplos abaixo.

fig exemplo de canvas

var canvas = document.getElementById('ex05');
var context = canvas.getContext('2d');

context.beginPath();
context.moveTo(60, 30);
context.lineTo(240, 30);
context.stroke();

context.beginPath();
context.moveTo(60, 60);
context.lineTo(240, 60);
context.stroke();

context.beginPath();
context.moveTo(60, 90);
context.lineTo(240, 90);
context.stroke();

context.beginPath();
context.moveTo(60, 120);
context.lineTo(240, 120);
context.stroke();

No código acima, todas as linhas estão no tom cinza.

Já o debaixo, apenas a última linha está com tom cinza.

fig exemplo de canvas

var canvas = document.getElementById('ex06');
var context = canvas.getContext('2d');

//context.beginPath();
context.moveTo(60, 30);
context.lineTo(240, 30);
context.stroke();

//context.beginPath();
context.moveTo(60, 60);
context.lineTo(240, 60);
context.stroke();

//context.beginPath();
context.moveTo(60, 90);
context.lineTo(240, 90);
context.stroke();

//context.beginPath();
context.moveTo(60, 120);
context.lineTo(240, 120);
context.stroke();

Repare que no segundo exemplo o beginPath() foi comentado (anulado).

Qual é a diferença entre os resultados?

A princípo percebe-se uma inconsistencia no exemplo sem o beginPath().

Então podemos afirmar que o path ajuda na consistencia de nosso desenho.

Desafio

No primeiro exemplo, fazemos uso da função beginPath() mas não fechamos os caminhos (closePath()).

O que isso siginifca?

Que o beginPath() seguido de outro beginPath() inicia um subPath ?

ou...

Que o beginPath() seguido de outro beginPath() funciona também como closePath()?

Fonte

Próxima matéria

Canvas - Desenhando retângulos (strokeRect, fillRect, clearRect e rect)

Comentários

comments powered by Disqus