Skip to content

Instantly share code, notes, and snippets.

@jocubeit
Created March 18, 2019 02:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jocubeit/68ddbf322785f61c4f09b973e6112c55 to your computer and use it in GitHub Desktop.
Save jocubeit/68ddbf322785f61c4f09b973e6112c55 to your computer and use it in GitHub Desktop.
Circular Calendar Display

Circular Calendar Display

A circular calendar and clock display, with and added weather and daily activity widget mock-ups.

A Pen by Matthew Juggins on CodePen.

License.

.center-dial
%h1{:class => "center-preview"} HELLO
.head
.torso
.hand-container#minutes
.minute-hand
.hand-container#hours
.hour-hand
.hand-container#seconds
.second-hand
.day-name-dial
.ring-back
.ring#r1
%h1{:class => "day-name-preview"} DAY NAME
%h2{:class => "day-name-text"} MON TUE WED THU FRI SAT SUN
.month-dial
.ring-back
.ring#r2
%h1{:class => "month-preview"} MONTH
%h2{:class => "month-text"} JAN FEB MAR APR MAY JUN JUL AUG SEP OCT NOV DEC
.day-dial
.ring-back
.ring#r3
%h1{:class => "day-preview"} DAY
%h2{:class => "day-text"} 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
.side-ring#weather
.fa.fa-cloud
%p{:class => "temperature"} 14&#176C
.side-ring#steps
.bars
.bar
.day-letter M
.x#x1
.bar
.day-letter T
.x#x2
.bar
.day-letter W
.x#x3
.bar
.day-letter T
.x#x4
.bar
.day-letter F
.x#x5
.bar
.day-letter S
.x#x6
.bar
.day-letter S
.x#x7
/*
* Cirulcar Calendar Display.js
* Matthew Juggins
* Change log:
* 25/09/16 - Quick fix to day of the week
*/
$(function() {
var date, dayName, day, month, year;
var range = 270,
sectionsDayName = 7,
sectionsDay = 31,
sectionsMonth = 12,
charactersDayName = 3,
charactersDay = 2,
charactersMonth = 3,
dayColor = '#FF2D55',
monthColor = '#007AFF',
dayNameColor = '#4CD964';
// Rotate the selected ring the correct amount and illuminate the correct characters of the ring text
function rotateRing(input, sections, characters, ring, text, color) {
var sectionWidth = range / sections;
var initialRotation = 135 - (sectionWidth / 2);
var rotateAmount = initialRotation - sectionWidth * (input - 1);
var start = (characters * (input - 1)) + (input - 1) + 1;
$(ring).css({
'-webkit-transform': 'rotate(' + rotateAmount + 'deg)',
'-moz-transform': 'rotate(' + rotateAmount + 'deg)',
'-ms-transform': 'rotate(' + rotateAmount + 'deg)',
'transform': 'rotate(' + rotateAmount + 'deg)'
});
for (var i = start; i < start + characters; i++) {
$(text).children('.char' + i).css({
'color': color
});
}
}
// Get a new date object every second and update the rotation of the clock handles
function clockRotation() {
setInterval(function() {
var date = new Date();
var seconds = date.getSeconds();
var minutes = date.getMinutes();
var hours = date.getHours();
var secondsRotation = seconds * 6;
var minutesRotation = minutes * 6;
var hoursRotation = hours * 30 + (minutes / 2);
$("#seconds").css({
'-webkit-transform': 'rotate(' + secondsRotation + 'deg)',
'-moz-transform': 'rotate(' + secondsRotation + 'deg)',
'-ms-transform': 'rotate(' + secondsRotation + 'deg)',
'transform': 'rotate(' + secondsRotation + 'deg)'
});
$("#minutes").css({
'-webkit-transform': 'rotate(' + minutesRotation + 'deg)',
'-moz-transform': 'rotate(' + minutesRotation + 'deg)',
'-ms-transform': 'rotate(' + minutesRotation + 'deg)',
'transform': 'rotate(' + minutesRotation + 'deg)'
});
$("#hours").css({
'-webkit-transform': 'rotate(' + hoursRotation + 'deg)',
'-moz-transform': 'rotate(' + hoursRotation + 'deg)',
'-ms-transform': 'rotate(' + hoursRotation + 'deg)',
'transform': 'rotate(' + hoursRotation + 'deg)'
});
}, 1000);
}
// Give column representing passed days and the current day this week a height
function loadBars() {
for(var i = 1; i <= dayName; i++){
var newHeight = (Math.floor(Math.random() * 85) + 5);
var newTop = 110 - newHeight;
$("#x"+i).css({
'height' : newHeight + 'px',
});
}
}
function init() {
$(".center-preview").lettering();
$(".day-name-preview").lettering();
$(".day-name-text").lettering();
$(".day-preview").lettering();
$(".day-text").lettering();
$(".month-preview").lettering();
$(".month-text").lettering();
$('.day-preview').fadeTo(10, 1);
$('.month-preview').fadeTo(10, 1);
$('.day-name-preview').fadeTo(10, 1);
$('.center-preview').fadeTo(10, 1);
// Get date variables
date = new Date();
dayName = date.getDay(); // Day of week (1-7)
day = date.getDate(); // Get current date (1-31)
month = date.getMonth() + 1; // Current month (1-12)
if (dayName == 0) {
dayName = 7;
}
// Fade in/out second dial and rotate. Also fade in and animate side elements.
setTimeout(function() {
$('.day-preview').fadeTo(500, 0);
$('.day-text').fadeTo(500, 1, function() {
rotateRing(day, sectionsDay, charactersDay, '#r3', '.day-text', dayColor);
});
}, 500);
// Fade in/out second dial and rotate. Also fade in and animate side elements.
setTimeout(function() {
$('.month-preview').fadeTo(500, 0);
$('.fa-cloud').fadeTo(500, 1);
$('.temperature').fadeTo(500, 1);
$('.bars').fadeTo(500, 1);
$('.month-text').fadeTo(500, 1, function() {
rotateRing(month, sectionsMonth, charactersMonth, '#r2', '.month-text', monthColor);
loadBars();
});
}, 1000);
// Fade in/out first dial and rotate
setTimeout(function() {
$('.day-name-preview').fadeTo(500, 0);
$('.day-name-text').fadeTo(500, 1, function() {
rotateRing(dayName, sectionsDayName, charactersDayName, '#r1', '.day-name-text', dayNameColor);
});
}, 1500);
// Fade in/out center dial
setTimeout(function() {
$('.center-preview').fadeTo(500, 0);
$('.head').fadeTo(500, 0);
$('.torso').fadeTo(500, 0);
$(".hand-container").fadeTo(500, 1, function() {
//console.log("Clock faded in");
});
}, 2000);
// Begin clock rotation now it is visible
clockRotation();
}
init();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/lettering.js/0.6.1/jquery.lettering.min.js"></script>
// VARIABLES
$background-grey: #292929;
$ring-back: #FFFFFF;
$ring-preview-characters: 6;
$bar-colors: #FF3B30, #FF9500, #FFCC00, #4CD964, #5AC8FA, #007AFF, #5856D6;
$center-dial-size: 150px;
$day-name-size: 250px;
$month-size: 350px;
$day-size: 450px;
$h1-size: 25px;
$h2-size: 12px;
$side-ring-size: 200px;
// MIXINS
@mixin position($position, $top: null, $right: null, $bottom: null, $left: null) {
position: $position;
top: $top;
right: $right;
bottom: $bottom;
left: $left;
}
@mixin absolute($args...) {
@include position(absolute, $args...);
}
@mixin relative($args...) {
@include position(relative, $args...);
}
@mixin fixed($args...) {
@include position(fixed, $args...);
}
@mixin opacity($opacity) {
opacity: $opacity;
$opacity-ie: $opacity * 100;
filter: alpha(opacity=$opacity-ie); //IE8
}
@mixin size($width, $height: $width) {
width: $width;
height: $height;
}
@mixin transition($args...) {
-webkit-transition: $args;
-moz-transition: $args;
-ms-transition: $args;
-o-transition: $args;
transition: $args;
}
@mixin transition-delay($delay) {
-webkit-transition-delay: $delay;
-moz-transition-delay: $delay;
-ms-transition-delay: $delay;
-o-transition-delay: $delay;
transition-delay: $delay;
}
@mixin transform($transforms) {
-moz-transform: $transforms;
-o-transform: $transforms;
-ms-transform: $transforms;
-webkit-transform: $transforms;
transform: $transforms;
}
@mixin transform-origin ($origin) {
moz-transform-origin: $origin;
-o-transform-origin: $origin;
-ms-transform-origin: $origin;
-webkit-transform-origin: $origin;
transform-origin: $origin;
}
@mixin rotated-text($num-letters: 100, $angle-span: 180deg, $angle-offset: 0deg) {
$angle-per-char: $angle-span / $num-letters;
@for $i from 1 through $num-letters {
.char#{$i} {
@include transform(rotate($angle-offset + $angle-per-char * $i));
}
}
}
// LOOPS
@each $current-color in $bar-colors {
$i: index($bar-colors, $current-color);
#x#{$i} {
background: $current-color;
}
}
@for $i from 1 to 8 {
.bar:nth-child(#{$i}) {
@include absolute($top: 0px, $left: 20px * ($i - 1));
}
}
// PLACEHOLDERS
%center {
@include absolute($top: 50%, $left: 50%);
transform: translateX(-50%) translateY(-50%);
}
%center-inside {
@include relative($top: 50%, $left: 50%);
transform: translateX(-50%) translateY(-50%);
}
%ring-text {
text-align: center;
@include transform-origin(center center);
}
// TYPICAL ELEMENTS
* {
box-sizing: border-box;
}
html,
body {
background: $background-grey;
border: 0;
font-family: 'Roboto Mono', monospace;
height: 100%;
margin: 0px;
width: 100%;
}
h1 {
color: #555;
font-size: 25px;
}
h2{
color: #555;
font-size: 15px;
}
// CLASSES AND IDS IN ORDER OF APPEARANCE IN HTML
.center-dial {
@include absolute($top: calc(50% - 75px), $left: calc(50% - 75px));
@include transition(all .5s);
@include size($center-dial-size);
background-color: #202020;
border-radius: 50%; color: #000;
box-shadow: 0px 2px 2px #000;
cursor: pointer;
overflow: hidden;
}
.center-preview span {
@extend %ring-text;
@include absolute($top: 0%, $left: calc(50% - 12.5px));
height: $center-dial-size;
width: $h1-size;
}
.center-preview {
@include opacity(0);
@include rotated-text($num-letters: 6, $angle-span: 120deg, $angle-offset: -60deg);
}
.head {
@extend %center-inside;
@include size(50px, 50px);
background: #FFF;
border-radius: 50%;
}
.torso {
@include relative($top: calc(50% - 20px), $left: calc(50% - 50px));
@include size(100px, 100px);
background: #FFF;
border-radius: 50%;
}
.hand-container {
@extend %ring-text;
@include absolute($top: 0%, $left: calc(50% - 12.5px));
@include opacity(0);
@include size($h1-size, $center-dial-size);
@include transform-origin(center center);
}
.hour-hand {
@include size(10px, 50px);
@include relative($top: calc(50% - 45px), $left: calc(50% - 5px));
@include transition(all .5s);
background: #FFF;
border-radius: 5px;
}
.minute-hand {
@include size(10px, 70px);
@include relative($top: calc(50% - 65px), $left: calc(50% - 5px));
background: #CCC;
border-radius: 5px;
}
.second-hand {
@include size(2px, 70px);
@include relative($top: calc(50% - 69px), $left: calc(50% - 1px));
background: #AAA;
border-radius: 1px;
}
.day-name-dial {
@extend %center;
@include size($day-name-size);
@include transition(all .5s);
}
.day-name-preview span {
@extend %ring-text;
@include absolute($top: calc(-25% - 5px), $left: calc(50% - 12.5px));
height: $day-name-size;
width: $h1-size;
}
.day-name-preview {
@include opacity(0);
@include rotated-text($num-letters: 9, $angle-span: 90deg, $angle-offset: -45deg);
}
.day-name-text span {
@extend %ring-text;
@include absolute($top: calc(-25% + 5px), $left: calc(50% - 6px));
height: 232px;
width: $h2-size;
}
.day-name-text {
@include opacity(0);
@include rotated-text($num-letters: 28, $angle-span: 270deg, $angle-offset: -135deg);
}
.month-dial {
@extend %center;
@include size($month-size);
@include transition(all .5s);
}
.month-preview span {
@extend %ring-text;
@include absolute($top: calc(-25% + 20px), $left: calc(50% - 12.5px));
height: $month-size;
width: $h1-size;
}
.month-preview{
@include opacity(0);
@include rotated-text($num-letters: 6, $angle-span: 90deg, $angle-offset: -45deg);
}
.month-text span {
@extend %ring-text;
@include absolute($top: calc(-25% + 30px), $left: calc(50% - 6px));
height: 332px;
width: $h2-size;
}
.month-text{
@include opacity(0);
@include rotated-text($num-letters: 48, $angle-span: 270deg, $angle-offset: -135deg);
}
.day-dial {
@extend %center;
@include size(450px, 450px);
@include transition(all .5s);
}
.day-preview span {
@extend %ring-text;
@include absolute($top: calc(-25% + 45px), $left: calc(50% - 12.5px));
height: $day-size;
width: $h1-size;
}
.day-preview{
@include opacity(0);
@include rotated-text($num-letters: 4, $angle-span: 90deg, $angle-offset: -45deg);
}
.day-text span {
@extend %ring-text;
@include absolute($top: calc(-25% + 55px), $left: calc(50% - 6px));
height: 432px;
width: $h2-size;
}
.day-text{
@include opacity(0);
@include rotated-text($num-letters: 93, $angle-span: 270deg, $angle-offset: -135deg);
}
.ring-back {
@include opacity(.1);
@include size(100%, 100%);
border: solid 10px transparent;
border-radius: 50%;
&:before {
@include absolute($top: 5px, $left: 5px, $bottom: 5px, $right: 5px);
border-radius: 50%;
border: solid 35px $ring-back;
content: " ";
}
}
.ring {
@include relative($top: -100%);
@include size(100%, 100%);
@include transition(all .5s);
border: solid 45px #202020;
border-radius: 50%;
border-bottom-color: transparent;
box-shadow: 0px -2px 2px #000;
}
.side-ring {
@include transition(all .5s);
@include size($side-ring-size);
background-color: #202020;
border-radius: 50%;
box-shadow: 0px 2px 2px #000;
color: #000;
overflow: hidden;
}
#weather {
@include absolute($top: calc(50% - 100px), $left: calc(20% - 100px));
}
#steps {
@include absolute($top: calc(50% - 100px), $left: calc(80% - 100px));
}
.fa-cloud {
@include opacity(0);
@include absolute($top: calc(50% - 40px), $left: calc(50% - 40px));
color: #555;
font-size: 80px;
}
.temperature {
@include opacity(0);
@include absolute($top: 10%, $left: 55%);
color: #FFCC00;
font-size: 20px;
}
.bars {
@include opacity(0);
@include relative($top: calc(50% - 70px), $left: calc(50% - 65px));
@include size(140px, 140px);
}
.bar {
@include size(18px, 140px);
margin: 0px -4px;
}
.day-letter {
@include relative($top: 110px);
color: #555;
font-size: 18px;
text-align: center;
}
.x {
@include absolute($bottom: 30px, $left: 1px);
@include size(16px, 2px);
@include transition (all .5s);
}
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css" rel="stylesheet" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment