Solucionado (ver solução)
Solucionado
(ver solução)
7
respostas

Eita Consegui!!!

Gente a milha solução foi muito complicada!!!!

Eu criei uma modal para selecionar a cor. Nessa modal, tem 2 botões um pra cancelar, outro para alterar a cor. Tem um select com o nome das cores e ao lado do select tem uma div que mostra a cor que está pra selecionar. Não sei se aqui dará todo meu código. Mas lá vai!

7 respostas

HTML

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <link rel="shortcut icon" type="image/jpg" href="img/favicon.ico" />
    <title>Robotron 2000</title>

    <link rel="stylesheet" href="css/style.css" />
    <link rel="preconnect" href="https://fonts.googleapis.com" />
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
    <link href="https://fonts.googleapis.com/css2?family=Teko:wght@300;500&display=swap" rel="stylesheet" />
  </head>
  <body>
    <main>
      <section class="robotron">
        <img class="robo" src="img/robotron.png" alt="Robotron" imgRobotron />
        <figcaption class="titulo">ROBOTRON <br />2000</figcaption>
      </section>

      <section class="box estatisticas">
        <div class="estatistica">
          <p class="estatistica-titulo">Força</p>
          <div class="estatistica-valor">
            <p class="estatistica-numero" data-estatistica="forca">0</p>
          </div>
        </div>
        <div class="estatistica">
          <p class="estatistica-titulo">Poder</p>
          <div class="estatistica-valor">
            <p class="estatistica-numero" data-estatistica="poder">0</p>
          </div>
        </div>
        <div class="estatistica">
          <p class="estatistica-titulo">Energia</p>
          <div class="estatistica-valor">
            <p class="estatistica-numero" data-estatistica="energia">0</p>
          </div>
        </div>
        <div class="estatistica">
          <p class="estatistica-titulo">Velocidade</p>
          <div class="estatistica-valor">
            <p class="estatistica-numero" data-estatistica="velocidade">0</p>
          </div>
        </div>
      </section>

      <section class="equipamentos">
        <form action="" class="montador">
          <div class="box montador-conteudo">
            <div class="peca">
              <label for="" class="peca-titulo">Braços</label>
              <div class="controle">
                <buttom class="controle-ajuste" data-operacao="-" data-peca="bracos">-</buttom>
                <input type="text" class="controle-contador" value="00" data-contador />
                <buttom class="controle-ajuste" data-operacao="+" data-peca="bracos">+</buttom>
              </div>
            </div>
            <hr class="linha" />
            <div class="peca">
              <label for="" class="peca-titulo">Blindagem</label>
              <div class="controle">
                <buttom class="controle-ajuste" data-operacao="-" data-peca="blindagem">-</buttom>
                <input type="text" class="controle-contador" value="00" data-contador />
                <buttom class="controle-ajuste" data-operacao="+" data-peca="blindagem">+</buttom>
              </div>
            </div>
            <hr class="linha" />
            <div class="peca">
              <label for="" class="peca-titulo">Núcleos</label>
              <div class="controle">
                <buttom class="controle-ajuste" data-operacao="-" data-peca="nucleos">-</buttom>
                <input type="text" class="controle-contador" value="00" data-contador/>
                <buttom class="controle-ajuste" data-operacao="+" data-peca="nucleos">+</buttom>
              </div>
            </div>
            <hr class="linha" />
            <div class="peca">
              <label for="" class="peca-titulo">Pernas</label>
              <div class="controle">
                <buttom class="controle-ajuste" data-operacao="-" data-peca="pernas">-</buttom>
                <input type="text" class="controle-contador" value="00" data-contador/>
                <buttom class="controle-ajuste" data-operacao="+" data-peca="pernas">+</buttom>
              </div>
            </div>
            <hr class="linha" />
            <div class="peca">
              <label for="" class="peca-titulo">Foguetes</label>
              <div class="controle">
                <buttom class="controle-ajuste" data-operacao="-" data-peca="foguetes">-</buttom>
                <input type="text" class="controle-contador" value="00" data-contador />
                <buttom class="controle-ajuste" data-operacao="+" data-peca="foguetes" >+</buttom>
              </div>
            </div>
          </div>
          <input type="submit" value="Iniciar produção" class="producao" id="producao"/>
        </form>
      </section>
    </main>

obs. continua na próxima página obs1: Mudei alguns nomes no HTML pq estava achando confuso.

<dialog class="dialog" id="selecionar-cor" dialo>
      <form method="dialog">
        <div class="dialog__form">
          <label for="cor-selecionada" class="label">Escolha a cor do seu robotron</label>

          <div class="dialog__container">
            <select id="cor-selecionada" name="cor-selecionada" select></select>
            <div class="dialog_mostra" mostra></div>
          </div>
        </div>
        <div class="dialog__buttons">
          <input type="submit" value="Confirmar" data-acao="confirmar" />
          <input type="submit" value="Cancelar" data-acao="cancelar" />
        </div>
      </form>
    </dialog>
    <script src="js/main.js" type="module"></script>
  </body>
</html>

CSS

:root {
    --main-cinza: #CCCCCC;
    --main-branco: #FFFFFF;
    --main-preto: #000000;
}

* {
    box-sizing: border-box;
}

body {
    background: url(../img/fundo.jpg);
    background-position: center center;
    background-size: cover cover;
    padding: 0;
    margin: 0;
    font-weight: 300;
}

body, input {
    font-family: 'Teko', sans-serif;
}

main {
    width: 80vw;
    height: 80vh;
    margin: 10vh 8vw 10vh 12vw;
    display: flex;
    gap: 1vw;
}

.robotron {
    background: url(../img/estrutura.png) no-repeat;
    background-position: center center;
    margin: 0;
    flex-basis: 40%;
    position: relative;
}

.robo {
    height: 110%;
    z-index: 1;
    position: absolute;
    left: -20%;
    top: -5%;
}

.titulo {
    transform: rotate(180deg);
    font-weight: 500;
    font-size: 8.12rem;
    position: absolute;
    bottom: 7rem;
    left: -3rem;
    line-height: 0.8;
    writing-mode: vertical-rl;
    text-orientation: mixed;
    color: rgba(255,255,255,0.8)
}

.box {
    background: rgba(0,0,0,0.6);
    clip-path: polygon(calc(100% - 30px) 0, 100% 30px, 100% calc(100% - 30px), calc(100% - 30px) 100%, 30px 100%, 0 calc(100% - 30px), 0 30px, 30px 0);
    border-left: 5px solid var(--main-cinza);
    height: 80%;
}

/****************************** Equipamentos *****/

.equipamentos {
    flex-basis: 32%;
}

.montador {
    height: 100%;;
}

.montador-conteudo {
    padding: 2em 10%;
}

.peca {
    padding: 1em 0;
}

.peca-titulo {
    color: var(--main-branco);
    text-transform: uppercase;
    font-size: 2.5em;
}

.controle {
    background: var(--main-preto);
    border-radius: 25px;
    float: right;
    display: inline-flex;
    padding: 5px;
    align-items: center;
    align-self: flex-end;
}

.controle-contador {
    width: 40px;
    height: 35px;
    background: none;
    border: 0;
    margin: 0 1rem;
    color: var(--main-branco);
    text-align: center;
    font-size: 2.5em;
    display: inline-flex;
    align-items: center;
    padding-top: 8px;
}

.controle-ajuste {
    display: inline-block;
    width: 40px;
    height: 40px;
    line-height: 44px;
    border-radius: 50%;
    color: var(--main-cinza);
    font-size: 4em;
    background: var(--main-preto);
    text-align: center;
    border: 3px solid var(--main-cinza);
    cursor: pointer;
}

.linha {
    border-color: var(--main-cinza);
}

.producao {
    margin-top: 1em;
    font-size: 2em;
    text-transform: uppercase;
    padding: 0.2em 1em;
    float: right;
    border: 3px solid var(--main-branco);
    background: var(--main-branco);
    clip-path: polygon(100% 0, 100% calc(100% - 30px), calc(100% - 30px) 100%, 0 100%, 0 0);
    cursor: pointer;
}

.producao:hover {
    background: var(--main-preto);
    color: var(--main-branco)
}



/****************************** Estatísticas *****/
.estatisticas {
    flex-basis: 23%;
    padding: 2em 2em 0;
}

.estatistica {
    color: var(--main-branco);
    display: flex;
    align-items: flex-start;
    height: 25%;
}

.estatistica-titulo {
    font-size: 1.5em;
    border-bottom: 1px solid var(--main-cinza);
    flex-basis: 40%;
    text-transform: uppercase;
    order: 1
}

.estatistica-valor {
    flex-basis: 60%;
    position: relative;
    margin: 10px 0 0;
    order: 2;
    margin: -10px 0 0;
}

.estatistica-valor::after {
    content: "";
    display: block;
    padding-bottom: 100%;
    border: 1px solid var(--main-cinza);
    border-radius: 50%;
}

.estatistica-numero {
    position: absolute;
    top: 50%;
    transform: translateY(-46%);
    width: 100%;
    line-height: 100%;
    text-align: center;
    font-size: 3em;
    margin: 0;
}

.estatistica:nth-child(2n) .estatistica-titulo {
    order: 2;
    text-align: right;
}

.estatistica:nth-child(2n) .estatistica-valor {
    order: 1;
    flex-basis: 35%;
    margin: 10px 0 0;
}

obs. continua na próxima pagina


@media screen and (max-width: 1600px) {
    body { 
        font-size: 14px;
    }
    main {
        width: 90vw;
        height: 80vh;
        margin: 5vh auto;
    }
}

@media screen and (max-width: 1200px) {
    body { 
        font-size: 13px;
    }

    main {
        width: 96vw;
        height: 80vh;
        margin: 10vh auto;
    }
}

/** Dialog 
* Selecionar cor do Robotron
*/
.dialog {
    width: 15rem;
    border-radius: 1rem;
}

.dialog form {    
    display: flex;
    flex-direction: column;
    gap: 1rem;
}

.dialog__form label{
    font-size: 1.2rem;
    font-weight: 400;
}

.dialog__container{
    display:flex;
    align-items: center;
    gap: 1rem;
}

[select]{
    border-radius: .5rem;
    padding: .5rem
}

[mostra]{
    width: 3rem;
    height: 2rem;
    border: 1px solid;
    border-radius: .5rem;
}

.dialog__buttons {
    display: flex;
    gap: 1rem;
}

[data-acao]{
    border-radius: .5rem;
    width: 5rem;
    font-size: 1.2rem;
}

JavaScript

const robotron = document.querySelector('.robotron')
const btnsControle = document.querySelectorAll('[data-operacao]') //somente botão
const estatisticas = document.querySelectorAll('[data-estatistica]') //estatísticas do robô

const pecas = {
  bracos: {
    forca: 29,
    poder: 35,
    energia: -21,
    velocidade: -5
  },

  blindagem: {
    forca: 41,
    poder: 20,
    energia: 0,
    velocidade: -20
  },
  nucleos: {
    forca: 0,
    poder: 7,
    energia: 48,
    velocidade: -24
  },
  pernas: {
    forca: 27,
    poder: 21,
    energia: -32,
    velocidade: 42
  },
  foguetes: {
    forca: 0,
    poder: 28,
    energia: 0,
    velocidade: -2
  }
}

const cores = {
  Amarelo: '#EFC821',
  Azul: '#9BCBD9',
  Branco: '#FAFEFE',
  Preto: '#1E0C10',
  Rosa: '#EA95BD',
  Vermelho: '#C15B48'
}

const corRobotron = (cor) => {
  let img = document.querySelector('[imgRobotron]')
  let pathImg = `../img/cores/Robotron 2000 - ${cor}.png`
  img.src = pathImg
  return img
}

function alterarCorRobotron() {
  let dialog = document.querySelector('[dialog]')
  let btnsDialog = dialog.querySelectorAll('[data-acao]')
  let select = dialog.querySelector('[select]')
  let mostraCores = dialog.querySelector('[mostra]')
  mostraCores.setAttribute('width', '50px')

  robotron.addEventListener('click', () => {
    for (const item in cores) {
      let opcao = document.createElement('option')
      opcao.setAttribute('value', item)
      opcao.style.fontSize = '16px'
      opcao.textContent = item

      select.appendChild(opcao)
    }

    select.addEventListener('mouseup', (e) => {
      let corDeFundo = e.target.value
      mostraCores.style.background = cores[corDeFundo]
    })
    dialog.showModal()
  })

  btnsDialog.forEach((button) => {
    button.addEventListener('click', (e) => {
      if (e.target.dataset.acao === 'confirmar') {
        corRobotron(select.value)
        select.innerHTML = ''
      }
    })
  })
}

alterarCorRobotron()

function alterarCorContador(peca) {
  const atributoFraco = '#EB4F3B'
  const atributoMedio = '#EBD43F'
  const atributoForte = '#3EEB55'

  let vlrPeca = parseInt(peca.value)
  let nivel = vlrPeca < 3 ? 'fraco' : vlrPeca < 7 ? 'medio' : 'forte'

  switch (nivel) {
    case 'fraco':
      peca.style.color = atributoFraco
      break
    case 'medio':
      peca.style.color = atributoMedio
      break
    case 'forte':
      peca.style.color = atributoForte
      break
  }
}

function manipularDados(operacao, controle) {
  let peca = controle.querySelector('[data-contador]')
  peca.value =
    operacao === '-'
      ? limitarValorMinimoPeca(peca)
        ? parseInt(peca.value) - 1
        : peca.value
      : limitarValorMaximoPeca(peca)
      ? parseInt(peca.value) + 1
      : peca.value

  alterarCorContador(peca)
}

function atualizarEstatistica(peca) {
  estatisticas.forEach((item) => {
    let vlrEstatistica = parseInt(item.textContent)

    item.textContent = vlrEstatistica + pecas[peca][item.dataset.estatistica]
  })
}

//limitar valores das peçasde 0 a 9
function limitarValorMinimoPeca(peca) {
  let vlrPeca = parseInt(peca.value)
  let minimo = vlrPeca === 0 ? false : true
  return minimo
}

function limitarValorMaximoPeca(peca) {
  let vlrPeca = parseInt(peca.value)
  let maximo = vlrPeca === 9 ? false : true
  return maximo
}
//fim limitar valor das peças

/**Manipulando vários elementos */
btnsControle.forEach((element) => {
  element.addEventListener('click', (evento) => {
    let operacao = evento.target.dataset.operacao //botão de operações
    let controle = evento.target.parentNode //todo o componente de controle da peça (input e botões)
    let peca = evento.target.dataset.peca

    manipularDados(operacao, controle) //parenteNode é o controle da peça toda (btns e input)
    atualizarEstatistica(peca)
  })
})

Ufa enfim acabou!

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

solução!

Oi Antônio, tudo bem?

Caramba que incrível essa sua ideia do modal! Parabéns pela dedicação e muito obrigada por compartilhar com a gente essa maneira incrível de fazer!

Espero que tenha gostado do desafio!

Um abraço e bons estudos.

Obrigado Lorena!

Eu não queria mudar o layout que a equipe fez com tanto carinho!

Obrigado por sempre me responder!