Skip to content

Instantly share code, notes, and snippets.

@stanwmusic
Created February 11, 2022 05:03
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save stanwmusic/f6a93e1627f4484ea2dc73a7e2533cfc to your computer and use it in GitHub Desktop.
Save stanwmusic/f6a93e1627f4484ea2dc73a7e2533cfc to your computer and use it in GitHub Desktop.
Analog Clock

Analog Clock

For this analog clock, I used JavaScript only for getting the current time at load then used CSS animation to run the clock from there.

A Pen by Stan Williams on CodePen.

License.

#clock
%ul.hours
- (1..12).each do |i|
%li
%span
#{i}
%ul.mins
- (1..60).each do |j|
%li
%span
|
.hr-wrapper
.hand.hr
.min-wrapper
.hand.min
.sec-wrapper
.hand.sec
// get current time
var dateInfo = new Date();
var hr = dateInfo.getHours() > 12 ? dateInfo.getHours() - 12 : dateInfo.getHours(),
min = dateInfo.getMinutes(),
sec = dateInfo.getSeconds(),
milsec = dateInfo.getMilliseconds();
/*
1 hr = 30°, 1 min = 6°, 1 sec = 6°, 1 millisec = 0.36°
Even though we can calculate the proper angles of the hour, minute, and second hands, we can determine more accurately where the hands are between the current and next ticks. For example, if it is 6:30, we know that the hour hand is at least 180°, yet it should be between the 6 and 7. To get that, we divide the angle of the current minute by 12 ((30 * 6°) / 12) and add the result (15) to 180. Therefore, the hour hand should be at 195°.
*/
var hrAngle = hr * 30 + (min * 6 / 12),
minAngle = min * 6 + (sec * 6 / 60),
secAngle = sec * 6 + (milsec * 0.36 / 1000);
// set initial angles of the hand wrappers
function setAngle(wrapper, angle) {
document.querySelector("." + wrapper).style.transform = "rotate(" + angle + "deg)";
}
setAngle("hr-wrapper", hrAngle);
setAngle("min-wrapper", minAngle);
setAngle("sec-wrapper", secAngle);
$size: 320px
// for drawing hands of clock
@mixin handConfig($color, $handW, $handH, $dur)
background: $color
left: ($size / 2) - ($handW / 2)
width: $handW
height: $handH
animation: rotateHand $dur linear infinite
&:after
background: $color
border-radius: 50%
content: ""
display: block
position: absolute
bottom: 0 - ($handW / 2)
width: $handW
height: $handW
body
background: #444
color: #333
font-family: Helvetica, sans-serif
// hour and minute marks on clock
$hourWingW: $size/4
$minWingW: $size/12
ul
list-style: none
top: 0
margin: 0
padding: 0
position: absolute
text-align: center
li
position: absolute
transform-origin: 50% 100%
height: $size/2
.hours
left: ($size/2)- ($hourWingW/2)
font-size: $size/6
letter-spacing: $size/-200
line-height: $size/3.5
li
width: $hourWingW
span
display: block
@for $i from 1 through 12
li:nth-of-type(#{$i})
transform: rotate(30deg * $i)
span
transform: rotate(-30deg * $i)
.mins
left: ($size/2)- ($minWingW/2)
line-height: $size/12
li
width: $minWingW
span
font-size: $size/24
li:nth-of-type(5n)
span
font-size: $size/16
font-weight: bold
@for $i from 1 through 60
li:nth-of-type(#{$i})
transform: rotate(6deg * $i)
// clock itself
#clock
background: #fff
border: $size/12 solid #222
border-radius: 50%
box-shadow: 0 4px 0 #aaa inset, 0 8px 0 rgba(0, 0, 0, 0.5)
position: relative
width: $size
height: $size
margin: auto
// hands
/* JavaScript pre-rotates these wrappers instead of the hands when getting the time at load. If it pre-rotates the hands, then the hands will not perform 1 turn at their normal speeds. */
.hr-wrapper, .min-wrapper, .sec-wrapper
position: absolute
width: $size
height: $size
.hand
position: absolute
bottom: 50%
transform-origin: 50% 100%
.hr
@include handConfig(#222, round($size / 20), round($size / 2.75), 60s*60*12)
.min
@include handConfig(#222, round($size / 20), round(($size / 2) * 0.95), 60s*60)
.sec
@include handConfig(#d00, round($size / 45), round(($size / 2) * 0.95), 60s)
@keyframes rotateHand
to
transform: rotate(1turn)
@stanwmusic
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment