Last active
April 21, 2019 23:24
-
-
Save brokenmass/39225b0b8c21bc75966b428cdc7d7951 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const secondHand = document.querySelector('.sec-hand'); | |
const minsHand = document.querySelector('.min-hand'); | |
const hourHand = document.querySelector('.hour-hand'); | |
function calculateAngle(value, steps) { | |
return Math.round(90 + (value / steps) * 360); | |
} | |
function forceRepaint(element) { | |
element.style.display='none'; | |
// no need to store the following anywhere. retrieving the reference is enough, but is a critical step | |
// otherwise the js engine might optimise the execution and skip the repaint. | |
element.offsetHeight; | |
element.style.display='block'; | |
} | |
function renderDate() { | |
const now = new Date(); | |
const seconds = now.getSeconds(); | |
const mins = now.getMinutes(); | |
const hour = now.getHours(); | |
if(seconds === 0) { | |
// To avoid visual glitches you have to do an instantaneous transition from the 59s hand position | |
// to the (equivalen) '-1s' position before performing the transition to the 0s position. | |
// To achieve this using js, a solution is to set transition to '0s all' (hence disabling any animation), | |
// set the position of the hand to -1s, force a repaint so that the browser repaint it | |
// even if we are in the middle of js code execution, and finally revert the transition property to the original | |
// value. | |
// At this point he normal cicle will ensure that a 'smooth' transition from the -1s to 0s occurs. | |
secondHand.style.transition = "all 0s"; | |
secondHand.style.transform = `rotate(${calculateAngle(-1, 60 )}deg)`; | |
forceRepaint(secondHand); | |
secondHand.style.transition = ""; | |
if(mins === 0) { | |
// Here we just moved from hh:59:59 to (hh+1):00:00 so we also have to 'reset' the minutes handle | |
minsHand.style.transition = "all 0s"; | |
minsHand.style.transform = `rotate(${calculateAngle(-1/60, 60 )}deg)`; | |
forceRepaint(minsHand); | |
minsHand.style.transition = ""; | |
if(hours % 12 === 0) { | |
// here we just moved from 11:59:59 to 00:00:00 so we also have to 'reset' the hours handle | |
hourHand.style.transition = "all 0s"; | |
hourHand.style.transform = `rotate(${calculateAngle(-1/3600, 12 )}deg)`; | |
forceRepaint(hourHand); | |
hourHand.style.transition = ""; | |
} | |
} | |
} | |
const secondsDegrees = calculateAngle(seconds, 60 ); | |
secondHand.style.transform = `rotate(${secondsDegrees}deg)`; | |
const minsDegrees = calculateAngle(mins + seconds/60, 60); | |
minsHand.style.transform = `rotate(${minsDegrees}deg)`; | |
const hourDegrees = calculateAngle(hour + mins/60 + seconds/3600, 12); | |
hourHand.style.transform = `rotate(${hourDegrees}deg)`; | |
} | |
setInterval(renderDate, 1000) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment