Beautiful Object Oriented Clock...
Tags: html, javascript, webdev, objects
Published: 2021-07-26 17:09:53

Inspired by a nice post [Simple Analog Clock Using Html, CSS & Javascript](https://dev.to/code_mystery/simple-analog-clock-using-html-css-javascript-2c6a), that shows how to build an analog clock the *"traditional"* way, I was curious to see, how much coding it would need with [DML](https://github.com/efpage/DML), the Document Makeup Library.

The original HTML-setup is very nice, but a bit lengthy. And it lacks some **portability**. So, here I show, how to set up a class with DML that gives you the same functionality. This can be used like any standard HTML element in DML or it can be provided as a WebComponent with minimal effort.

This is myclock.js:
```javascript
// just a class wrapper for convenience
function myClock(size = 300, attrib) { return new _myClock(size, attrib) }

// the class
class _myClock  {
  constructor(size, attrib) {
    this.size = size
    const cx = size/2, cy = size/2;  // Radius
    const _clockstyle = "width: " + (size) + "px;  height: " + (size) + "px;"
      + "border: 7px solid #282828; background: #585858;"
      + "border-radius: 50%; margin: 50px;"
      + "box-shadow: -4px -4px 10px rgba(67,67,67,0.5), inset 4px 4px 10px rgba(0,0,0,0.5),"
      + "inset -4px -4px 10px rgba(67,67,67,0.5), 4px 4px 10px rgba(0,0,0,0.3);"

    this.base = sidiv("", _clockstyle+attrib)
    let c = this.canvas = canvas2D({ width: px(2 * cx), height: px(2 * cy) })
    
    c.ctx.lineCap = "round"
    unselectBase()

    // Paint anything radial
    function tick(color, width, angle, length, innerlength = 0) {
      function ls(length) { return length * Math.sin(angle / 180.0 * Math.PI) }
      function lc(length) { return -length * Math.cos(angle / 180.0 * Math.PI) }
      c.setLineType(width, color)
      c.line(cx + ls(innerlength), cy + lc(innerlength), cx + ls(length), cy + lc(length))
    }

    // Draw clock
    function drawClock() {
      c.clear()
      // Draw ticks
      for (let i = 0; i < 360; i += 30)
        if ((i % 90) == 0) tick("#1df52f", 5, i, size*0.45, size*0.40)
        else tick("#bdbdcb", 3, i,  size*0.45, size*0.43)

      // draw hands
      let t = new Date();  // get time
      tick("#61afff", 5, t.getHours() * 30, size*0.25)  // hour
      tick("#71afff", 2, t.getMinutes() * 6, size*0.35)  // min
      tick("#ee791a", 2, t.getSeconds() * 6, size*0.42)  // s

      // drwa center
      c.setFillStyle("#4d4b63")
      c.circle(cx, cy, 10, { fill: true })
    }
    drawClock()
    setInterval(drawClock, 1000)
  }
}
```

This is the complete webpage to create a number of different sized clocks:
```html
<!DOCTYPE html>
<html lang="de">

<head>
  <meta charset="utf-8">
  <title>title</title>
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <script src="https://efpage.de/DML/DML_homepage/lib/DML-min.js"></script>
  <script src="myclock.js"></script>
</head>

<body>
  <script>  "use strict";
  	for (let i = 200; i>30; i*=0.75)
    myClock(i, "background-color: teal; margin: 10px;")
  </script>
</body>

</html>
``` 
The result should look like this:
![Clock sized](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ip8jriysrp2uhvovuta4.png)
You can add different styles too:
```js
  <script>  "use strict";
    let c = ["red", "green", "blue", "yellow", "orange"]
    let k=0
  	for (let i = 200; i>30; i*=0.75)
    myClock(i, "background-color: "+c[k++]+"; margin: 10px; border-radius: 25%;")
  </script>
``` 
![Clocks with decorations](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pzkijsbit2rc7o61dztl.png)

###Making a WebComponent...
If you like the more traditional way, it is easy to convert the DML-class to act as a web-component. In fact, it is still usable in DML without changes. 

You need just two small changes in the source:

a) derive the class from HTMLElement
```js
class _myClock extends HTMLElement {....
```
b) add the HTML-element-definition below the class definition
```js
window.customElements.define('my-clock', _myClock);
```
The class still works as a DML-class, but now can be used as a new html-tag too:
```js
<body>
  <my-clock></my-clock>
</body>
```
The class was just quickly converted for demonstration purpose, so it might lack some functionallity. Just, it works...