/cefet-front-end-snap

Uma ferramenta para marcar suas fotos!

Primary LanguageCSS

PokéhotoSnap

Uma ferramenta para marcar suas fotos! Baixe o código seminal.

Atividade

Você deve modificar a página para que ela mostre duas marcações (pokémons) na imagem (foto). Cada marcação é definida por um quadrado e possui um título e um conteúdo, que devem ser exibidos em um balãozinho quando o usuário passar o mouse sobre cada uma.

Exercício 1: Alterar/remover conteúdo do balãozinho

Resultado da realização do exercício 1

Crie um código JavaScript (e.g., balaozinho.js) que, para cada região anotada (.marcacao, cada quadradinho dentro da imagem), define o conteúdo do elemento #balaozinho (lembre-se como definir o conteúdo de um elemento HTML) com uma string qualquer.

Você deve atrelar os devidos eventos de mouse a cada¹ .marcacao para que (relembre os eventos de mouse):

  1. quando o mouse entrar no quadradinho, definir o conteúdo do #balaozinho como uma string qualquer
  2. quando o mouse sair do quadradinho, definir o conteúdo como uma string vazia

Se acontecer do balãozinho ficar "piscando" ao mexer o mouse, veja o FAQ sobre como consertar.

¹ No momento existem duas .marcacaos, mas pode ser que existam muitas outras, ou até nenhuma. Lembre-se de como selecionar vários elementos do DOM. Você fez isso na prática da exploração espacial. Lembre-se também de como associar eventos a elementos HTML.

Exercício 2: Formatação do balãozinho

Resultado da realização do exercício 2

Este é um exercício de CSS mesmo (não precisa fazer em JavaScript). Estilize o #balaozinho para que ele se pareça com um balãozinho mesmo. Sugestões:

  • Tamanho de fonte menor (tipo 10px)
  • Cor de fundo semitransparente
  • Bordinha marota
  • Um espacinho interno (padding)
  • Cantinho levemente arredondado
  • Uma sombra sinistra (veja FAQ)

Além disso, altere o pointeiro do mouse quando ele estiver em uma .marcacao. Isso pode ser feito em uma regra que estiliza .marcacao e define a propriedade cursor como help (interrogação) ou pointer (mãozinha).

Exercício 3: Definir título/conteúdo correto do balãozinho

Resultado da realização do exercício 3

Agora, você deve substituir a "string qualquer" com um trecho HTML que contenha o título e o conteúdo da marcação, tipo assim:

<div id="balaozinho">  
  <h2>título da anotação</h2>
  <p>conteúdo da anotação</p>
</div>

Você sabia?? É possível colocar elementos HTML dentro de uma string que estamos atribuindo ao innerHTML de um elemento, tipo assim:

algumEl.innerHTML = '<span>abc</span><div>def</div>';

Mas como saber qual das duas .marcacao passamos o mouse em cima? Basta pegar qual elemento foi alvo do evento (mouseover). Para isso, lembre-se do argumento de evento (vimos na aula da exploração espacial para saber qual dos botões dos parágrafos havia sido clicado).

Cada .marcacao é uma <div></div> devidamente estilizada e ela está assim:

<div class="marcacao"
  data-titulo="Electrode"
  data-conteudo="Este é uma pseudo-pokébola invertida"
  style="width: 20px; height: 20px; top: 10px; left: 40px;"></div>

Elas possuem dois atributos "personalizados" (nome certo é "atributos de dados"): um deles chama data-titulo="..." e armazena o título daquela marcação e o outro chama data-conteudo="..." e armazena o texto que deve ir dentro do parágrafo do balãozinho.

Na verdade, nós podemos usar atributos que não existem no HTML para nossos próprios propósitos. Basta colocar data-novoatributo em um elemento (data em inglês = dados em português).

Para acessar o valor desses atributos, usamos uma propriedade dataset do elemento HTML, assim:

<span data-dikentinha="um certo texto">Algum assunto</span>
let algumEl = document.querySelector('....');
let dikentinha = algumEl.dataset.dikentinha;
// variável dikentinha contém "um certo texto"

Exercício 4: Posicionamento do balãozinho

Resultado da realização do exercício 4

Faça com que, quando o mouse se movimente dentro de uma .marcacao, o #balaozinho se posicione nas mesmas coordenadas que o mouse. Veja como pegar a posição do mouse nos slides. Lembre-se: será necessário usar o argumento de evento, que é um parâmetro das callbacks de evento e contém informações sobre o que aconteceu.

Exercício 5: Definição da 1ª marcação

Resultado da realização do exercício 5

Faça com que o usuário possa definir as propriedades da 1ª marcação (left, top, width, height) a partir dos campos input à direita.

Quando o botão for clicado, as propriedades da 1ª marcação devem ser atualizadas.

Como um mimo para os olhos do usuário, você pode colocar, em CSS, a propriedade transition: all 200ms ease na .marcacao para que os valores alterdos das propriedades façam uma transição suave (fica show).

Desafio 1: Atualização mais ágil da marcação

Em vez de usar o botão para atualizar as propriedades da marcação, faça com que assim que o usuário pressionar uma tecla em qualquer dos inputs, a região da marcação seja atualizada. Aí você pode até tirar o botão do HTML.

Isso pode ser feito com o evento change (ainda não vimos) que pode ser associado a um input.

Desafio 2: Definição da marcação sendo editada

Faça com que, em vez de poder alterar apenas a 1ª marcação, o usuário possa escolher qual delas quer atualizar.

Uma ideia é: (1) ter uma variável global que aponta para a marcacaoAtualEl, (2) colocar eventos de click às marcações e, na callback registrada, (3) atualizar o valor dessa variável para o elemento que foi alvo do evento.

Além disso, se quiser indicar visualmente qual é a marcação selecionada, faça com que ela (e apenas ela) tenha a classe .selecionada.

Desafio 3: Escolha da imagem (hardcore! 💣💣💣)

Existe um <input type="file"> que permite ao usuário escolher um arquivo de seu computador. Você pode colocar um desses na página e, assim que o usuário alterar valor desse input (evento change), seu código altera a imagem que está sendo anotada.

Desafio mais difícil: veja o artigo a seguir e tente identificar um código nele que faz o que você precisa: deixa usuário escolher um arquivo e o coloca como uma imagem no lugar da foto dos pokémons.

Referência: https://www.html5rocks.com/en/tutorials/file/dndfiles/

FAQ

Balãozinho piscando quando movimento o mouse

Pode acontecer de o balãozinho ficar "piscando" quando você movimenta o mouse em cima da marcação. Isso acontece porque o navegador entende que ora o mouse está em cima da marcação, ora ele está em cima do balãozinho - e isso alterna muitas vezes por segundo.

Uma forma de evitar isso é posicionar o balãozinho a uma certa distância do mouse, em vez de exatamente na posição dele. Outra forma é falar que a <div id="balaozinho">...</div> não "responde" a eventos de mouse. É possível fazer isso bem facilmente com uma propriedade CSS no #balaozinho: propriedade pointer-events com valor none.

Como altero uma propriedade CSS de um elemento dinamicamente?

Há 2 formas, sendo uma delas colocando e tirando classes, e a outra alterando a propriedades CSS diretamente.

Como fazer sombras em CSS?

Existe a propriedade box-shadow. Ela funciona assim:

div {
  box-shadow: 4px 4px 4px silver;
}

O primeiro valor é o deslocamento horizontal da sombra (positivo vai para a direita), o segundo é o vertical (positivo vai para baixo), o terceiro é o quanto a sombra está "borrada" (para uma borda suave, coloque algo diferente de 0) e o quarto é a cor da sombra.

A cor da sombra, tipicamente, colocamos uma cor semitransparente (e.g., rgba(...., 0.2)).

Ficou um quadradinho visível no balãozinho

Se após estilizar o balãozinho (Exercício 2), ao tirar o mouse de cima de uma marcação, continuar aparecendo um quadradinho no lugar do balão, é devido ao `padding` (espaçamento interno) que foi colocado nele.

Para que o balãozinho fique oculto quando estiver vazio, nesse caso, uma forma é colocar um balaozinhoEl.style.display = 'none' no mouseout e ...display = 'block' no mouseover.

Ou então, dá pra fazer via CSS também, usando a pseudoclasse :empty. Ela serve para estilizar elementos quando eles estão vazios (ou seja, seu innerHTML === ''). Então, poderia ser feito assim:

#balaozinho:empty {
  display: none;
}

Obs: fazendo isso, o quadradinho ainda ficará aparecendo quando a página carrega. Isso acontece porque o .innerHTML do balãozinho não está vazio, porque ele contém um comentário dentro dele. Nesse caso, basta apagar o comentário e não deixar nenhum espaço entre a tag de abertura e a de fechamento, assim: <div id="balaozinho"></div>.