I gradienti fanno parte dello spettro CSS da un po' di tempo ormai. Vediamo molti gradienti radiali e lineari in molti progetti, ma c'è un tipo di gradiente che sembra essere un po' solitario: il gradiente conico. Creeremo un quadrante usando questo tipo di gradiente.
Lavorare con gradienti conici
Quello che stiamo facendo consiste in un gradiente con transizioni di colore ruotate attorno a un punto centrale e può avere più valori di colore. Affinché questo orologio funzioni, utilizzeremo anche il valore dell'angolo di un gradiente conico che definisce la rotazione o il punto iniziale. L'angolo è definito utilizzando a from
valore.
background-image: conic-gradient(from 45deg, #6e7dab, #5762d5);
La cosa interessante di questo è che un angolo iniziale può avere un valore negativo nei CSS, che tornerà utile in seguito.
Un semplice ed elegante esempio di gradiente conico:
Costruire il nostro orologio di base
Iniziamo aggiungendo del codice HTML per l'orologio e le lancette:
Creiamo uno stile predefinito per il nostro orologio. Affinché funzioni correttamente, aggiorneremo le variabili CSS con JavaScript in seguito, quindi esaminiamo queste variabili all'interno del nostro .clock
selettore. Per un facile ritocco, aggiungiamo anche i colori delle mani.
.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));
}
Questo ci imposta con lo stile generale di cui abbiamo bisogno per l'orologio. Abbiamo impostato transform-origin
sulle lancette in modo che ruotino correttamente attorno al quadrante dell'orologio. Ci sono anche alcune proprietà personalizzate per impostare gli angoli delle lancette che aggiorneremo con JavaScript per ottenere i tempi giusti in modo che ogni lancetta corrisponda a secondi, minuti e ore di conseguenza.
Ecco cosa abbiamo finora:
Bene, passiamo all'aggiornamento di quelle proprietà personalizzate!
Aggiunta del JavaScript per il nostro orologio di base
Prima di tutto, prenderemo di mira il nostro orologio e creeremo una funzione:
const clock = document.getElementById("clock");
function setDate() {
// Code to set the current time and hand angles.
}
setDate();
All'interno della nostra funzione recupereremo l'ora corrente usando il comando Date()
function per calcolare l'angolo corretto delle lancette:
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;
Ecco come funziona questo calcolo:
- secondi: Prendiamo 60 secondi e lo moltiplichiamo per
6
, che sembra essere360
, il numero perfetto di angoli in un cerchio completo. - Minuti: Come i secondi, ma ora aggiungiamo l'angolo dei secondi e lo dividiamo per
60
per aumentare l'angolo solo un po' all'interno del minuto per un risultato più accurato. - Ore: Innanzitutto, calcoliamo il resto dell'ora e lo dividiamo per
12
. Quindi dividiamo quel resto per12
di nuovo per ottenere un valore decimale che possiamo moltiplicare per360
. Ad esempio, quando siamo alla 23a ora,23 / 12 =
remain
11
. Dividilo per 12 e otteniamo0.916
che poi viene moltiplicato per360
per un totale complessivo di330
. Qui, faremo la stessa cosa che abbiamo fatto con i minuti e aggiungeremo l'angolo dei minuti, diviso per12
, per un risultato più accurato.
Ora che abbiamo i nostri angoli, l'unica cosa che resta da fare è aggiornare le variabili del nostro orologio aggiungendo quanto segue alla fine della nostra funzione:
clock.style.setProperty("--second-hand-degrees", secondsAngle + "deg");
clock.style.setProperty("--minute-hand-degrees", minsAngle + "deg");
clock.style.setProperty("--hour-hand-degrees", hourAngle + "deg");
Ultimo, ma non meno importante, attiveremo la funzione con un intervallo di un secondo per ottenere un orologio funzionante:
const clock = document.getElementById("clock");
function setDate() {
// etc.
}
// Tick tick tick
setInterval(setDate, 1000);
setDate();
Guarda la demo funzionante del nostro orologio base:
Applicandolo a un gradiente conico
OK, quindi le lancette del nostro orologio funzionano. Quello che vogliamo veramente è mapparli su un gradiente conico che si aggiorna al variare del tempo. Potresti aver visto lo stesso effetto se hai un Apple Watch con il quadrante "Gradient" attivo:
Per fare ciò, iniziamo aggiornando il ns .clock
elemento con un gradiente conico e due proprietà personalizzate che controllano gli angoli iniziale e finale:
.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)
);
}
Puoi giocarci un po' per modellarlo come piace a te. Ho aggiunto alcuni colori extra nel gradiente a mio piacimento, ma finché hai un punto di partenza e un punto finale, sei a posto.
Successivamente, aggiorneremo il nostro setDate()
funzione in modo che aggiorni le variabili per i nostri punti di inizio e fine sul gradiente conico. Il punto di partenza sarà la nostra lancetta dei secondi, che è facile da trovare perché sarà la stessa dell'angolo dei nostri minuti. Per fare questo fine alla lancetta delle ore, dovremmo rendere il nostro punto finale uguale a hourAngle
variabile nello script, ma sottrarre il nostro punto di partenza da esso.
let startPosition = minsAngle;
let endPosition = hourAngle - minsAngle;
Ora possiamo aggiornare nuovamente le nostre variabili con JavaScript:
clock.style.setProperty("--start", startPosition + "deg");
clock.style.setProperty("--end", endPosition + "deg");
Sembra che potremmo aver finito a questo punto, ma c'è un problema! Questo calcolo funziona bene fintanto che la lancetta dei minuti ha un angolo più piccolo della lancetta delle ore. Il nostro gradiente conico diventerà disordinato nel momento in cui la lancetta dei minuti lo supererà. Per risolvere questo problema, utilizzeremo un valore negativo come punto di partenza. Fortunatamente, è facile individuare quando ciò accade. Prima di aggiornare le nostre variabili aggiungeremo quanto segue:
if (minsAngle > hourAngle) {
startPosition = minsAngle - 360;
endPosition = hourAngle - startPosition;
}
Sottraendo 360
dal nostro angolo dei minuti, siamo in grado di impostare un valore negativo per il nostro startposition
variabile. A causa di questo punto di partenza negativo, la nostra posizione finale dovrebbe essere aggiornata dell'angolo orario, sottratto dalla posizione iniziale.
Ecco fatto, ora le lancette delle ore e dei minuti sono impostate su angoli sfumati:
Questo è tutto! Ma non lasciare che questo ti impedisca di andare ancora oltre. Crea i tuoi stili e condividili con me nei commenti in modo che io possa verificarli. Ecco una piccola ispirazione per iniziare: