Skip to content

Instantly share code, notes, and snippets.

@stanwmusic
Created February 10, 2022 07:09
Show Gist options
  • Save stanwmusic/8aaa0b93a125d09829670f574df4b095 to your computer and use it in GitHub Desktop.
Save stanwmusic/8aaa0b93a125d09829670f574df4b095 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: #cc7
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)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment