O objetivo é entender lógica de programação com javascript puro na criação de botão.

Primeiro, quais são os requisitos mínimos de um botão?

  1. Uma forma na tela (normalmente um retângulo)

Podemos cobrir os requisitos 1 e 2 facilmente:

fill(0, 234, 255);
rect(100, 100, 150, 50, 5);
fill(0, 0, 0);
textSize(19);
text("Useless button", 110, 133);

Para cobrir o requisito 3, precisamos definir uma função mouseClicked que será chamada quando o usuário clicar. Dentro dela, precisamos verificar se mouseX e mouseY estão dentro da caixa delimitadora do botão. Para o botão acima, ela estende-se de x=100 até x=250, e de y=100 até y=150, conforme ilustrado abaixo:

Podemos verificar as coordenadas utilizando && para unir as quatro condições:

mouseClicked = function() {
if (mouseX >= 100 && mouseX <= 250 &&
mouseY >= 100 && mouseY <= 150) {
println("Ainda continua inútil");
}
};

Tente clicar no botão e na área em volta para ver se ele funciona:

Ele definitivamente funciona, mas isso também me preocupa. Estou preocupado por não ser código muito reutilizável. Quanto trabalho eu terei se quiser mudar o botão de posição? (Experimente acima!) Eu vejo muitos números fixados no código — como as coordenadas na função mouseClicked, o que imediatamente me leva a pensar se não há uma maneira mais simples de fazer isso.

Para começar, vamos criar variáveis para a posição e tamanho, de forma que possamos mudar esses valores em um só lugar e, mesmo assim, manter o clique funcionando. Eu adicionei btnX, btnY, btnWidth e btnHeight ao programa abaixo. Experimente mudar seus valores e clicar no botão:

Bem, assim está melhor. No entanto, quanto trabalho terei se quiser adicionar mais um botão? Tenho que copiar e colar tudo aquilo, e criar btn2X, btn2Y? Ah, isso não parece muito divertido. Isso parece um bom motivo para escrever uma função que se encarregará de fazer tudo que for igual para os botões, e usará parâmetros para lidar com o que for diferente. Nós poderíamos escrevê-la assim, transformando as variáveis em parâmetros:

var drawButton = function(btnX, btnY, btnWidth, btnHeight) {
fill(0, 234, 255);
rect(btnX, btnY, btnWidth, btnHeight, 5);
fill(0, 0, 0);
textSize(19);
textAlign(LEFT, TOP);
text("Useless button", btnX+10, btnY+btnHeight/4);
};

Então, chamamos a função assim:

drawButton(100, 100, 150, 50);

Mas, e o nosso código de mouseClicked? Vê qual seria o problema com isso?

mouseClicked = function() {
if (mouseX >= btnX && mouseX <= (btnX+btnWidth) &&
mouseY >= btnY && mouseY <= (btnY+btnHeight)) {
println("Ainda continua inútil");
}
};

Se tivéssemos todo esse código junto, teríamos um erro de “Oh, não” com “btnX não está definido” — e ele está certo! Nós transformamos btnX em um parâmetro de função, o que significa que não é mais uma variável global. Isso é ótimo para a reutilização da função drawButton, mas, agora, a função mouseClicked não tem como saber as coordenadas que precisa verificar.

Então nós precisamos descobrir uma boa maneira de passar a informação para drawButton e disponibilizar essa informação para mouseClicked. Eu tenho algumas opções:

  1. Criar novamente variáveis globais para a posição e o tamanho (btnX, btnY, btnWidth, btnHeight)

Qual escolher? Bem, eu não gosto muito da primeira porque teríamos que adicionar muitas variáveis globais e eu tenho uma alergia a variáveis globais. Eu não amo a segunda técnica porque é difícil ler código que pega dados baseados em índices de arranjos. Gosto da terceira técnica porque ela usa somente uma variável global, e assim o código fica mais legível. Eu também gosto da quarta técnica, que usa princípios orientados a objetos para criar tipos de objeto Button genéricos, mas vamos deixar isso para depois.

Podemos criar nosso objeto global btn1 da seguinte forma:

var btn1 = {
x: 100,
y: 100,
width: 150,
height: 50
};

E alterar a função drawButton para aceitar um único objeto, do qual então pega as propriedades:

var drawButton = function(btn) {
fill(0, 234, 255);
rect(btn.x, btn.y, btn.width, btn.height, 5);
fill(0, 0, 0);
textSize(19);
textAlign(LEFT, TOP);
text("Useless button", btn.x+10, btn.y+btn.height/4);
};

A função mouseClicked irá verificar as propriedades da variável global:

mouseClicked = function() {
if (mouseX >= btn1.x && mouseX <= (btn1.x+btn1.width) &&
mouseY >= btn1.y && mouseY <= (btn1.y+btn1.height)) {
println("Ainda continua inútil");
}
};

Experimente fazer isso! Como antes, tente alterar parâmetros diferentes do botão e ver se ele continua funcionando:

A ideia de fazer isso é que possamos adicionar mais botões com facilidade, o último teste de reusabilidade. Podemos fazer isso?

Vamos começar com uma nova variável global, btn2, com deslocamento na direção y do primeiro botão:

var btn2 = {
x: 100,
y: 200,
width: 150,
height: 50
};

Em seguida, vamos desenhar esse botão:

drawButton(btn2);

Desse modo, conseguiremos desenhar 2 botões na tela, mas somente o primeiro responderá a cliques. Nós podemos fazer o segundo responder ao duplicar a lógica e substituir btn2 por btn1, assim:

mouseClicked = function() {
if (mouseX >= btn1.x && mouseX <= (btn1.x+btn1.width) &&
mouseY >= btn1.y && mouseY <= (btn1.y+btn1.height)) {
println("Ainda continua inútil");
}
if (mouseX >= btn2.x && mouseX <= (btn2.x+btn2.width) &&
mouseY >= btn2.y && mouseY <= (btn2.y+btn2.height)) {
println("O segundo também ainda inútil!");
}
};

Mas todo esse código repetido não te deixa de nariz torcido? Vamos criar uma função isMouseInside que sabe verificar qualquer objeto de botão e retorna "verdadeiro" se o mouse estiver dentro dele:

var isMouseInside = function(btn) {
return (mouseX >= btn.x &&
mouseX <= (btn.x+btn.width) &&
mouseY >= btn.y &&
mouseY <= (btn.y+btn.height));
};

Agora, podemos usar a função dentro de mouseClicked para reduzir drasticamente a quantidade de código repetido:

mouseClicked = function() {
if (isMouseInside(btn1)) {
println("Ainda continua inútil ");
} else if (isMouseInside(btn2)) {
println("2nd one still quite useless!");
}
};

Aí está! Usamos funções para desenhar vários botões, e ficou relativamente fácil adicionar novos botões. Tente fazer isso abaixo:

Poderíamos continuar — criando arranjos de todos os botões de um programa, tornando possível personalizar o texto e a cor de um botão — mas espero que o que foi feito já tenha te dado uma boa base para criar botões simples usando funções. Em seguida, vamos percorrer passo a passo a criação de botões usando princípios orientados a objeto.

Lembrando que esse e outros conteúdos estão disponíveis no Khan Academy.

Esse artigo ficou menor que os demais, mas a intenção é tratar situações mais específicas nesse tipo de tema técnico e prático. Tomara que tenha gostado, aplauda o artigo! Até o próximo artigo e ótimos códigos.

Developer Frontend Web — Javascript | ReactJS https://linktr.ee/douglasabnovato

Developer Frontend Web — Javascript | ReactJS https://linktr.ee/douglasabnovato