Quem não lembra do lendário programa do Silvio Santos Pião da Casa Própria? Neste post vamos trazer esta lenda de volta a vida, desta vez encarnado em puro código HTML5, sem imagens ou plugins. Se seu navegador for o Chrome, Safari ou Firefox atualizados, você poderá ver abaixo como nosso experimento irá ficar ao final deste post.
Todo o código deste experimento está disponível no GitHub e um preview completo pode ser visto aqui.
A brincadeira é muito fácil
Vamos começar com o código HTML. Apenas uma div
contendo 6 outras div
, uma para cada face do pião, a div
wrapper, que servirá de container para o pião, e mais uma última para a moldura do pião.
<div id="wrapper">
<div id="piao">
<!-- todas as faces do pião -->
<div class="numero um">1</div>
<div class="numero dois">2</div>
<div class="numero tres">3</div>
<div class="numero quatro">4</div>
<div class="numero cinco">5</div>
<div class="numero seis">6</div>
</div>
<div id="moldura"> </div>
</div>
Agora vamos dar um pouco de estilo ao pião e à moldura.
#wrapper {
width: 400px;
height: 400px;
position: absolute;
left: 50%;
top: 50%;
margin-left: -200px;
margin-top: -200px;
}
#piao {
position: relative;
top: 40px; /* centraliza o pião */
margin: 0 auto; /* centraliza o pião */
height: 330px;
width: 200px;
}
#piao .numero {
position: absolute;
height: 100%;
width: 200px;
border: 6px solid white;
-webkit-box-sizing: border-box;
text-align: center;
line-height: 320px;
font-family: Impact, sans-serif;
font-size: 240px;
color: white;
background-color: rgb(0, 0, 0);
}
#moldura {
height: 400px;
width: 400px;
border: 50px solid rgb(200, 0, 0);
border-radius: 250px;
position: absolute;
top: -45px;
left: -50px;
/*
1ª shadow: simula 3D no elemento, na parte interna
2ª shadow: shadow interna para simular profundidade
3ª shadow: simula 3D no elemento, na parte externa
4ª shadow: shadow externa para simular profundidade
*/
box-shadow:
inset -1px -2px 0px 3px rgb(150, 0, 0),
inset -1px -2px 10px 10px rgba(0, 0, 0, 0.5),
-2px -2px 0px 3px rgb(150, 0, 0),
-4px -4px 10px 10px rgba(0, 0, 0, 0.5);
}
Agora já podemos ver algo sem graça no browser com o código acima: um número 6 dentro de um círculo vermelho com um efeito 3D simulado.
Posição no plano 3D
Vamos agora posicionar o pião no plano 3D. Mas antes uma breve explicação sobre o plano 3D em CSS.
Temos 3 eixos de coordenadas para posicionarmos os elementos relativos a eles. O eixo X é o eixo horizontal (esquerda-direita) e tem sua origem no ponto mais a esquerda. O eixo Y é o eixo vertical (cima-baixo) e, diferente de um plano cartesiano comum, tem seu início na parte mais acima do navegador. Portanto, o ponto do seu navegador mais acima e a esquerda é o ponto de coordenadas X = 0 e Y = 0.
Mas para objetos 3D nós precisamos de mais um eixo, o eixo Z, que vai nos dar a sensação de profundidade. Este eixo se inicia no monitor e cresce no sentido monitor ↝ você. Então, quanto mais “distante” do monitor o objeto aparentar estar, maior o valor de Z.
Agora entendendo um pouco sobre o plano 3D, vamos organizar os elementos a fim de formar o pião.
#piao > .numero.um {
/*
a rotação deste elemento é 0, o que já é o valor padrão
então não há necessidade de redeclarar sua rotação
*/
}
#piao > .numero.dois {
-webkit-transform: rotateY(60deg);
}
#piao > .numero.tres {
-webkit-transform: rotateY(120deg);
}
#piao > .numero.quatro {
-webkit-transform: rotateY(180deg);
}
#piao > .numero.cinco {
-webkit-transform: rotateY(240deg);
}
#piao > .numero.seis {
-webkit-transform: rotateY(300deg);
}
No trecho de CSS acima, nós giramos as faces em relação ao eixo Y. Precisamos girar todas as faces a fim de fecharmos uma volta. Como uma volta possui 360 graus e o pião possui 6 faces, então iremos rotacionar cada face em 60 graus mais a rotação da face anterior, ou seja, o primeiro elemento irá ser rotacionado em 60 graus, o segundo em 120 graus, o terceiro em 180 graus, e assim por diante até o último elemento.
Porém se rotacionarmos apenas no eixo Y os elementos, eles ficarão todos um por cima dos outros, apenas inclinados de forma diferente. Estarão todos no centro do que será nosso pião. Precisamos agora afastar as faces umas das outras. E para isso iremos usar a propriedade translateZ
.
#piao {
...
-webkit-transform-style: preserve-3d;
}
#piao > .numero.um {
-webkit-transform: translateZ(170px);
}
#piao > .numero.dois {
-webkit-transform: rotateY(60deg) translateZ(170px);
}
#piao > .numero.tres {
-webkit-transform: rotateY(120deg) translateZ(170px);
}
#piao > .numero.quatro {
-webkit-transform: rotateY(180deg) translateZ(170px);
}
#piao > .numero.cinco {
-webkit-transform: rotateY(240deg) translateZ(170px);
}
#piao > .numero.seis {
-webkit-transform: rotateY(300deg) translateZ(170px);
}
Com o transform-style: preserve-3d
estamos dizendo que os filhos diretos do elemento pião irão compartilhar o mesmo espaço 3D que o pai. Caso contrário os elementos seriam renderizados de forma plana no elemento pai.
Depois, com a regra translateZ
, estamos afastanto todos os elementos do seu ponto inicial no eixo Z. Com o rotateY
giramos todas as faces e com o translateZ
é como se estivéssemos pedindo para que todas as faces dessem um passo de 170px à frente. Como giramos todas para um lado diferente, elas irão “caminhar” para um sentido diferente.
Com isso temos o nosso pião 3D, mas para deixar tudo mais interessante, vamos usar animation
para fazer a rotação do pião.
Animação em ritmo de festa
O efeito que queremos ver é o do pião rodando em relação ao seu eixo Y, o mesmo eixo em que rotacionamos as faces do pião. Para isso iremos criar uma animação com o estado inicial no ponto 0 graus do eixo Y e estado final no 360 graus, ou seja, uma volta completa.
/*
animação para o pião rodar
uma animação básica ao redor do eixo Y
*/
@-webkit-keyframes rodando {
from { -webkit-transform: rotateY(0); }
to { -webkit-transform: rotateY(-360deg); }
}
No trecho acima definimos nossa animação e a chamamos de rodando (em homenagem). Agora é só a usarmos no elemento que desejarmos.
#piao {
...
-webkit-animation: rodando 4s infinite linear;
}
Aqui dizemos que queremos animar o elemento pião, utilizando a animação “rodando”, demorando 4 segundos para ir de seu estado inicial ao estado final, essa animação não irá parar (infinite) e a sua transição entre estados será linear.
Agora se checarmos no navegador, iremos finalmente ter nosso pião da casa própria em HTML5. E rodandooo.
One more thing…
O Pião da Casa Própria não seria o mesmo sem a clássica trilha sonnora. Então vamos adicioná-la ao experimento. Iremos usar a nova tag audio
para reproduzir a música sem a nececissade do Flash. Basta declarar a tag audio
e dentro dela as tags source
com os caminhos para o mesmo arquivo salvo em diferentes codecs.
<!-- trilha do pião da casa própria. máá ô-ê -->
<audio preload="auto" loop="true">
<source src="piao-da-casa-propria-soundtrack.mp3" />
<source src="piao-da-casa-propria-soundtrack.m4a" />
<source src="piao-da-casa-propria-soundtrack.ogg" />
</audio>
O navegador irá tentar de cima para baixo executar os formatos, e quando achar um que possa reproduzir, irá carregar e não irá mais procurar por outros source
. O uso desta tag é necessário pois cada navegador dá suporte a um diferente conjunto de codecs.
Caso queiram escutar a trilha sonora agora e ver o pião rodando é só apertar o botão play no lado direito superior dentro do experimento, no início do post. Utilizei a API JavaScript para controlar o comportamento da tag audio
, mas para não perdemos o foco, essa API fica para um próximo post.