Inspired by a nice post Simple Analog Clock Using Html, CSS & Javascript, that shows how to build an analog clock the "traditional" way, I was curious to see, how much coding it would need with 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:
// 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:
<!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:
You can add different styles too:
<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>
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
class _myClock extends HTMLElement {....
b) add the HTML-element-definition below the class definition
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:
<body>
<my-clock></my-clock>
</body>
The class was just quickly converted for demonstration purpose, so it might lack some functionallity. Just, it works...
Top comments (0)