Desenhando Formas - JavaScript
Além de retângulos, o canvas permite desenhar formas mais complexas. Para construir essas formas complexas, utilizamos a concepção de caminhos geométricos, que consistem em um conjunto de linhas, círculos, retângulos e outros elementos menores, necessários para a construção da forma desejada.
Para criar um novo caminho, utilizamos o método beginPath()
const canvas = document.getElementById("canvas");
const context = canvas.getContext("2d");
context.beginPath(); // começando o desenho da forma
Após chamar o método beginPath()
Métodos moveTo() e lineTo()
Para iniciar o desenho de um caminho, precisamos definir o ponto de partida. Isso pode ser feito com o método moveTo()
moveTo(x, y)
Esse método move a posição atual para o ponto especificado pelas coordenadas x
y
O método lineTo()
lineTo(x, y)
Esse método desenha uma linha da posição atual até o ponto com as coordenadas x
y
Vamos desenhar algumas linhas:
const canvas = document.getElementById("canvas");
const context = canvas.getContext("2d");
context.beginPath();
context.moveTo(20, 100);
context.lineTo(140, 10);
context.lineTo(260, 100);
context.stroke();
Aqui, definimos o início do caminho no ponto (20, 100)
(140, 10)
(260, 100)
stroke()
Por padrão, o desenho será feito em preto, mas podemos alterar a cor utilizando a propriedade strokeStyle
const canvas = document.getElementById("canvas");
const context = canvas.getContext("2d");
context.beginPath();
context.moveTo(20, 100);
context.lineTo(140, 10);
context.lineTo(260, 100);
context.strokeStyle = "red"; // definindo a cor vermelha
context.stroke(); // exibindo o caminho
Fechando o Caminho
Desenhamos duas linhas e, supondo que queremos conectá-las para formar uma figura fechada — neste caso, um triângulo — podemos utilizar o método closePath()
const canvas = document.getElementById("canvas");
const context = canvas.getContext("2d");
context.beginPath();
context.moveTo(20, 100);
context.lineTo(140, 10);
context.lineTo(260, 100);
context.closePath(); // fechando o caminho
context.stroke();
Objetos Path2D
Ao trabalhar com vários caminhos, pode ser difícil gerenciá-los. Para separar diferentes caminhos, podemos utilizar o objeto Path2D
const canvas = document.getElementById("canvas");
const context = canvas.getContext("2d");
const path1 = new Path2D(); // primeiro caminho
path1.moveTo(20, 100);
path1.lineTo(140, 10);
path1.lineTo(260, 100);
path1.closePath(); // fechando o caminho
context.strokeStyle = "blue";
context.stroke(path1);
const path2 = new Path2D(); // segundo caminho
path2.moveTo(20, 110);
path2.lineTo(140, 200);
path2.lineTo(260, 110);
path2.closePath(); // fechando o caminho
context.strokeStyle = "red";
context.stroke(path2);
Aqui, criamos dois caminhos, cada um representando um triângulo. Para desenhar cada caminho, chamamos o método context.stroke()
Método rect
O método rect()
rect(x, y, width, height)
Onde x
y
const canvas = document.getElementById("canvas");
const context = canvas.getContext("2d");
context.beginPath();
context.rect(30, 20, 100, 90);
context.closePath();
context.stroke();
Vale notar que poderíamos criar o mesmo retângulo utilizando linhas:
const canvas = document.getElementById("canvas");
const context = canvas.getContext("2d");
context.beginPath();
context.moveTo(30, 20);
context.lineTo(130, 20);
context.lineTo(130, 110);
context.lineTo(30, 110);
context.closePath();
context.stroke();
Método fill()
O método fill()
const canvas = document.getElementById("canvas");
const context = canvas.getContext("2d");
context.beginPath();
context.moveTo(20, 100);
context.lineTo(140, 10);
context.lineTo(260, 100);
context.closePath();
context.strokeStyle = "#2e86de";
context.fillStyle = "#4bcffa";
context.fill();
context.stroke();
A cor de preenchimento pode ser definida usando a propriedade fillStyle
#4bcffa
Método clip()
O método clip()
Para entender melhor como esse método funciona, primeiro desenharemos dois retângulos:
const canvas = document.getElementById("canvas");
const context = canvas.getContext("2d");
// desenhando o primeiro retângulo vermelho
context.beginPath();
context.moveTo(10, 20);
context.lineTo(130, 20);
context.lineTo(130, 110);
context.lineTo(10, 110);
context.closePath();
context.strokeStyle = "red";
context.stroke();
// desenhando o segundo retângulo verde
context.beginPath();
context.rect(30, 50, 180, 70);
context.closePath();
context.strokeStyle = "green";
context.stroke();
Agora, vamos aplicar o método clip()
const canvas = document.getElementById("canvas");
const context = canvas.getContext("2d");
// desenhando o primeiro retângulo vermelho
context.beginPath();
context.moveTo(10, 20);
context.lineTo(130, 20);
context.lineTo(130, 110);
context.lineTo(10, 110);
context.closePath();
context.strokeStyle = "red";
context.stroke();
context.clip(); // recortando a área de desenho conforme o primeiro caminho
// desenhando o segundo retângulo verde
context.beginPath();
context.rect(30, 50, 180, 70);
context.closePath();
context.strokeStyle = "green";
context.stroke();
Como o método clip() é chamado após o desenho do primeiro retângulo, apenas a parte do segundo retângulo que se sobrepõe ao primeiro será exibida.
Método arc()
O método arc()
arc(x, y, radius, startAngle, endAngle, anticlockwise)
Aqui estão os parâmetros utilizados:
ex
: coordenadas do ponto central do arco.y
: raio do círculo no qual o arco é desenhado.radius
estartAngle
: ângulos inicial e final que definem a porção do círculo que será desenhada. Esses ângulos são medidos em radianos. Por exemplo, uma circunferência completa equivale a 2π radianos. Em JavaScript, podemos obter esse valor com a expressãoendAngle
.Math.PI * 2
: define a direção do traçado. Se tranticlockwise
ue, o arco é traçado no sentido anti-horário; se , no sentido horário.false
Exemplo de desenho de arcos e círculos:
const canvas = document.getElementById("canvas");
const context = canvas.getContext("2d");
context.strokeStyle = "red";
context.beginPath();
context.moveTo(20, 90);
context.arc(20, 90, 50, 0, Math.PI/2, false);
context.closePath();
context.stroke();
context.beginPath();
context.moveTo(130, 90);
context.arc(130, 90, 50, 0, Math.PI, false);
context.closePath();
context.stroke();
context.beginPath();
context.moveTo(240, 90);
context.arc(240, 90, 50, 0, Math.PI * 3 / 2, false);
context.closePath();
context.stroke();
context.beginPath();
context.arc(350, 90, 50, 0, Math.PI * 2, false);
context.closePath();
context.stroke();
O último parâmetro, anticlockwise
true
false
const canvas = document.getElementById("canvas");
const context = canvas.getContext("2d");
context.strokeStyle = "red";
context.beginPath();
context.moveTo(80, 90);
context.arc(80, 90, 50, 0, Math.PI/2, false);
context.closePath();
context.stroke();
context.beginPath();
context.moveTo(240, 90);
context.arc(240, 90, 50, 0, Math.PI/2, true);
context.closePath();
context.stroke();
Método arcTo()
O método arcTo()
arcTo(x1, y1, x2, y2, radius)
Onde x1
y1
x2
y2
radius
Exemplo de desenho de arcos com arcTo()
const canvas = document.getElementById("canvas");
const canvas = document.getElementById("canvas");
const context = canvas.getContext("2d");
context.strokeStyle = "red";
context.beginPath();
context.moveTo(0, 150);
context.arcTo(0, 0, 150, 0, 140);
context.closePath();
context.stroke();
Neste exemplo, começamos no ponto (0, 150)
(0, 0)
(150, 0)
Método quadraticCurveTo()
O método quadraticCurveTo()
quadraticCurveTo(x1, y1, x2, y2)
Aqui, x1
y1
x2
y2
Exemplo de uma curva quadrática de bézier:
const canvas = document.getElementById("canvas");
const context = canvas.getContext("2d");
context.strokeStyle = "red";
context.beginPath();
context.moveTo(20, 90);
context.quadraticCurveTo(130, 0, 280, 90);
context.closePath();
context.stroke();
Neste exemplo, a curva começa no ponto (20, 90)
(130, 0)
(280, 90)
Método bezierCurveTo()
O método bezierCurveTo()
bezierCurveTo(x1, y1, x2, y2, x3, y3)
Onde x1
y1
x2
y2
x3
y3
Exemplo de uma curva bézier:
const canvas = document.getElementById("canvas");
const context = canvas.getContext("2d");
context.strokeStyle = "red";
context.beginPath();
context.moveTo(30, 100);
context.bezierCurveTo(110, 0, 190, 200, 270, 100);
context.closePath();
context.stroke();
Neste exemplo, a curva começa no ponto (30, 100)
(110, 0)
(190, 200)
(270, 100)
Figuras Complexas
Agora, vamos combinar várias formas para desenhar uma cena bidimensional mais complexa:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Desenho Complexo</title>
</head>
<body>
<canvas id="canvas" width="400" height="250"></canvas>
<script>
const canvas = document.getElementById("canvas");
const context = canvas.getContext("2d");
// Desenhando o fundo amarelo
context.fillStyle = "yellow";
context.beginPath();
context.arc(160, 130, 100, 0, 2 * Math.PI);
context.fill();
// Desenhando a boca
context.beginPath();
context.moveTo(100, 160);
context.quadraticCurveTo(160, 250, 220, 160);
context.closePath();
context.fillStyle = "red";
context.fill();
context.lineWidth = 2;
context.strokeStyle = "black";
context.stroke();
// Desenhando os dentes
context.fillStyle = "#FFFFFF";
context.fillRect(140, 160, 15, 15);
context.fillRect(170, 160, 15, 15);
// Desenhando os olhos
context.beginPath();
context.arc(130, 90, 20, 0, 2 * Math.PI);
context.fillStyle = "#333333";
context.fill();
context.closePath();
context.beginPath();
context.arc(190, 90, 20, 0, 2 * Math.PI);
context.fillStyle = "#333333";
context.fill();
context.closePath();
</script>
</body>
</html>