From c6c4673bc2c49386074a19c50040d682fd2291fd Mon Sep 17 00:00:00 2001 From: FranzAT Date: Thu, 15 Jul 2021 16:57:42 +0200 Subject: [PATCH 1/3] canvas clock ready --- README.md | 2 + clock.js | 184 +++++++++++++++++++++++++++++++++++++-------------- css/main.css | 73 ++++++++++++++++++++ index.html | 32 +++++++-- 4 files changed, 237 insertions(+), 54 deletions(-) create mode 100644 css/main.css diff --git a/README.md b/README.md index bfabaa0..f1810c3 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,4 @@ # Analog Clock (Canvas) [Video Guide](https://youtu.be/1q7EEd6Huf0) + +[Digital wall clock with Raspberry Pi](https://ampron.eu/article/use-case/digital-wall-clock-with-raspberry-pi/) \ No newline at end of file diff --git a/clock.js b/clock.js index 0a6c29a..3c5ba99 100644 --- a/clock.js +++ b/clock.js @@ -1,46 +1,108 @@ let canvas, ctx; +//https://stackoverflow.com/questions/29675279/how-to-style-canvas-elements-with-css + + +/* Function to get information from CSS into Canvas: + - An div element is created and added to the DOM. + - The CSS information of the element is saved to an array and available for the canvas. + - After that, the element is removed from the DOM again. +*/ + +// "Cache" +var classProperties = {}; +function getPropeties(className){ + if (true === classProperties[className]) { + return classProperties[className]; + } + + // Create an element with the class name and add it to the DOM + let element = document.createElement('div'); + element.style.display = 'none;' + //element.classList.add(className); + element.setAttribute('id', className); + document.body.appendChild(element); + //document.getElementById("clock").appendChild(element); + + // Get needed stuff from the DOM and put it in the cache + let compStyles = window.getComputedStyle(element); + // create font like '18px Noto Sans' + let font = (canvas.width / 16)+"px "+compStyles.fontFamily.slice(1,-1); + classProperties[className] = { + fill: compStyles.backgroundColor, + lineWidth: compStyles.fontSize, + stroke: compStyles.borderColor, + second: compStyles.outlineColor, + color: compStyles.color, + font: font + } + // Remove the element from the DOM again + element.remove(); + return classProperties[className]; +} + function draw () { + let time = (function () { - let midnight = new Date(); - midnight.setHours(0); - midnight.setMinutes(0); - midnight.setSeconds(0); - midnight.setMilliseconds(0); - return Date.now() - midnight.getTime(); - })(), - hours = time / (60 * 60 * 1000), - minutes = hours * 60 % 60, - seconds = minutes * 60 % 60, - c = {x: canvas.width / 2, y: canvas.height / 2}; + let midnight = new Date(); + midnight.setHours(0); + midnight.setMinutes(0); + midnight.setSeconds(0); + midnight.setMilliseconds(0); + return Date.now() - midnight.getTime(); + })(), + + hours = time / (60 * 60 * 1000), + minutes = hours * 60 % 60, + seconds = Math.round(minutes * 60 % 60), + + c = {x: canvas.width / 2, y: canvas.height / 2}; ctx.clearRect(0, 0, canvas.width, canvas.height); - ctx.lineCap = 'round'; - secondHand(); - minuteHand(); + background(); hourHand(); + minuteHand(); + secondHand(); face(); + function background() { + // Background + ctx_bgr.beginPath(); + //ctx.arc(c.x, c.y, canvas.width / 2 - 10, 0, Math.PI * 2); + ctx_bgr.arc(c.x, c.y, canvas.width / 2 - canvas.width / 60, 0, Math.PI * 2); + ctx_bgr.fillStyle = classProperties.clockface.fill; + ctx_bgr.fill(); + } + function face () { - // Border - ctx.lineWidth = 5; - ctx.strokeStyle = 'black'; + + // Border + //ctx.lineWidth = 5; + let lwf = canvas.width / 300; + ctx.lineWidth = lwf; + ctx.strokeStyle = classProperties.clockface.stroke; ctx.beginPath(); - ctx.arc(c.x, c.y, 140, 0, Math.PI * 2); - ctx.stroke(); - + //ctx.arc(c.x, c.y, canvas.width / 2 - 10, 0, Math.PI * 2); + let rf = canvas.width / 2 - canvas.width / 60; + ctx.arc(c.x, c.y, rf, 0, Math.PI * 2); + ctx.stroke(); + // Dashes - ctx.lineWidth = 3; + //ctx.lineWidth = 3; + ctx.lineWidth = lwf; for (let i = 0; i < 60; i++) { - let r = 135, - l = 5; - ctx.strokeStyle = 'rgba(0, 0, 0, 0.25)'; + //let r = canvas.width / 2 - 15, + let l = canvas.width / 80, + r = rf - l; + //ctx.strokeStyle = 'rgba(0, 0, 0, 0.25)'; + ctx.strokeStyle = classProperties.clockface.stroke; if (i % 5 === 0) - r -= l, - l *= 2, - ctx.strokeStyle = 'rgba(0, 0, 0, 0.5)'; + l *= 2.5, + r = rf - l, + //ctx.strokeStyle = 'rgba(0, 0, 0, 0.5)'; + ctx.strokeStyle = classProperties.clockface.stroke; let v = new Vector(r, Math.PI * 2 * (i / 60) - Math.PI / 2); ctx.beginPath(); ctx.moveTo(v.getX() + c.x, v.getY() + c.y); @@ -50,54 +112,72 @@ function draw () { } // Numbers - ctx.font = '18px Noto Sans'; - ctx.fillStyle = 'black'; + //ctx.font = '18px Noto Sans'; + ctx.font = classProperties.clockface.font; + //ctx.fillStyle = 'black'; + ctx.fillStyle = classProperties.clockface.color; ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; for (let i = 1; i <= 12; i++) { - let v = new Vector(113, Math.PI * 2 * (i / 12) - Math.PI / 2); + let v = new Vector(rf - canvas.width / 14, Math.PI * 2 * (i / 12) - Math.PI / 2); ctx.fillText(i, v.getX() + c.x, v.getY() + c.y); } // Center button ctx.beginPath(); - ctx.arc(c.x, c.y, 3.75, 0, Math.PI * 2); - ctx.fillStyle = 'white'; - ctx.strokeStyle = 'black'; - ctx.lineWidth = 2.5; + //ctx.arc(c.x, c.y, 3.75, 0, Math.PI * 2); + ctx.arc(c.x, c.y, canvas.width / 130, 0, Math.PI * 2); + //ctx.fillStyle = 'white'; + ctx.fillStyle = classProperties.clockface.fill; + //ctx.strokeStyle = 'black'; + ctx.strokeStyle = classProperties.clockface.second; + //ctx.lineWidth = 2.5; + ctx.lineWidth = canvas.width / 180; ctx.fill(); ctx.stroke(); + + } function secondHand () { - ctx.lineWidth = 1.5; - ctx.strokeStyle = 'black'; + //ctx.lineWidth = 1.5; + ctx.lineWidth = canvas.width / 200; + //ctx.strokeStyle = 'black'; + ctx.strokeStyle = classProperties.clockface.second; ctx.beginPath(); let a = Math.PI * 2 * (seconds / 60) - Math.PI / 2; - let v = new Vector(95, a); - let v2 = new Vector(-20, a); + //let v = new Vector(canvas.width / 2 - 55, a); + let v = new Vector(canvas.width / 2 - canvas.width / 6, a); + //let v2 = new Vector(-20, a); + let v2 = new Vector(-canvas.width / 20, a); ctx.moveTo(v2.getX() + c.x, v2.getY() + c.y); ctx.lineTo(v.getX() + c.x, v.getY() + c.y); ctx.stroke(); } function minuteHand () { - ctx.lineWidth = 4; - ctx.strokeStyle = 'black'; + //ctx.lineWidth = 4; + ctx.lineWidth = canvas.width / 75; + //ctx.strokeStyle = 'black'; + ctx.strokeStyle = classProperties.clockface.stroke; ctx.beginPath(); let a = Math.PI * 2 * (minutes / 60) - Math.PI / 2; - let v = new Vector(95, a); + //let v = new Vector(canvas.width / 2 - 55, a); + let v = new Vector(canvas.width / 2 - canvas.width / 6, a); ctx.moveTo(c.x, c.y); ctx.lineTo(v.getX() + c.x, v.getY() + c.y); ctx.stroke(); } function hourHand () { - ctx.lineWidth = 4; - ctx.strokeStyle = 'black'; + //ctx.lineWidth = 4; + ctx.lineWidth = canvas.width / 75; + //ctx.strokeStyle = 'black'; + ctx.strokeStyle = classProperties.clockface.stroke; ctx.beginPath(); let a = Math.PI * 2 * (hours / 12) - Math.PI / 2; - let v = new Vector(60, a); + //let v = new Vector(canvas.width / 2 - 90, a); + let v = new Vector(canvas.width / 2 - canvas.width / 3.5, a); ctx.moveTo(c.x, c.y); ctx.lineTo(v.getX() + c.x, v.getY() + c.y); ctx.stroke(); @@ -106,10 +186,18 @@ function draw () { function init () { canvas = document.getElementById('clock'); - canvas.width = canvas.height = 300; + canvas_bgr = document.getElementById('clock-background'); + ctx = canvas.getContext('2d'); - - setInterval(draw, 10); + ctx_bgr = canvas_bgr.getContext('2d'); + + let canvasCSS = window.getComputedStyle(clock); // get current width of clock element in px, because CSS defined with 100% so that it is flexible to screensize + let blocksize = canvasCSS.width.slice(0, -2); // create out of canvas.width 1080px a string 1080 + canvas.width = canvas.height = blocksize; // define canvas size based on current size of clock element shown on screen + canvas_bgr.width = canvas_bgr.height = blocksize; + getPropeties('clockface'); // get CSS properties for canvas + + setInterval(draw, 1000); // draw the clock every second } -init(); +init(); \ No newline at end of file diff --git a/css/main.css b/css/main.css new file mode 100644 index 0000000..2864632 --- /dev/null +++ b/css/main.css @@ -0,0 +1,73 @@ +html{ + height: 100vh; +} + +body { + background-color:#262A39; + color: black; + width:100%; + height: 100%; + margin:0; + padding:0; + display:flex; +} + +main { + background-color: #8a8a8a; + width: 100%; + height: 100%; + display: flex; + flex-wrap: wrap; + justify-content: flex-start; + align-content: flex-start; + align-items: stretch; +} + +h1 { + color: navy; + text-align: center; +} + +p { + font-family: verdana; + font-size: 20px; +} + +#clock-section { + position: relative; + flex: 100vh; /*initial width of flexible item is 100% of viewport width*/ + max-height: 100vw; /*maxium height is 100% of viewport width*/ + max-width: 100vh; /*maxium width is 100% of viewport height*/ + aspect-ratio: 1/1; /*in connection with max-height and max-width above - full screen quadrat */ + display: flex; /* so child elements can use flexbox stuff too*/ + justify-content: center; + align-items: center; +} + +#weather-section { + flex: auto; + height: 100vh; +} +@media (max-width: 100vh){ + #weather-section{ + max-height: calc(100% - 100vw); + } +} + +#clock, #clock-background { + position: absolute; + width: 100%; + height: 100%; +} + +#clockface { + background-color: #faf0e6; + border-color: black; + outline-color: red; /*SecondHand*/ + color: black; + font-family: Noto Sans; +} + +#clock-functions { + position: absolute; +} \ No newline at end of file diff --git a/index.html b/index.html index 04f4843..2f2b522 100644 --- a/index.html +++ b/index.html @@ -1,12 +1,32 @@ - + - Analog Clock + + + + + + Analog Clock + + - - - - +
+
+ +
+ +
+ +
+
+
+ +
+
+
+ + + From 23ac389988bfc675b2c2ae6fd4454a456b47025d Mon Sep 17 00:00:00 2001 From: FranzAT Date: Thu, 15 Jul 2021 17:36:26 +0200 Subject: [PATCH 2/3] Removing unnecessary comments made during development --- clock.js | 27 +-------------------------- 1 file changed, 1 insertion(+), 26 deletions(-) diff --git a/clock.js b/clock.js index 3c5ba99..21a7241 100644 --- a/clock.js +++ b/clock.js @@ -22,7 +22,6 @@ function getPropeties(className){ //element.classList.add(className); element.setAttribute('id', className); document.body.appendChild(element); - //document.getElementById("clock").appendChild(element); // Get needed stuff from the DOM and put it in the cache let compStyles = window.getComputedStyle(element); @@ -70,7 +69,6 @@ function draw () { function background() { // Background ctx_bgr.beginPath(); - //ctx.arc(c.x, c.y, canvas.width / 2 - 10, 0, Math.PI * 2); ctx_bgr.arc(c.x, c.y, canvas.width / 2 - canvas.width / 60, 0, Math.PI * 2); ctx_bgr.fillStyle = classProperties.clockface.fill; ctx_bgr.fill(); @@ -79,29 +77,23 @@ function draw () { function face () { // Border - //ctx.lineWidth = 5; let lwf = canvas.width / 300; ctx.lineWidth = lwf; ctx.strokeStyle = classProperties.clockface.stroke; ctx.beginPath(); - //ctx.arc(c.x, c.y, canvas.width / 2 - 10, 0, Math.PI * 2); let rf = canvas.width / 2 - canvas.width / 60; ctx.arc(c.x, c.y, rf, 0, Math.PI * 2); ctx.stroke(); // Dashes - //ctx.lineWidth = 3; ctx.lineWidth = lwf; for (let i = 0; i < 60; i++) { - //let r = canvas.width / 2 - 15, let l = canvas.width / 80, r = rf - l; - //ctx.strokeStyle = 'rgba(0, 0, 0, 0.25)'; ctx.strokeStyle = classProperties.clockface.stroke; if (i % 5 === 0) l *= 2.5, r = rf - l, - //ctx.strokeStyle = 'rgba(0, 0, 0, 0.5)'; ctx.strokeStyle = classProperties.clockface.stroke; let v = new Vector(r, Math.PI * 2 * (i / 60) - Math.PI / 2); ctx.beginPath(); @@ -112,9 +104,7 @@ function draw () { } // Numbers - //ctx.font = '18px Noto Sans'; ctx.font = classProperties.clockface.font; - //ctx.fillStyle = 'black'; ctx.fillStyle = classProperties.clockface.color; ctx.textAlign = 'center'; ctx.textBaseline = 'middle'; @@ -125,30 +115,21 @@ function draw () { // Center button ctx.beginPath(); - //ctx.arc(c.x, c.y, 3.75, 0, Math.PI * 2); ctx.arc(c.x, c.y, canvas.width / 130, 0, Math.PI * 2); - //ctx.fillStyle = 'white'; ctx.fillStyle = classProperties.clockface.fill; - //ctx.strokeStyle = 'black'; ctx.strokeStyle = classProperties.clockface.second; - //ctx.lineWidth = 2.5; ctx.lineWidth = canvas.width / 180; ctx.fill(); - ctx.stroke(); - + ctx.stroke(); } function secondHand () { - //ctx.lineWidth = 1.5; ctx.lineWidth = canvas.width / 200; - //ctx.strokeStyle = 'black'; ctx.strokeStyle = classProperties.clockface.second; ctx.beginPath(); let a = Math.PI * 2 * (seconds / 60) - Math.PI / 2; - //let v = new Vector(canvas.width / 2 - 55, a); let v = new Vector(canvas.width / 2 - canvas.width / 6, a); - //let v2 = new Vector(-20, a); let v2 = new Vector(-canvas.width / 20, a); ctx.moveTo(v2.getX() + c.x, v2.getY() + c.y); ctx.lineTo(v.getX() + c.x, v.getY() + c.y); @@ -156,13 +137,10 @@ function draw () { } function minuteHand () { - //ctx.lineWidth = 4; ctx.lineWidth = canvas.width / 75; - //ctx.strokeStyle = 'black'; ctx.strokeStyle = classProperties.clockface.stroke; ctx.beginPath(); let a = Math.PI * 2 * (minutes / 60) - Math.PI / 2; - //let v = new Vector(canvas.width / 2 - 55, a); let v = new Vector(canvas.width / 2 - canvas.width / 6, a); ctx.moveTo(c.x, c.y); ctx.lineTo(v.getX() + c.x, v.getY() + c.y); @@ -170,13 +148,10 @@ function draw () { } function hourHand () { - //ctx.lineWidth = 4; ctx.lineWidth = canvas.width / 75; - //ctx.strokeStyle = 'black'; ctx.strokeStyle = classProperties.clockface.stroke; ctx.beginPath(); let a = Math.PI * 2 * (hours / 12) - Math.PI / 2; - //let v = new Vector(canvas.width / 2 - 90, a); let v = new Vector(canvas.width / 2 - canvas.width / 3.5, a); ctx.moveTo(c.x, c.y); ctx.lineTo(v.getX() + c.x, v.getY() + c.y); From e897e5419086dffd266d4960ddc56c1ef060240c Mon Sep 17 00:00:00 2001 From: FranzAT Date: Thu, 15 Jul 2021 17:48:53 +0200 Subject: [PATCH 3/3] Cleaned spaces by tab --- clock.js | 130 +++++++++++++++++++++++++++---------------------------- 1 file changed, 65 insertions(+), 65 deletions(-) diff --git a/clock.js b/clock.js index 21a7241..b94f30f 100644 --- a/clock.js +++ b/clock.js @@ -42,7 +42,7 @@ function getPropeties(className){ function draw () { - let time = (function () { + let time = (function () { let midnight = new Date(); midnight.setHours(0); midnight.setMinutes(0); @@ -56,123 +56,123 @@ function draw () { seconds = Math.round(minutes * 60 % 60), c = {x: canvas.width / 2, y: canvas.height / 2}; - - ctx.clearRect(0, 0, canvas.width, canvas.height); - ctx.lineCap = 'round'; + + ctx.clearRect(0, 0, canvas.width, canvas.height); + ctx.lineCap = 'round'; background(); - hourHand(); - minuteHand(); - secondHand(); - face(); + hourHand(); + minuteHand(); + secondHand(); + face(); function background() { // Background - ctx_bgr.beginPath(); + ctx_bgr.beginPath(); ctx_bgr.arc(c.x, c.y, canvas.width / 2 - canvas.width / 60, 0, Math.PI * 2); ctx_bgr.fillStyle = classProperties.clockface.fill; - ctx_bgr.fill(); + ctx_bgr.fill(); } - function face () { - + function face () { + // Border let lwf = canvas.width / 300; ctx.lineWidth = lwf; - ctx.strokeStyle = classProperties.clockface.stroke; - ctx.beginPath(); + ctx.strokeStyle = classProperties.clockface.stroke; + ctx.beginPath(); let rf = canvas.width / 2 - canvas.width / 60; - ctx.arc(c.x, c.y, rf, 0, Math.PI * 2); + ctx.arc(c.x, c.y, rf, 0, Math.PI * 2); ctx.stroke(); - // Dashes + // Dashes ctx.lineWidth = lwf; - for (let i = 0; i < 60; i++) { + for (let i = 0; i < 60; i++) { let l = canvas.width / 80, r = rf - l; ctx.strokeStyle = classProperties.clockface.stroke; - if (i % 5 === 0) + if (i % 5 === 0) l *= 2.5, - r = rf - l, + r = rf - l, ctx.strokeStyle = classProperties.clockface.stroke; - let v = new Vector(r, Math.PI * 2 * (i / 60) - Math.PI / 2); - ctx.beginPath(); - ctx.moveTo(v.getX() + c.x, v.getY() + c.y); - v.setMag(r + l); - ctx.lineTo(v.getX() + c.x, v.getY() + c.y); - ctx.stroke(); - } - - // Numbers + let v = new Vector(r, Math.PI * 2 * (i / 60) - Math.PI / 2); + ctx.beginPath(); + ctx.moveTo(v.getX() + c.x, v.getY() + c.y); + v.setMag(r + l); + ctx.lineTo(v.getX() + c.x, v.getY() + c.y); + ctx.stroke(); + } + + // Numbers ctx.font = classProperties.clockface.font; ctx.fillStyle = classProperties.clockface.color; - ctx.textAlign = 'center'; - ctx.textBaseline = 'middle'; - for (let i = 1; i <= 12; i++) { - let v = new Vector(rf - canvas.width / 14, Math.PI * 2 * (i / 12) - Math.PI / 2); - ctx.fillText(i, v.getX() + c.x, v.getY() + c.y); - } - - // Center button - ctx.beginPath(); + ctx.textAlign = 'center'; + ctx.textBaseline = 'middle'; + for (let i = 1; i <= 12; i++) { + let v = new Vector(rf - canvas.width / 14, Math.PI * 2 * (i / 12) - Math.PI / 2); + ctx.fillText(i, v.getX() + c.x, v.getY() + c.y); + } + + // Center button + ctx.beginPath(); ctx.arc(c.x, c.y, canvas.width / 130, 0, Math.PI * 2); ctx.fillStyle = classProperties.clockface.fill; ctx.strokeStyle = classProperties.clockface.second; ctx.lineWidth = canvas.width / 180; - ctx.fill(); - ctx.stroke(); + ctx.fill(); + ctx.stroke(); - } + } - function secondHand () { + function secondHand () { ctx.lineWidth = canvas.width / 200; ctx.strokeStyle = classProperties.clockface.second; - ctx.beginPath(); - let a = Math.PI * 2 * (seconds / 60) - Math.PI / 2; + ctx.beginPath(); + let a = Math.PI * 2 * (seconds / 60) - Math.PI / 2; let v = new Vector(canvas.width / 2 - canvas.width / 6, a); let v2 = new Vector(-canvas.width / 20, a); - ctx.moveTo(v2.getX() + c.x, v2.getY() + c.y); - ctx.lineTo(v.getX() + c.x, v.getY() + c.y); - ctx.stroke(); - } + ctx.moveTo(v2.getX() + c.x, v2.getY() + c.y); + ctx.lineTo(v.getX() + c.x, v.getY() + c.y); + ctx.stroke(); + } - function minuteHand () { + function minuteHand () { ctx.lineWidth = canvas.width / 75; ctx.strokeStyle = classProperties.clockface.stroke; - ctx.beginPath(); - let a = Math.PI * 2 * (minutes / 60) - Math.PI / 2; + ctx.beginPath(); + let a = Math.PI * 2 * (minutes / 60) - Math.PI / 2; let v = new Vector(canvas.width / 2 - canvas.width / 6, a); - ctx.moveTo(c.x, c.y); - ctx.lineTo(v.getX() + c.x, v.getY() + c.y); - ctx.stroke(); - } + ctx.moveTo(c.x, c.y); + ctx.lineTo(v.getX() + c.x, v.getY() + c.y); + ctx.stroke(); + } - function hourHand () { + function hourHand () { ctx.lineWidth = canvas.width / 75; ctx.strokeStyle = classProperties.clockface.stroke; - ctx.beginPath(); - let a = Math.PI * 2 * (hours / 12) - Math.PI / 2; + ctx.beginPath(); + let a = Math.PI * 2 * (hours / 12) - Math.PI / 2; let v = new Vector(canvas.width / 2 - canvas.width / 3.5, a); - ctx.moveTo(c.x, c.y); - ctx.lineTo(v.getX() + c.x, v.getY() + c.y); - ctx.stroke(); - } + ctx.moveTo(c.x, c.y); + ctx.lineTo(v.getX() + c.x, v.getY() + c.y); + ctx.stroke(); + } } function init () { - canvas = document.getElementById('clock'); + canvas = document.getElementById('clock'); canvas_bgr = document.getElementById('clock-background'); - ctx = canvas.getContext('2d'); + ctx = canvas.getContext('2d'); ctx_bgr = canvas_bgr.getContext('2d'); let canvasCSS = window.getComputedStyle(clock); // get current width of clock element in px, because CSS defined with 100% so that it is flexible to screensize let blocksize = canvasCSS.width.slice(0, -2); // create out of canvas.width 1080px a string 1080 - canvas.width = canvas.height = blocksize; // define canvas size based on current size of clock element shown on screen + canvas.width = canvas.height = blocksize; // define canvas size based on current size of clock element shown on screen canvas_bgr.width = canvas_bgr.height = blocksize; getPropeties('clockface'); // get CSS properties for canvas - setInterval(draw, 1000); // draw the clock every second + setInterval(draw, 1000); // draw the clock every second } init(); \ No newline at end of file