Fazendo um relógio em tempo real com uma face cônica gradiente PlatoBlockchain Data Intelligence. Pesquisa vertical. Ai.

Fazendo um relógio em tempo real com um gradiente cônico

Os gradientes fazem parte do espectro do CSS há algum tempo. Vemos muitos gradientes radiais e lineares em muitos projetos, mas há um tipo de gradiente que parece um pouco solitário: o gradiente cônico. Vamos fazer um mostrador de relógio usando esse tipo de gradiente.

Trabalhando com gradientes cônicos

O que estamos fazendo consiste em um gradiente com transições de cores giradas em torno de um ponto central e pode ter vários valores de cores. Para que este relógio funcione, também usaremos o valor do ângulo de um gradiente cônico que define a rotação ou ponto de partida. O ângulo é definido usando um from valor.

background-image: conic-gradient(from 45deg, #6e7dab, #5762d5);

O interessante disso é que um ângulo inicial pode ter um valor negativo em CSS, o que será útil mais tarde.

Um exemplo simples e elegante de um gradiente cônico:

Construindo nosso relógio básico

Vamos começar adicionando um pouco de HTML para o relógio e os ponteiros:

Vamos criar um estilo padrão para o nosso relógio. Para que isso funcione corretamente, atualizaremos as variáveis ​​CSS com JavaScript mais tarde, então vamos definir o escopo dessas variáveis ​​dentro do nosso .clock seletor. Para ajustes fáceis, vamos adicionar as cores das mãos também.

.clock {
  /* general clock vars */
  --hour-hand-color: #000;
  --hour-hand-degrees: 0deg;
  --minute-hand-color: #000;
  --minute-hand-degrees: 0deg;
  --second-hand-color: hotpink;
  --second-hand-degrees: 0deg;

  position: relative;
  min-width: 320px;
  width: 25vw;
  height: 25vw;
  min-height: 320px;
  border-radius: 50%;
  margin: 0 auto;
  border: 7px solid #000;
}

/* clock hands */
.hand {
  position: absolute;
  left: 50%;
  bottom: 50%;
  height: 45%;
  width: 4px;
  margin-left: -2px;
  background: var(--second-hand-color);
  border-radius: 6px;
  transform-origin: bottom center;
  transition-timing-function: cubic-bezier(0.1, 2.7, 0.58, 1);
}
.second-hand {
  transform: rotate(var(--second-hand-degrees));
}
.hour-hand {
  height: 35%;
  border-radius: 40px;
  background-color: var(--hour-hand-color);
  transform: rotate(var(--hour-hand-degrees));
}
.minute-hand {
  height: 50%;
  background: var(--minute-hand-color);
  transform: rotate(var(--minute-hand-degrees));
}

Isso nos define com o estilo geral que precisamos para o relógio. Nós configuramos transform-origin nos ponteiros para que eles girem corretamente ao redor do mostrador do relógio. Há também algumas propriedades personalizadas para definir ângulos nos ponteiros que atualizaremos com JavaScript para obter o tempo certo para que cada ponteiro seja mapeado para segundos, minutos e horas de acordo.

Aqui está o que temos até agora:

Tudo bem, vamos continuar atualizando essas propriedades personalizadas!

Adicionando o JavaScript para nosso relógio básico

Primeiro, vamos direcionar nosso relógio e criar uma função:

const clock = document.getElementById("clock");
function setDate() {
  // Code to set the current time and hand angles.
}
setDate();

Dentro de nossa função vamos buscar a hora atual usando o Date() função para calcular o ângulo correto das mãos:

const now = new Date();
const secondsAngle = now.getSeconds() * 6; 
const minsAngle = now.getMinutes() * 6 + secondsAngle / 60;
const hourAngle = ((now.getHours() % 12) / 12) * 360 + minsAngle / 12;

Veja como funciona esse cálculo:

  • Segundos: Pegamos 60 segundos e multiplicamos por 6, que passa a ser 360, o número perfeito de ângulos em um círculo completo.
  • Minutos: O mesmo que segundos, mas agora adicionamos o ângulo dos segundos e dividimos por 60 para aumentar o ângulo um pouco dentro de um minuto para um resultado mais preciso.
  • Horas: Primeiro, calculamos o resto da hora e dividimos por 12. Então dividimos esse resto por 12 novamente para obter um valor decimal, podemos multiplicar por 360. Por exemplo, quando estamos na 23ª hora, 23 / 12 = remain 11. Divida isso por 12 e teremos 0.916 que então é multiplicado por 360 para um total de 330. Aqui, faremos a mesma coisa que fizemos com os minutos e somaremos o ângulo dos minutos, dividido por 12, para um resultado mais preciso.

Agora que temos nossos ângulos, a única coisa que resta a fazer é atualizar as variáveis ​​do nosso relógio adicionando o seguinte no final da nossa função:

clock.style.setProperty("--second-hand-degrees", secondsAngle + "deg");
clock.style.setProperty("--minute-hand-degrees", minsAngle + "deg");
clock.style.setProperty("--hour-hand-degrees", hourAngle + "deg");

Por último, mas não menos importante, acionaremos a função com um intervalo de um segundo para obter um relógio funcionando:

const clock = document.getElementById("clock");
function setDate() {
  // etc.
}
// Tick tick tick
setInterval(setDate, 1000);
setDate();

Veja a demonstração de trabalho do nosso relógio básico:

Aplicando isso a um gradiente cônico

OK, então os ponteiros do nosso relógio estão funcionando. O que realmente queremos é mapeá-los para um gradiente cônico que se atualiza conforme o tempo muda. Você pode ter visto o mesmo efeito se tiver um Apple Watch com a face “Gradiente” ativa:

Crédito: Macworld

Para fazer isso, vamos começar atualizando nosso .clock elemento com um gradiente cônico e duas propriedades personalizadas que controlam os ângulos inicial e final:

.clock {
  /* same as before */

  /* conic gradient vars */
  --start: 0deg;
  --end: 0deg;

  /* same as before */

  background: 
    conic-gradient(
      from var(--start),
      rgb(255 255 255) 2deg,
      rgb(0 0 0 / 0.5) var(--end),
      rgb(255 255 255) 2deg,
      rgb(0 0 0 / 0.7)
  );
}

Você pode brincar um pouco com isso para estilizá-lo do jeito que você gosta. Eu adicionei algumas cores extras no gradiente ao meu gosto, mas contanto que você tenha um ponto inicial e um ponto final, você está pronto para ir.

A seguir, atualizaremos nosso setDate() função para que atualize as variáveis ​​para nossos pontos inicial e final no gradiente cônico. O ponto de partida será o nosso ponteiro dos segundos, que é fácil de encontrar porque será o mesmo que o ângulo dos nossos minutos. Para fazer isso no ponteiro das horas, devemos fazer o nosso ponto final igual ao hourAngle variável no script, mas subtraia nosso ponto de partida dela.

let startPosition = minsAngle;
let endPosition = hourAngle - minsAngle;

Agora podemos atualizar nossas variáveis ​​com JavaScript novamente:

clock.style.setProperty("--start", startPosition + "deg");
clock.style.setProperty("--end", endPosition + "deg");

Parece que poderíamos terminar neste ponto, mas há um problema! Este cálculo funciona bem desde que o ponteiro dos minutos tenha um ângulo menor que o ponteiro das horas. Nosso gradiente cônico ficará confuso no momento em que o ponteiro dos minutos passar por ele. Para corrigir isso, usaremos um valor negativo como ponto de partida. Felizmente, é fácil identificar quando isso acontece. Antes de atualizar nossas variáveis, adicionaremos o seguinte:

if (minsAngle > hourAngle) {
  startPosition = minsAngle - 360;
  endPosition = hourAngle - startPosition;
}

Ao subtrair 360 do ângulo dos minutos, podemos definir um valor negativo para o nosso startposition variável. Por causa desse ponto inicial negativo, nossa posição final deve ser atualizada pelo ângulo horário, subtraído da posição inicial.

Lá vamos nós - agora os ponteiros das horas e minutos estão definidos para ângulos de gradiente:

É isso! Mas não deixe que isso o impeça de levar isso ainda mais longe. Crie seus próprios estilos e compartilhe-os comigo nos comentários para que eu possa vê-los. Aqui está uma pequena inspiração para você seguir em frente:

Carimbo de hora:

Mais de Truques CSS