# clock

This clock is built entirely with the gySVG library.

edit in codepen.io (opens new window)

We will now explain step by step how to create a dynamic SVG of this type.

# Import gySVG

The first step, if we haven't already done so, is to import the gySVG library. In our case, we've chosen to include the code within a script type=module and we'll use the import expression.

see: load gySVG

# Create the SVG

To create the graph we are going to use gySVG() and we are going to configure the viewBox.

see: SVG Element, .viewBox, .attachTo

# Outside circle

We create the outer circle of the image with .add('circle') and configure it:

see: Circle

# Hour and minute marks

To create the hour and minute marks we have to use add('line') and to position each line inside the circle every N degrees we are going to use some relatively complex mathematical operations:

see: Line

# Text label for every hour

We modified the previous code a bit to add with add('text') the labels for each of the clock hours. Again, to properly locate each of the texts we have to use a couple of trigonometric functions.

see: Text element

# Clock hands

Now we create the three clock hands by add('polygon'), one for the seconds, one for the minutes, and one for the hours.

see: Polygon

# Update time automatically

By adding a little more code we can rotate the clock hands to show the current time. To avoid complicating the example we have used a simple setInterval() where .transform('rotate()) is called for each of the hands.

see: Transform

# The complete code

If we put all these steps together this is the example's code:

import gySVG from 'https://cdn.graphery.online/0.1.5/svg/module/index.js';

const svg = gySVG().viewBox('0 0 250 250');

svg.add('circle')
  .cx(125).cy(125).r(124)
  .stroke('#000').stroke_width(2).fill('none');

let h = 1;
for (let n = 6;  n <= 360; n += 6) {
  const radians = ((n - 90) * Math.PI) / 180.0;
  let radio;
  if (n % 30 === 0) {
    radio = 110;
    svg.add('text')
      .innerHTML(h++)
      .x(125 + 95 * Math.cos(radians))
      .y(132 + 95 * Math.sin(radians))
      .style.fontSize(20)
      .style.fontFamily('sans-serif')
      .text_anchor('middle');
  } else {
    radio = 115;
  }
  svg.add('line')
    .x1(125 + 120 * Math.cos(radians))
    .y1(125 + 120 * Math.sin(radians))
    .x2(125 + radio * Math.cos(radians))
    .y2(125 + radio * Math.sin(radians))
    .stroke('#000').stroke_width(n % 30 === 0 ? 2 : 1);
}

const g       = svg.add('g').fill('#000').stroke('#555').stroke_width(1);
const seconds = g.add('polygon').points([125, 20], [129, 125], [125, 145], [124, 125]);
const minutes = g.add('polygon').points([125, 30], [130, 125], [125, 150], [120, 125]);
const hours   = g.add('polygon').points([125, 60], [132, 125], [125, 160], [118, 125]);

svg.attachTo('#example-clock');

setInterval((function update() {
  const d = new Date();
  seconds.transform(`rotate(${ d.getSeconds() * 6 }, 125, 125)`);
  minutes.transform(`rotate(${ d.getMinutes() * 6 }, 125, 125)`);
  hours.transform(`rotate(${(d.getHours() % 12 * 30) +(d.getMinutes() * 0.5) }, 125, 125)`);
  return update;
})(), 1000);