Att skapa en realtidsklocka med en konisk gradientyta PlatoBlockchain Data Intelligence. Vertikal sökning. Ai.

Att göra en realtidsklocka med en konisk lutning

Gradienter har varit en del av CSS-spektrumet ganska länge nu. Vi ser många radiella och linjära gradienter i många projekt, men det finns en typ av gradient som verkar vara lite ensam: den koniska gradienten. Vi kommer att göra en urtavla med den här typen av gradient.

Arbeta med koniska gradienter

Det vi gör består av en gradient med färgövergångar roterade runt en mittpunkt och kan ha flera färgvärden. För att den här klockan ska fungera kommer vi också att använda vinkelvärdet för en konisk gradient som definierar rotationen eller startpunkten. Vinkeln definieras med hjälp av a from värde.

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

Det som är intressant med detta är att en startvinkel kan ha ett negativt värde i CSS, vilket kommer väl till pass senare.

Ett enkelt elegant exempel på en konisk gradient:

Bygger vår grundläggande klocka

Låt oss börja med att lägga till lite HTML för klockan och visarna:

Låt oss skapa lite standardstyling för vår klocka. För att detta ska fungera korrekt kommer vi att uppdatera CSS-variabler med JavaScript senare, så låt oss omfånga dessa variabler i vår .clock väljare. För enkel justering, låt oss lägga till färgerna på händerna också.

.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));
}

Detta ger oss den allmänna stilen vi behöver för klockan. Vi har satt transform-origin på visarna så att de roterar ordentligt runt klockan. Det finns också några anpassade egenskaper där för att ställa in vinklar på visarna som vi kommer att uppdatera med JavaScript för att få rätt timing så att varje hand mappas till sekunder, minuter och timmar därefter.

Här är vad vi har hittills:

Okej, låt oss gå vidare till att uppdatera dessa anpassade egenskaper!

Lägger till JavaScript för vår grundläggande klocka

Först och främst ska vi rikta vår klocka och skapa en funktion:

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

Inuti vår funktion kommer vi att hämta den aktuella tiden med hjälp av Date() fungera för att beräkna rätt vinkel på händerna:

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;

Så här fungerar den här beräkningen:

  • sekunder: Vi tar 60 sekunder och multiplicerar det med 6, som råkar vara 360, det perfekta antalet vinklar i en hel cirkel.
  • Minuter: Samma som sekunder, men nu lägger vi till sekundvinkeln och dividerar den med 60 för att öka vinkeln bara lite inom en minut för ett mer exakt resultat.
  • Öppettider: Först beräknar vi resten av timmen och dividerar den med 12. Sedan delar vi resten med 12 igen för att få ett decimalvärde kan vi multiplicera med 360. Till exempel, när vi är vid 23:e timmen, 23 / 12 = remain 11. Dividera detta med 12 så får vi 0.916 som sedan multipliceras med 360 för totalt 330. Här kommer vi att göra samma sak som vi gjorde med minuterna och lägga till minutvinkeln, dividerat med 12, för ett mer exakt resultat.

Nu när vi har våra vinklar är det enda kvar att göra att uppdatera variablerna för vår klocka genom att lägga till följande i slutet av vår funktion:

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

Sist men inte minst kommer vi att trigga funktionen med ett intervall på en sekund för att få en fungerande klocka:

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

Se arbetsdemon av vår grundläggande klocka:

Applicera detta på en konisk gradient

Okej, så visar visarna på vår klocka fungerar. Vad vi verkligen vill är att mappa dem till en konisk gradient som uppdateras när tiden ändras. Du kanske har sett samma effekt om du har en Apple Watch med "Gradient"-ansiktet aktivt:

Credit: Macworld

För att göra detta, låt oss börja med att uppdatera vår .clock element med en konisk gradient och två anpassade egenskaper som styr start- och slutvinklarna:

.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)
  );
}

Du kan leka lite med den här för att styla den precis som du vill ha den. Jag lade till några extra färger i gradienten efter min smak, men så länge du har en startpunkt och en slutpunkt är du bra att gå.

Härnäst kommer vi att uppdatera vår setDate() funktion så att den uppdaterar variablerna för våra start- och slutpunkter på den koniska gradienten. Utgångspunkten kommer att vara vår sekundvisare, som är lätt att hitta eftersom den kommer att vara samma som vinkeln på våra minuter. För att detta ska sluta på timmarna bör vi göra vår slutpunkt till samma som hourAngle variabel i skriptet, men subtrahera vår utgångspunkt från den.

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

Nu kan vi uppdatera våra variabler med JavaScript igen:

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

Det ser ut som att vi skulle kunna vara klara vid det här laget, men det finns en hake! Denna beräkning fungerar bra så länge minutvisaren har en mindre vinkel än timvisaren. Vår koniska gradient kommer att bli rörig i det ögonblick då minutvisaren har flyttat förbi den. För att fixa detta kommer vi att använda ett negativt värde som utgångspunkt. Lyckligtvis är det lätt att upptäcka när detta händer. Innan vi uppdaterar våra variabler lägger vi till följande:

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

Genom att subtrahera 360 från vår minutvinkel kan vi ställa in ett negativt värde för vår startposition variabel. På grund av denna negativa startpunkt bör vår slutposition uppdateras med timvinkeln, subtraherad med startpositionen.

Där går vi — nu är tim- och minutvisare inställda på gradientvinklar:

Det är allt! Men låt inte det hindra dig från att ta det här ännu längre. Skapa dina egna stilar och dela dem med mig i kommentarerna så att jag kan kolla in dem.. Här är lite inspiration för att komma igång:

Tidsstämpel:

Mer från CSS-tricks