Clock face Guide
chevron down
 

Clock Face Guide

Overview

The Clock API allows developers to easily update their app's display based on the current date and time.

The tick event contains a JavaScript Date object with the current date and time. Although setInterval() could be used in a similar fashion, the Clock API automatically handles tick events at the correct precision and timing.

import clock from "clock";

clock.granularity = "minutes"; // seconds, minutes, or hours

clock.addEventListener("tick", (evt) => {
  // tick every minute
});

Another advantage of using the Clock API is that tick events do not occur when the display is off, so you're automatically reducing your impact upon battery life when using it.

Digital Clock

To create a simple digital clock, we need a <text> component, and use the tick event to update the display.

<svg viewport-fill="fb-cyan">
  <text id="clock-label" x="50%" y="50%+15"
      fill="black" font-size="32" font-family="System-Regular"
      text-anchor="middle" text-length="20">00:00:00</text>
</svg>

Then use JavaScript to update the <text> element every time the clock ticks.

import clock from "clock";
import document from "document";

clock.granularity = "seconds"; // seconds, minutes, hours

const clockLabel = document.getElementById("clock-label");

clock.addEventListener("tick", (evt) => {
  clockLabel.text = evt.date.toTimeString().slice(0, -4);
});

Analog Clock

The Clock API can also be used to easily create an analog clock. We take the current time from JavaScript, and use that to calculate the angles required to rotate hands.

First, we define <rect> elements to use for the hour, minute and seconds, and position them from the center of the screen, pointing at the 12 o'clock position. We define a <g> elements for each hand, so they can be rotated independently of the other elements.

<svg viewport-fill="fb-cyan">
  <g id="mins" pointer-events="visible" transform="translate(50%,50%)">
    <rect x="$-4" y="-110" width="8" height="110" fill="#e0e0e0" />
  </g>
  <g id="hours" pointer-events="visible" transform="translate(50%,50%)">
    <rect x="$-6" y="-75" width="12" height="75" fill="#ffffff" />
  </g>
  <g id="secs" pointer-events="visible" transform="translate(50%,50%)">
    <rect x="$-2" y="-120" width="4" height="120" fill="#ff0000" />
  </g>
  <circle cx="50%" cy="50%" r="10" fill="#444444" />
</svg>
import clock from "clock";
import document from "document";

// Tick every second
clock.granularity = "seconds";

let hourHand = document.getElementById("hours");
let minHand = document.getElementById("mins");
let secHand = document.getElementById("secs");

// Returns an angle (0-360) for the current hour in the day, including minutes
function hoursToAngle(hours, minutes) {
  let hourAngle = (360 / 12) * hours;
  let minAngle = (360 / 12 / 60) * minutes;
  return hourAngle + minAngle;
}

// Returns an angle (0-360) for minutes
function minutesToAngle(minutes) {
  return (360 / 60) * minutes;
}

// Returns an angle (0-360) for seconds
function secondsToAngle(seconds) {
  return (360 / 60) * seconds;
}

// Rotate the hands every tick
function updateClock() {
  let today = new Date();
  let hours = today.getHours() % 12;
  let mins = today.getMinutes();
  let secs = today.getSeconds();

  hourHand.groupTransform.rotate.angle = hoursToAngle(hours, mins);
  minHand.groupTransform.rotate.angle = minutesToAngle(mins);
  secHand.groupTransform.rotate.angle = secondsToAngle(secs);
}

// Update the clock every tick event
clock.addEventListener("tick", updateClock);