sábado, 5 de dezembro de 2015

Criando um Relógio Analógico com CSS3 e JQuery

Olá galera, hoje vou ensinar a vocês como criar um relógio analógico que pode ser colocado em um site ou página da web. Para isso vamos precisar usar as bibliotecas JQuery e MomentJS.

Primeiramente, você precisa se certificar que possui as duas bibliotecas que vamos utilizar para fazer o relógio. Adicione o código abaixo para importar essas duas bibliotecas:
<script src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<script src="http://momentjs.com/downloads/moment.js" type="application/javascript"></script>
<script src="http://momentjs.com/downloads/moment-timezone-with-data.js" type="application/javascript"></script>
Agora vamos adicionar o html necessário para gerar o relógio:
<div class="hero-circle">
    <div class="hero-face">
        <div id="hour" class="hero-hour"></div>
        <div id="minute" class="hero-minute"></div>
        <div id="second" class="hero-second"></div>
    </div>
</div>
Como são apenas divs vazias, ainda não vai aparecer nada na tela. Vamos agora adicionar CSS necessário para que elas se transformem realmente em um relógio. Primeiro vamos criar o círculo do relógio:
.hero-circle {
    width: 180px;
    height: 180px;
    position: relative;
    border: 8px solid #fff;
    border-radius: 50%;
    box-shadow: 0 1px 8px rgba(34,34,34,0.3),inset 0 1px 8px rgba(34,34,34,0.3);
}
Nesse CSS, estamos definindo que o relógio terá um tamanho de 180px por 180px, possui uma posição relativa, pois os ponteiros serão do tipo absolute e seu posicionamento deve ser definido pelas bordas do relógio. As outras propriedades servem para transformar a div em um círculo e adicionar bordas e sombreamento.

Agora vamos adicionar um CSS pra cada ponteiro separadamente, pois cada um possui propriedades diferentes, como tamanho e largura. Primeiro vamos fazer o das horas:
.hero-hour {
    width: 0;
    height: 0;
    position: absolute;
    top: 50%;
    left: 50%;
    margin: -4px 0 -4px -25%;
    padding: 4px 0 4px 25%;
    background: #fff;
    transform-origin: 100% 50%;
    border-radius: 4px 0 0 4px;
}
Com este CSS estamos definindo o tamanho e largura do ponteiro, assim como sua posição no centro das bordas do relógio e definindo as bordas arredondadas na ponta. O CSS para os ponteiros de minuto e segundos são semelhantes, mudando apenas as dimensões deles. Adicione o código abaixo para terminar a estilização:
.hero-minute {
    width: 0;
    height: 0;
    position: absolute;
    top: 50%;
    left: 50%;
    margin: -40% -3px 0;
    padding: 40% 3px 0;
    background: #fff;
    transform-origin: 50% 100%;
    border-radius: 3px 3px 0 0;
}

.hero-second {
    width: 0;
    height: 0;
    position: absolute;
    top: 50%;
    left: 50%;
    margin: -40% -1px 0 0;
    padding: 40% 1px 0;
    background: #fff;
    transform-origin: 50% 100%;
}
Agora seu relógio já deve estar formado, apesar de estar parado. Se você não o esta enxergando, pode mudar a cor de fundo dos ponteiros e do círculo pela propriedade background ou pode então adicionar o relógio dentro de uma div e mudar a cor de fundo dessa div.

Agora que o relógio esta pronto, vamos adicionar movimento a ele utilizando JQuery e a biblioteca MomentJS com TimeZone, pra que as horas sejam mostrada no horário de São Paulo. O script que deve ser adicionado esta mostrado abaixo:
function updateClock(){
    var now = moment();
    now.tz("America/Sao_Paulo");
    var second = now.seconds() * 6;
    var minute = now.minutes() * 6 + second / 60;
    var hour = ((now.hours() % 12) / 12) * 360 + 90 + minute / 12;
    $('#hour').css("transform", "rotate(" + hour + "deg)");
    $('#minute').css("transform", "rotate(" + minute + "deg)");
    $('#second').css("transform", "rotate(" + second + "deg)");
}

function timedUpdate () {
    updateClock();
    setTimeout(timedUpdate, 1000);
}

timedUpdate();
A função updateClock é a responsável por modificar a posição dos ponteiros de acordo com a hora atual do computador do usuário. O que ela faz é pegar as horas pela função now = moment() e depois pegar separadamente os segundos, minutos e horas. Como existe uma relação entre tempo e graus, as outras três instruções transformam cada unidade de tempo em seu equivalente em graus.

Através desses graus, pedimos através de JQuery que cada ponteiro deve ser rotacionado nessa medida em graus em torno do eixo central do círculo da borda do relógio. Como a função timeUpdate() possui um setTimeout que a chama de um em um segundo, o relógio é atualizado no mesmo tempo, mostrando a hora corretamente e no tempo certo.

Aqui esta a versão final do relógio analógico: