{"id":6177,"date":"2022-05-16T12:42:18","date_gmt":"2022-05-16T11:42:18","guid":{"rendered":"https:\/\/solidt.eu\/site\/?p=6177"},"modified":"2024-03-04T23:42:33","modified_gmt":"2024-03-04T22:42:33","slug":"draw-a-clock-with-sin-cos","status":"publish","type":"post","link":"https:\/\/solidt.eu\/site\/draw-a-clock-with-sin-cos\/","title":{"rendered":"Draw a clock with sin\/cos"},"content":{"rendered":"\n<canvas id=\"my-canvas\" width=\"600\" height=\"600\"><\/canvas>\n\n\n\n<div style=\"height: 250px; position:relative; margin-bottom: 50px;\" class=\"wp-block-simple-code-block-ace\"><pre class=\"wp-block-simple-code-block-ace\" style=\"position:absolute;top:0;right:0;bottom:0;left:0\" data-mode=\"javascript\" data-theme=\"monokai\" data-fontsize=\"14\" data-lines=\"Infinity\" data-showlines=\"true\" data-copy=\"false\">const on = (el, ev, fn) => el.addEventListener(ev, fn, { passive: true });\nconst $ = (selector, el) => (el || document).querySelector(selector);\n\non(document, 'DOMContentLoaded', () => {\n\tconst canvas = $('#my-canvas');\n\tconst context = canvas.getContext('2d');\n\tconst half_width = canvas.width \/ 2;\n\tconst half_height = canvas.height \/ 2;\n\tconst clock_radius = Math.min(half_width, half_height) * 0.85;\n\n\tfunction drawLine(x1, y1, x2, y2) {\n\t\tcontext.beginPath();\n\t\tcontext.moveTo(x1 + half_width, y1 + half_height);\n\t\tcontext.lineTo(x2 + half_width, y2 + half_height);\n\t\tcontext.stroke();\n\t};\n\n\tfunction putText(x, y, text) {\n\t\tcontext.font = \"18px Arial\";\n\t\tcontext.textAlign = \"center\"; \n\t\tcontext.fillText(text, x + half_width, y + half_height);\n\t};\n\n\tfunction clock() {\n        context.clearRect(0, 0, canvas.width, canvas.height);\n\t\tconst count = 12\n        const pi2 = 2 * Math.PI;\n\n\t\tfor (let r = 0; r &lt; count; r++) {\n\t\t\tconst angle = r * (pi2 \/ 12);\n\t\t\t\n\t\t\tconst x = Math.sin(angle) * clock_radius;\n\t\t\tconst y = -Math.cos(angle) * clock_radius;\n\t\t\t\n\t\t\tconst nextX = Math.sin(angle) * (clock_radius \/ 1.1);\n\t\t\tconst nextY = -Math.cos(angle) * (clock_radius \/ 1.1);\n\t\t\t\n\t\t\tconst textX = Math.sin(angle) * (clock_radius * 1.1);\n\t\t\tconst textY = -Math.cos(angle) * (clock_radius * 1.1);\n\n\t\t\tdrawLine(x, y, nextX, nextY);\n\t\t\tputText(textX, textY + 7, (r || 12).toString());\n\t\t};\n\t\t\n\t\tconst parts = 24 * 10;\n\t\tfor (let r = 0; r &lt; parts; r++) {\n\t\t\tconst angle = r * (pi2 \/ parts);\n\t\t\t\n\t\t\tconst x = Math.sin(angle) * clock_radius;\n\t\t\tconst y = -Math.cos(angle) * clock_radius;\n\t\t\t\n\t\t\tconst nextAngle = (r + 1) * pi2 \/ parts;\n\t\t\tconst nextX = Math.sin(nextAngle) * clock_radius;\n\t\t\tconst nextY = -Math.cos(nextAngle) * clock_radius;\n\t\t\tdrawLine(x, y, nextX, nextY);\n\t\t};\n\n        \/\/ draw hour\/minute lines\n        const now = new Date();\n        const hoursWithDecimals = now.getHours() + (now.getMinutes() \/ 60);\n        const minutes = now.getMinutes();\n        const seconds = now.getSeconds() + (now.getMilliseconds() \/ 1000);\n\n        function drawHours() {\n            const angle = hoursWithDecimals * (pi2 \/ 12)\n            const x = Math.sin(angle) * (clock_radius \/ 2);\n            const y = -Math.cos(angle) * (clock_radius \/ 2);\n            drawLine(0, 0, x, y);\n        }\n        \n        function drawMinutes() {\n            const angle = minutes * (pi2 \/ 60)\n            const x = Math.sin(angle) * (clock_radius \/ 1.2);\n            const y = -Math.cos(angle) * (clock_radius \/ 1.2);\n            drawLine(0, 0, x, y);\n        }\n\n        function drawSeconds() {\n            const angle = seconds * (pi2 \/ 60)\n            const x = Math.sin(angle) * (clock_radius \/ 1.05);\n            const y = -Math.cos(angle) * (clock_radius \/ 1.05);\n            drawLine(0, 0, x, y);\n        }\n\n        drawHours();\n        drawMinutes();\n        drawSeconds();\n\t};\n\n    const fps = 10;\n    const fpsInterval = 1000 \/ fps;\n    let then;\n    function step(now) {\n        window.requestAnimationFrame(step);\n        if (then === undefined) {\n            then = now;\n        }\n        const elapsed = now - then;\n        if (elapsed > fpsInterval) {\n            \/\/ Get ready for next frame by setting then=now, but also adjust for your\n            \/\/ specified fpsInterval not being a multiple of RAF's interval (16.7ms)\n            then = now - (elapsed % fpsInterval);\n            clock();\n        }\n      }\n    window.requestAnimationFrame(step);\n\t\/\/ setInterval(() => clock(), 20);\n});<\/pre><\/div>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"footnotes":""},"categories":[5,4,1],"tags":[],"class_list":["post-6177","post","type-post","status-publish","format-standard","hentry","category-javascript","category-programming","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/posts\/6177","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/comments?post=6177"}],"version-history":[{"count":15,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/posts\/6177\/revisions"}],"predecessor-version":[{"id":6294,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/posts\/6177\/revisions\/6294"}],"wp:attachment":[{"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/media?parent=6177"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/categories?post=6177"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/tags?post=6177"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}