Analog Clock written in CSS3 using SASS + showing real time by JavaScript
A Pen by Dawid Krajewski on CodePen.
Analog Clock written in CSS3 using SASS + showing real time by JavaScript
A Pen by Dawid Krajewski on CodePen.
| <div class="whole-page vertical-middle"> | |
| <div class="vertical-middle__child"> | |
| <div class="clock"> | |
| <ul class="clock__marks"></ul> | |
| <div class="clock__hands"> | |
| <div class="clock__hand clock__hand--hour"></div> | |
| <div class="clock__hand clock__hand--minute"></div> | |
| <div class="clock__hand clock__hand--second"></div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> |
| /* Setting current time + fix for inactive tab */ | |
| var radius = 6; | |
| $(document).ready(function() { | |
| for(var i=0; i<60; i++) | |
| $('.clock__marks').append('<li></li>'); | |
| var currentTime = new Date(); | |
| var second = currentTime.getSeconds() * radius; | |
| var minute = currentTime.getMinutes() * radius + Math.floor(second / (radius * 10) * 10) / 10; | |
| var hour = currentTime.getHours() * radius * 5 + Math.floor(minute / (radius * 2) * 10) / 10; | |
| setClockHands(second, minute, hour); | |
| }); | |
| function setClockHands(second, minute, hour){ | |
| var secondElm = $('.clock__hand--second'); | |
| var minuteElm = $('.clock__hand--minute'); | |
| var hourElm = $('.clock__hand--hour'); | |
| secondElm.css('transform', 'rotate(' + second + 'deg)'); | |
| minuteElm.css('transform', 'rotate(' + minute + 'deg)'); | |
| hourElm.css('transform', 'rotate(' + hour + 'deg)'); | |
| var interval = 1000; //1 second | |
| var before = new Date(); | |
| setInterval(function(){ | |
| var now = new Date(); | |
| var elapsedTime = now.getTime() - before.getTime(); //Fix calculating in inactive tabs | |
| var delay = Math.round(elapsedTime/interval); | |
| second += radius * delay; | |
| for(var i=0; i<delay; i++){ | |
| if( ((second - i) * radius) % (radius * 5) === 0 ){ | |
| minute += 0.5; | |
| if( minute % radius === 0 ){ | |
| hour += 0.5; | |
| } | |
| } | |
| } | |
| secondElm.css('transform', 'rotate(' + second + 'deg)'); | |
| minuteElm.css('transform', 'rotate(' + minute + 'deg)'); | |
| hourElm.css('transform', 'rotate(' + hour + 'deg)'); | |
| before = new Date(); | |
| }, interval); | |
| } |
| /* Pure CSS3 without any images */ | |
| *{ backface-visibility: hidden; } | |
| .whole-page{ background: radial-gradient(circle, #FFFFFF 0%, #8E8E8E 17%, #202020 100%); } | |
| .vertical-middle{ display: table; width: 100%; height: 100%; position: absolute; | |
| &__child{ display: table-cell; vertical-align: middle; text-align: center; } | |
| } | |
| /* Math functions */ | |
| $pi: 3.1415926535897932384626433832795028841971693993751; | |
| @function radian($angle){ | |
| @return $angle * $pi / 180; | |
| } | |
| @function strip-units($number) { | |
| @return $number / ($number * 0 + 1); | |
| } | |
| @function even($number){ | |
| $number: round($number); | |
| @if strip-units($number)%2 != 0{ | |
| $number: $number + 1; | |
| } | |
| @return $number; | |
| } | |
| /* Clock */ | |
| $clockSize: 400px; | |
| $clockPadding: $clockSize/60; | |
| $clockBorderWidth: $clockSize * 0.035; | |
| $digitsSize: round($clockSize / 10); | |
| $numOfMinuteMarks: 60; | |
| $radius: 360 / $numOfMinuteMarks; | |
| $handsCircleSize: round($clockSize/20); | |
| $handHourLength: round($clockSize * 0.3); | |
| $handHourWidth: even($handsCircleSize * 0.5); | |
| $handMinuteLength: round($clockSize * 0.4); | |
| $handMinuteWidth: even($handsCircleSize * 0.35); | |
| $handSecondLength: $handMinuteLength * 1.1; | |
| $handSecondWidth: ceil($clockSize/300); | |
| $S: ( | |
| x: ($clockSize - $clockPadding)/2, | |
| y: ($clockSize - $clockPadding)/2 | |
| ); | |
| $A: ( | |
| x: ($clockSize - $clockPadding)/2, | |
| y: 0 | |
| ); | |
| $u: ( | |
| x: -1 * map-get($S, x), | |
| y: -1 * map-get($S, y) | |
| ); | |
| .clock{ font-family: "Droid Serif", serif; display: inline-block; width: $clockSize; height: $clockSize; border: $clockBorderWidth solid #000; border-radius: 100%; position: absolute; top: 50%; left: 50%; margin-top: -$clockSize/2 - $clockBorderWidth; margin-left: -$clockSize/2 - $clockBorderWidth; background: linear-gradient(to bottom right, #E3E3E3, #FFF); box-shadow: 5px 5px 10px rgba(#000, 0.5) inset; | |
| &__marks{ list-style: none; position: absolute; top: 0; left: 0; margin: 0; padding: 0; | |
| li{ display: block; position: absolute; | |
| &:before{ content: ""; display: block; width: 1px; height: 6px; position: absolute; top: 0; left: 0; background: #000 } | |
| &:after{ font-size: $digitsSize; line-height: 1; position: absolute; top: $digitsSize*0.4; width: 50px; left: -25px; text-align: center; -webkit-font-smoothing: antialiased; } | |
| @for $i from 1 through $numOfMinuteMarks{ | |
| $B: ( | |
| x: -(map-get($A, y) + map-get($u, y)) * sin(radian($i * $radius)) - map-get($u, x) + $clockPadding/2, | |
| y: (map-get($A, y) + map-get($u, y)) * cos(radian($i * $radius)) - map-get($u, y) + $clockPadding/2 | |
| ); | |
| &:nth-child(#{$i}){ left: map-get($B, x); top: map-get($B, y); transform: rotate(#{$i * $radius}deg); | |
| @if $i%5 == 0{ | |
| &:before{ width: 3px; height: 7px; left: -1px; } | |
| &:after{ content: "#{$i/5}"; transform: rotate(#{-1 * $i * $radius}deg); } | |
| } | |
| } | |
| } | |
| } | |
| } | |
| &__hands{ width: $handsCircleSize; height: $handsCircleSize; border-radius: 100%; background: #6C5116; box-sizing: border-box; position: absolute; left: 50%; top: 50%; margin-left: -$handsCircleSize/2; margin-top: -$handsCircleSize/2; transform: rotate(180deg); } | |
| &__hand{ transform-origin: top center; background: #000; position: absolute; top: $handsCircleSize/2; transition: transform 0.2s; | |
| &:before{ content: ""; display: block; width: 0; height: 0; position: absolute; } | |
| &:after{ content: ""; display: block; position: absolute; background: #000; } | |
| &--hour{ width: $handHourWidth; height: $handHourLength; left: $handsCircleSize/2 - $handHourWidth/2; | |
| &:before{ bottom: -2 * floor($handHourWidth*0.8) + 2; border: solid transparent; border-width: floor($handHourWidth*0.8) $handHourWidth/2; border-top-color: #000; } | |
| &:after{ width: $handHourWidth; height: $handHourLength/5; top: -$handHourLength/5; } | |
| } | |
| &--minute{ width: $handMinuteWidth; height: $handMinuteLength; left: $handsCircleSize/2 - $handMinuteWidth/2; | |
| &:before{ bottom: -2 * floor($handMinuteWidth*0.8) + 1; border: solid transparent; border-width: floor($handMinuteWidth*0.8) $handMinuteWidth/2; border-top-color: #000; } | |
| &:after{ width: $handMinuteWidth; height: $handMinuteLength/5; top: -$handMinuteLength/5; } | |
| } | |
| &--second{ width: $handSecondWidth; height: $handSecondLength; left: $handsCircleSize/2 - $handSecondWidth/2; | |
| &:before{ top: -$handSecondLength*0.33; border: 0; width: $handSecondWidth + 2; height: $handSecondLength*0.25; background: #000; left: -1px; } | |
| &:after{ width: $handSecondWidth; height: $handSecondLength/5; top: -$handSecondLength/5; } | |
| } | |
| } | |
| } |