0% found this document useful (0 votes)
1K views8 pages

Alternative Analog SVG Clock

Uploaded by

Leonardo Forero
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF or read online on Scribd
0% found this document useful (0 votes)
1K views8 pages

Alternative Analog SVG Clock

Uploaded by

Leonardo Forero
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF or read online on Scribd
You are on page 1/ 8
ee)b) = PROJECT Alternative Analog SVG Clock Sergey Alexandrovich Kryukov 14 Mar 2023 CPOL A pure Web browser application, an alternative to the article “An SVG Analog Clock" The application has no server side and is based on HTML + SVG + CSS + JavaScript only Download source code — 3.8 KB se Analog SVG x CG @ File| C/sa/papers/My/Code.. 1 oe OF & Alternative Analog SVG Clock __ Copyright © Sergey A Kryukov, 2023 Contents Introduction What's so Interesting? Implementation svG Clock Comparison of Object Types Arrow Rotation Main Difference Between Analog and Digital Clocks How to Add Decorations? CSS: Docking Layout CSS: Fitting SVG What About Server Part? Introduction What's so Interesting? What's so Interesting? Virtually nothing! This is the application alternative to the one shown in the atticle An SVG Analog Clock. | was surprised by the fact of how a clock could be over-engineered and decided to provide a lean and near-optimal solution which | think is way more adequate ‘An on-screen clock has near-zero practical value, maybe even negative. This is just a traditional programming exercise, on par with editors, Tetris implementations, fractal image rendering, and the like. However, this article explains several subtle points that could be useful for beginners. Implementation SVG First, let's see how SVG can be built dynamically. Everything is implemented as the class SVG: JavaScript class SVG ( implementation = (}; constructor (viewBox, existingSvg) { const ns = “http://www.w3.org/2000/svg" ; this.#implementation.createNS = (name) =: document .createElementNS(ns, name) ; this.#implementation.attribute = (element, values) => { for (let attribute in values) element. setattribute(attribute, values[attribute]); return element; }5 //this. #impLenentation. attribute // defaults... this.#implementation.svg = existingSvg == null ? this.i#implenentation.createns("svg") : existingSvg; if (viewBox I= null) // it also covers undefined this.d#implenentation. svg. setattribute("viewBox", $(view8ox.x. from} ${viewBox.y. from} ${viewBox.x.to - viewBox.x. from} ${viewBox.y.to - viewBox.y. from)” )5 } //constructor get element() { return this.#implementation.svg; } // ... get/set attributes, primitives: Line, circle, ets. appendElement(elenent, group) { if (group) group. appendchild(element) ; else ‘this. #implementation. svg. appendchild(elenent) ; return elements } //appendéLement group() { return this.appendElement(this.#implementation.createNs("g")); } } //class SvG First, note that all the private code is hidden in the constructor and the private member. ‘this. #implementation ‘An SVG element can be created using the document object in a bit different way than HTML elements because SVG uses a different namespace. This is implemented in a local method this. itimplementation.createns. The class SVG can be used in two different ways. If existingSvg is specified, the class can be used to populate an existing element, and new content can be added to existing content. It can be used to add content to an element embedded in HTML. Clock The function createClock creates an instance of the clock. It can also be created in two different ways. If the parameter parent is of the class SVG (described above), the clock can be rendered on top of some existing element. Otherwise, it is created from scratch. As the instance of SVG.element is appended to some existing HTML element, the entire clock created from scratch will be appended to it. The function returns the function set used to set and render the current clock time. To choose the way to use, the code needs to compare objects by type. Let's look at this Comparison of Object Types In the function createClock, we have: JavaScript if (parent.constructor I= SVG) parent .appendChild(svg.element) ; Naturally, at this point, we assume that the object parent is not undefined and not null. When needed, it can be checked up by if (parent != null), as this comparison also covers the case of undefined. This is the way to compare types directly, not using magic strings. We can find many examples of JavaScript code where the types are compared using type names. This is dirty, less maintainable, and should be avoided. Arrow Rotation The central part of the clock is the method set. It rotates the arrows: JavaScript createClock parent => { const set = time => { if (currentTime currentTime = time; const date = new Date(time); let hour = date.getHours() % 12; let minute = date.getMinutes(); let second = date.getSeconds(); hour = (hour + minute / 69 + second / 3600) / 12; minute = (minute + second / 60) / 60; second = second / 68; arrowHour.style. transform = “rotate(${hour}turn)”; arrowMinute.style.transform = “rotate(${minute}turn)” 5 arrowSecond.style.transform = “rotate(${second}turn) 5 ys //set time) return; return set }3 //createClock Here, arrowHour, arrowMinute, arrowSecond are SVG groups. Why? It is done to generalize the code and make it maintainable in case one needs to render some complicated arrow shapes composed of several SVG elements. The other role of style. transform is to avoid trigonometric calculations and make the code more maintainable. Note that the transform assumes that the coordinate point (0, 0) is the center of rotation, Main Difference Between Analog and Digital Clocks The first idea of the calculation of the arrow angles would be using just hours, minutes, and seconds. This is what a digital clock does. These values are integers. And yes, it would be suitable for a digital clock, An analog clock is different. It would be incorrect to say that an hour arrow shows just hours. It should show Thi JavaScript createClock = parent => ( const set = time => { if (currentTime currentTime = time; const date = new Date(time); et hour = date.getHours() % 12; let minute = date.getminutes(); let second = date.getSeconds(); hour = hour / 125 minute = minute / 69; second = second / 69; arrowHour.style.transform = “rotate(${hour}turn)” 5 arrowtinute. style.transform = “rotate(${minute}turn)” 5 arrowSecond.style.transform = ~rotate(${second}turn)” 5 hs //set time) return; return sets }5 //createclock If this calculation was the same as for a digital clock, the minute arrow would stay at some minute label and jump to a new position every minute. And the hour arrow would jump by an hour every hour. Instead, all the arrows should move by seconds. This is done by the correct calculation shown above. How to Add Decorations? The demo application is very simple, How to add all those Arabic or Roman numeric labels, fancy arrows, or fancy backgrounds? The way to go would be using an existing element embedded in HTML. The SVG elements to be controlled by the script could be added on top of it. When | need to do such a thing, | draw appropriate vector graphics with some vector graphic editor and save it as an SVG file, | would recommend Inkscape. The file can be embedded into HTML. Usually, the file should be cleaned of comments, redundant metadata, and unused id attributes. Numeric colors should better be replaced with CSS color names Typically, adding some vector graphics to existing SVG requires some group. The reference to it can be obtained via its id attribute or some other way using Document .querySelector(). Here, most important thing is to match the coordinate system and a viewport. CSS: Docking Layout Note that the application behaves pretty much like a “desktop application”: when a browser window is resized, the
and
elements always stay on top and at bottom of the browser client area, The central
area, where SVG is rendered, is scaled appropriately. At least, it happens if the brower window is not too small This is the behavior most adequate for a single-page application, but not only for this purpose. This is achieved using the CSS Flexbox layout method. The application of flex has many subtle points. In the application, the relevant part of CSS is, commented on to show the right technique: css /* flex: */ html, body { height: 100%; } body { display: flex; flex-flow: column; } main { flex: auto; overflow: auto; } 7* end flex */ CSS: Fitting SVG Another tricky part of the application CSS is fitting the SVG part in its container and its centering. Itis used by using relative units: css section { text-align: center; } svg { height: 8@vmin; width: 8@vmin; } This way, the actual size of the vector graphics part is defined by either width or height of the client size of the browser window, depending on the current aspect ratio. What About Server Part? The question is: why? Maybe this question could be addressed to the author of the original article who presented a much bigger 2-tier application. | think the Web application using some server part is one thing, and a clock component is a totally different thing and should be considered separately. At best, the application can request the server part to change the time zone, or perhaps some reference point to count time from. It can be easily achieved with Ajax. Even in this case, separation of concerns should be used. License This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL) Written By Sergey Alexandrovich Kryukov Architect = United States Phy: manufacturing, diagnostics, testing, and research, theory of music, musical instruments. , physical and quantum optics, mathematics, computer science, control systems for Comments and Discussions & 2 messages have been posted for this article Visit https://www.codeproject.com/Articles/5356856/Alternative-Analog-SVG-Clock to post and view comments on this article, or click here to get a print view with messages Permalink Article Copyright 2023 by Sergey Advertise Alexandrovich Kryukov Privacy Everything else Copyright © CodeProject, Cookies 1999-2023, Terms of Use Web03 2.8:2023-03-03:1

You might also like