Pular para o conteúdo
murad.guide

Referência Essencial da Web

Capítulo 20

Objetos avançados

3 min de leitura 532 palavras 1 gravura

Trabalhe numa cópia da pasta inicio/ desta etapa. Ela já abre ou executa com as instruções do README. Leia o código, mude uma coisa e anote sua previsão antes de recarregar. Compare com a referência na pasta da etapa. Se nada mudar, confira a extensão do arquivo, o arquivo salvo e o caminho aberto. Blocos adicionais do capítulo são experiências separadas; a pasta de referência contém o programa completo desta etapa.

A Biblioteca da Ribeira é um acervo comunitário fictício no bairro da Ribeira, Recife. Neste capítulo o pátio ganha bolas que andam sozinhas: cada bola é um objeto, com posição, cor e o que sabe fazer.

O exemplo está em exemplos/20-objetos-avancados/. Abra index.html. O ciclo: ler, copiar, mudar uma coisa, prever, recarregar, conferir.

O que você vai aprender

Objeto: dados e ação

Um objeto guarda estado e ação. Estado é o que ele é agora: x, y, cor. Ação é o que ele sabe fazer: andar(), desenhar().

Objeto com dados de um lado e métodos do outro

Sem objeto, você espalha variáveis soltas. Com objeto, cada bola carrega o próprio pacote.

Classe e constructor

class descreve o molde. constructor roda quando você faz new Bola(...). this é aquela bola, não as outras.

class Bola {
  constructor(x, y, vx, cor) {
    this.x = x;
    this.y = y;
    this.vx = vx;
    this.vy = 1.4;
    this.cor = cor;
  }
  andar(largura, altura) {
    this.x += this.vx;
    this.y += this.vy;
    if (this.x < 12 || this.x > largura - 12) this.vx *= -1;
    if (this.y < 12 || this.y > altura - 12) this.vy *= -1;
  }
  desenhar(ctx) {
    ctx.beginPath();
    ctx.arc(this.x, this.y, 12, 0, Math.PI * 2);
    ctx.fillStyle = this.cor;
    ctx.fill();
  }
}

Três new Bola criam três instâncias. Mudar a cor de uma não pinta as outras.

Protótipo, só a ideia

Por baixo, o JavaScript liga cada instância a um protótipo: um objeto compartilhado com os métodos. Você não precisa escrever Bola.prototype neste volume.

A ideia basta: andar e desenhar existem uma vez no molde. Cada bola só guarda x, y, vx, vy e cor.

Bolas no canvas

canvas é um retângulo de desenho. getContext("2d") entrega o pincel. requestAnimationFrame pede o próximo quadro.

<!DOCTYPE html>
<html lang="pt-BR">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Bolas no pátio</title>
    <style>canvas { border: 1px solid #0f3d3e; background: #f4f1ea; max-width: 100%; }</style>
  </head>
  <body>
    <h1>Bolas no pátio</h1>
    <canvas id="patio" width="640" height="360"></canvas>
    <script src="bolas.js"></script>
  </body>
</html>

O arquivo bolas.js da pasta continua assim, depois da classe:

const canvas = document.getElementById("patio");
const ctx = canvas.getContext("2d");
const bolas = [
  new Bola(40, 40, 2, "#0f3d3e"),
  new Bola(200, 80, -1.5, "#e07a5f"),
  new Bola(320, 120, 1.2, "#3d6b6c")
];
function quadro() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  bolas.forEach(function (bola) {
    bola.andar(canvas.width, canvas.height);
    bola.desenhar(ctx);
  });
  requestAnimationFrame(quadro);
}
quadro();

Mude a cor da segunda bola para "#6b8f90". Preveja: só ela muda. Recarregue. Confira.

Erro comum: esquecer id="patio" ou o script depois do canvas. getElementById devolve null e a página para.

Arquivo no disco é o código. A janela mostra o pátio. Servidor de estudo, se usar, só em 127.0.0.1. Isto não é publicação.

O botão Pausar movimento interrompe os quadros. Com movimento reduzido, o desenho começa parado; o aluno pode iniciar se desejar.

Atividades

  1. O que new Bola(40, 40, 2, "#0f3d3e") cria que um objeto literal { x: 40 } ainda não resolve sozinho?
  2. Por que mudar this.cor numa instância não pinta as outras?
  3. O que ctx.clearRect evita se o quadro anterior não for apagado?

Respostas comentadas

  1. Uma instância do molde, com métodos andar e desenhar prontos. O literal só guarda números até você copiar as funções à mão.
  2. Cada new tem o próprio this. A cor mora na instância, não no molde compartilhado.
  3. Evita rastro. Sem limpar, a bola desenha por cima do quadro antigo e vira uma mancha.

O arquivo completo

Referência do exemplo 20-objetos-avancados, reproduzida aqui para que você possa conferir sem sair da página.

index.html

<!DOCTYPE html>

<html lang="pt-BR">
<head>
<meta charset="utf-8"/>
<meta content="width=device-width, initial-scale=1" name="viewport"/>
<title>Bolas no pátio</title>
<style>canvas { border: 1px solid #0f3d3e; background: #f4f1ea; max-width: 100%; }</style>
<style>
/* Apoio de leitura, teclado e tela estreita. */
img{max-width:100%;height:auto} html {overflow-wrap:anywhere} main {min-width:0} input,textarea,select,canvas {max-width:100%;box-sizing:border-box} fieldset {min-width:0}
pre {max-width:100%;overflow:auto} :focus-visible {outline:3px solid #0f3d3e;outline-offset:3px}
.skip {position:absolute;top:-5rem;left:1rem;background:#0f3d3e;color:white;padding:.5rem;z-index:9}.skip:focus {top:.5rem}
table {max-width:100%} td,th {overflow-wrap:anywhere}
@media(prefers-reduced-motion:reduce){*,*::before,*::after{animation:none!important;transition:none!important;scroll-behavior:auto!important}}
</style></head>
<body><a class="skip" href="#conteudo">Pular para o conteúdo</a><main id="conteudo" tabindex="-1">
<h1>Bolas no pátio</h1>
<button id="movimento" type="button">Pausar movimento</button><p>Desenho de três bolas para observar objetos; não há informação disponível apenas no movimento.</p><canvas height="360" id="patio" width="640"></canvas>

</main><script src="bolas.js"></script></body>
</html>