Skip to content

Instantly share code, notes, and snippets.

@Maximilianos
Last active December 18, 2015 07:39
Show Gist options
  • Save Maximilianos/5748203 to your computer and use it in GitHub Desktop.
Save Maximilianos/5748203 to your computer and use it in GitHub Desktop.
A CodePen by Max G J Panas. Sun Joo Timer - Customizable Raphael.js Timer based on a Dribble Shot (http://dribbble.com/shots/1102815-Timer) by Sun Joo (@plios_sun).
<figure class="wrap">
<div class="clock-wrap">
<div class="clock">
<div id="clock_hours"></div>
</div>
<div class="ticker" id="ticker_hours"></div>
</div>
<div class="clock-wrap">
<div class="clock">
<div id="clock_minutes"></div>
</div>
<div class="ticker" id="ticker_minutes"></div>
</div>
<div class="clock-wrap">
<div class="clock">
<div id="clock_seconds"></div>
</div>
<div class="ticker" id="ticker_seconds"></div>
</div>
</figure>
<section class="pen-description">
<p>Rebound of <a href="http://dribbble.com/shots/1102815-Timer" target="_blank">a Dribble Shot</a> by <a href="https://twitter.com/plios_sun" target="_blank">@plios_sun</a></p>
<p>HTML, CSS & Js by <a href="https://twitter.com/mgjp_" target="_blank">@mgjp_</a></p>
</section>
/**
* Rebound of A Dribble Shot
* by Sun Joo (@plios_sun)
* http://dribbble.com/shots/1102815-Timer
*
* see the bottom of the js code to see how the custom
* SunJooTimer object is called to create each clock & ticker
*/
//This creates the clock face & hand
var SunJooClock = function(clockElem, animDelay, clockDegrees, tickerTime) {
var size = clockElem.offsetWidth,
sizeHalf = size / 2,
sizeThird = size / 3,
rimRadius = size / 2.22,
rimStart = sizeHalf - rimRadius,
rad = Math.PI / 180,
clock = new Raphael(clockElem, size, size);
function rimPath(deg) {
var a = (90 - deg) * rad,
x = sizeHalf + rimRadius * Math.cos(a),
y = sizeHalf - rimRadius * Math.sin(a);
return ['M', sizeHalf, rimStart, 'A', rimRadius, rimRadius, 0, +(deg > 180), 1, x, y];
}
function pieSlicePath(deg) {
var a = (90 - deg) * rad,
x = sizeHalf + sizeThird * Math.cos(a),
y = sizeHalf - sizeThird * Math.sin(a);
return ['M', sizeHalf, sizeHalf, 'v', -sizeThird, 'A', sizeThird, sizeThird, 0, +(deg > 180), 1, x, y, 'z'];
}
var rim = clock.path(rimPath(0)).attr({
stroke: '#ECECEC',
'stroke-width': size / 25,
opacity: .9
});
var rimShadow = rim.glow({
width: size / 60,
color: '#ececec'
});
var back = clock.path(pieSlicePath(0)).attr({
stroke: '#cdcdcd',
fill: '#D9d6de'
});
var backShadow = back.clone().scale(.9).hide().glow({
width: 8,
color: '#C5C0CC'
});
var handPath = ['M', sizeHalf, size * .48, 'm', size / 20, 0, 'l', -size / 30, -size * .29, 'c', 0, -size / 30, -size / 30, -size / 30, -size / 30, 0, 'l', -size / 30, size * .29, 'c', -size / 100, size * .0933, size * .11, size * .0933, size / 10, 0];
var hand = clock.path(handPath);
hand.attr({
fill: '#F26522',
stroke: '#777',
'stroke-width': 1
});
var handShadow = hand.glow({
opacity: .2,
width: size / 30,
color: 'darkOrange'
});
var first = 0;
function animation_loop(animDelay) {
var check = tickerTime();
var degs = clockDegrees();
var animTime = check ? !first++ ? 300 : animDelay : 0;
var rimsPath = rimPath(degs);
rim.animate({
path: rimsPath
}, animTime);
rimShadow.animate({
path: rimsPath
}, animTime);
var backPath = pieSlicePath(degs);
back.animate({
path: backPath
}, animTime);
backShadow.animate({
path: Raphael.transformPath(backPath, ['s', .9])
}, animTime);
if(!check) {
var backFade = back.clone().toBack().animate({
opacity: 0
}, 700, 'ease-out', function() {
backFade.remove();
});
var rimFade = rim.clone().animate({
opacity: 0
}, 700, 'ease-out', function() {
rimFade.remove();
});
}
var handsPath = Raphael.transformPath(handPath, ['r', degs, sizeHalf, sizeHalf]);
hand.animate({
path: handsPath
}, animTime);
handShadow.animate({
path: handsPath
}, animTime);
setTimeout(function() {
animation_loop(animDelay);
}, animDelay);
}
animation_loop(animDelay);
};
//This creates the ticker underneath the clock
var SunJooTicker = function(tickerElem, animDelay, tickerTime) {
function animation_loop(animDelay) {
//tickerTime is passed a function that determines
//the text in the ticker for each iteration of the
//animation loop. See constructors in window.onload
//below for more.
tickerElem.innerHTML = tickerTime();
setTimeout(function() {
animation_loop(animDelay);
}, animDelay);
}
animation_loop(animDelay);
};
//This just wraps the calls to the clock & ticker objects
//into one call
var SunJooTimer = function(clockElem, tickerElem, animDelay, clockDegrees, tickerTime) {
this.clock = new SunJooClock(clockElem, animDelay, clockDegrees, tickerTime);
this.ticker = new SunJooTicker(tickerElem, animDelay, tickerTime);
};
//create the timers on load
window.onload = function() {
var secondsTimer = new SunJooTimer(
document.getElementById('clock_seconds'),
document.getElementById('ticker_seconds'), 60000 / 360,
function() {
//Custom function gets called each time the animation
//loops. Returns the degrees the clock should be at at
//each iteration of the loop. You can change this to
//whatever you want so long as they return a number
//between 0 - 360
var date = new Date();
return date.getSeconds() / 60 * 360
+ date.getMilliseconds() / 1000 * 6; //1s = 6deg
}, function() {
//This function gets called both by the clock object
//and by the ticker object on each animation loop.
//In the former to determine whether the clock has
//done a full loop, in the latter to output the text
//displayed by the ticker.
return new Date().getSeconds();
});
var minutesTimer = new SunJooTimer(
document.getElementById('clock_minutes'),
document.getElementById('ticker_minutes'), 60000 / 360,
function() {
var date = new Date();
return date.getMinutes() / 60 * 360
+ date.getSeconds() / 60 * 6; //1m = 6deg
}, function() {
return new Date().getMinutes();
});
var hoursTimer = new SunJooTimer(
document.getElementById('clock_hours'),
document.getElementById('ticker_hours'), 60000 / 360,
function() {
var date = new Date();
return date.getHours() / 24 * 360
+ date.getMinutes() / 60 * 15; //1h = 15deg
}, function() {
return new Date().getHours();
});
};
@import "compass";
/** Sun Joo Timer Css Styles ** by Max G J Panas */
$circleSize: 150px; /* << Try Changing this! */
.wrap {
display: inline-block;
}
.clock-wrap {
float: left;
width: $circleSize;
margin: 0 $circleSize / 7;
}
.clock {
position: relative;
box-sizing: border-box;
height: $circleSize;
width: $circleSize;
border: 3px solid #fbfbfb;
border-radius: 50%;
background-image: linear-gradient(bottom, rgb(194,187,200) 100%, rgb(170,168,189) 0%);
background-image: -o-linear-gradient(bottom, rgb(194,187,200) 100%, rgb(170,168,189) 0%);
background-image: -moz-linear-gradient(bottom, rgb(194,187,200) 100%, rgb(170,168,189) 0%);
background-image: -webkit-linear-gradient(bottom, rgb(194,187,200) 100%, rgb(170,168,189) 0%);
background-image: -ms-linear-gradient(bottom, rgb(194,187,200) 100%, rgb(170,168,189) 0%);
background-image: -webkit-gradient(linear, left bottom, left top, color-stop(1, rgb(194,187,200)), color-stop(0, rgb(170,168,189)));
box-shadow: inset 0 0 15px rgba(0,0,0,.3);
&:before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: auto;
box-sizing: border-box;
height: $circleSize / 1.28;
width: $circleSize / 1.28;
border: 2px solid #fff;
border-radius: 50%;
background-image: linear-gradient(bottom, rgb(255,255,255) 0%, rgb(237,236,242) 100%);
background-image: -o-linear-gradient(bottom, rgb(255,255,255) 0%, rgb(237,236,242) 100%);
background-image: -moz-linear-gradient(bottom, rgb(255,255,255) 0%, rgb(237,236,242) 100%);
background-image: -webkit-linear-gradient(bottom, rgb(255,255,255) 0%, rgb(237,236,242) 100%);
background-image: -ms-linear-gradient(bottom, rgb(255,255,255) 0%, rgb(237,236,242) 100%);
background-image: -webkit-gradient(linear,left bottom,left top,color-stop(0, rgb(255,255,255)),color-stop(1, rgb(237,236,242)));
box-shadow: 0 0 15px rgba(0,0,0,.3);
}
}
.ticker {
padding: .4em 0;
font-family: 'Arial', sans-serif;
font-size: 2.3em;
color: #C1BFCE;
text-shadow: 0 0 .1em #fff,
0 0 .2em #fff,
0 0 .2em #fff;
}
/** General Pen Styles */
html, body {
height: 99.3%;
background-image: -webkit-gradient(linear, 0 100%, 0 0, from(rgb(216,215,221)), to(rgb(236,236,238)));
background-image: -webkit-linear-gradient(bottom, rgb(216,215,221) 0%, rgb(236,236,238) 100%);
background-image: -moz-linear-gradient(bottom, rgb(216,215,221) 0%, rgb(236,236,238) 100%);
background-image: -o-linear-gradient(bottom, rgb(216,215,221) 0%, rgb(236,236,238) 100%);
background-image: linear-gradient(bottom, rgb(216,215,221) 0%, rgb(236,236,238) 100%);
text-align: center;
}
.pen-description {
margin-top: 10px;
font-family: arial, sans-serif;
color: #9E9DB0;
text-shadow: 1px 1px 0 #fbfbfb;
}
.pen-description p {
margin: 5px;
}
.pen-description a {
color: #666;
text-decoration: none;
&:hover, &:active, &:focus {
color: #444;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment