Skip to content

Instantly share code, notes, and snippets.

@ianchanning
Last active May 8, 2016 07:51
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save ianchanning/5c11595627b1dde957de to your computer and use it in GitHub Desktop.
Save ianchanning/5c11595627b1dde957de to your computer and use it in GitHub Desktop.
jQuery timer function
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>chker</title>
<link type="text/css" href="style.css" rel="stylesheet" />
</head>
<body>
<div id="chker" class="chker">
<p>
<span class="day">00</span> <!-- <span class="hr">00</span>: --><span class="min">25</span>:<span class="sec">00</span><!-- .<span class="hsec">00</span> -->
</p>
<hr>
<div>
<a href="#" class="start button gray">Start</a>
<a href="#" class="stop button gray">Stop</a>
</div>
</div>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.11.3.min.js"></script>
<script type="text/javascript" src="jquery.chk.js"></script>
<script type="text/javascript" src="jquery.chker.js"></script>
<script type="text/javascript">
$(function(){
$('#chker').chker();
var checkToggle = function(stopButton, startButton) {
return $('#chker').hasClass('ticking') ? stopButton : startButton;
};
var myToggle = function(myButton) {
myButton.click().focus().toggleClass('button-activated');
};
var myActive = function(myButton) {
myButton.toggleClass('button-activated');
};
$(document).keydown(function(event) {
if (event.keyCode == '32') { // space bar
event.preventDefault(); // the default being scroll the page down
myActive(checkToggle($('#chker .stop'), $('#chker .start')));
}
});
$(document).keyup(function(event) {
if (event.keyCode == '32') { // space bar
event.preventDefault();
myToggle(checkToggle($('#chker .stop'), $('#chker .start')));
}
});
});
</script>
</body>
</html>
(function($) {
/**
* A general object for ticking a set of values up or down
*
* Each tick is done on a unit (e.g. hour / minute / second)
* And compared against all the fractions of the unit e.g. seconds are fractions of a minte
* Short for chained tick I think of it as 'chuck' rather than 'check', i.e. 'chuck up'
* Also see: @link https://en.wikipedia.org/wiki/!!!
*
* This code was based off https://github.com/kellishaver/stopwatch but pretty much all that is left of that are the zeroPad and hand functions
*/
jQuery.fn.chk = function() {
/**
* The checkSum to see if the current unit should tick up or down
*
* This is the magic to allow all the chaining
* It means that a larger unit will only tick when all smaller factions have just 'ticked'
* Going up we know that all the values have ticked if they are zero
* Going down we know that all the values have ticked if they are one less than the limit e.g. 59 seconds
* The default of null means always tick
* @type Number
*/
this.checkSum = null;
/**
* Stopwatch style tick up
* @param Object unitElement jQuery element
* @param Number limit The count at which to overflow and cycle back
* @return this Allow for chaining
*/
this.up = function(unitElement, limit) {
/**
* What to set the value to when it overflows the limit
* @type Number
*/
var overflow = 0;
var newHand = this.countUp(this.hand(unitElement), this.checkSum, limit, overflow);
this.update(unitElement, newHand, overflow);
return this;
};
/**
* Tick up
* @param Number unit The current value
* @param Number checkSum Whether to tick this value up by one
* @param Number limit The count of how many units e.g. (gone in) 60 seconds
* @param Number overflow Where to go when you're over the limit (avoiding jail)
* @return Number The ticked unit - this will be the same as unit unless the checkSum is zero
*/
this.countUp = function(unit, checkSum, limit, overflow) {
if (this.check(checkSum)) {
unit++;
}
if (unit >= limit) {
return overflow;
}
return unit;
};
/**
* Timer style tick down
* @param Object unitElement jQuery element
* @param Number limit The count at which to overflow and cycle back
* @return this Allow for chaining
*/
this.down = function(unitElement, limit) {
/**
* What to set the value to when it overflows the limit
* @type Number
*/
var overflow = limit - 1;
var newHand = this.countDown(this.hand(unitElement), this.checkSum, limit, overflow);
this.update(unitElement, newHand, overflow);
return this;
};
/**
* Tick down
* @param Number unit The current value
* @param Number checkSum Whether to tick this value up by one
* @param Number limit The count of how many units e.g. (gone in) 60 seconds
* @param Number overflow Where to go when you're over the limit (avoiding jail)
* @return Number The ticked unit - this will be the same as unit unless the checkSum is zero
*/
this.countDown = function(unit, checkSum, limit, overflow) {
// allow people to set the limit to zero as that makes more sense
if (overflow < 0) {
overflow = 0;
}
if (this.check(checkSum)) {
unit--;
}
if (unit < 0) {
return overflow;
}
return unit;
};
this.check = function(checkSum) {
return typeof(checkSum) === undefined || checkSum === null || checkSum === 0;
};
this.update = function(unitElement, newHand, overflow) {
unitElement.html(this.zeroPad(newHand));
// this here is the bit that makes it all tick
this.checkSum += (newHand - overflow);
};
/**
* Pad numbers with a single zero for printing
*
* @todo This needs to be more generic based on the limit e.g. handling 1000ths of a second
* @param Number newHand The new value to print
* @return String 01, ..., 09, 10, ...
*/
this.zeroPad = function (newHand) {
return "0".substring(newHand >= 10) + newHand;
};
/**
* The value of one of the clock 'hands'
*
* The meaning doesn't apply if you're using values that aren't hours / minutes / seconds
* But it's just getting the value for the current unit
* Oh just fork it and call it what ever you want
* Talk to the hand
* @param Object unitElement jQuery element
* @return Number The integer value
*/
this.hand = function(unitElement) {
// parseInt() doesn't work here...
return parseFloat(unitElement.text());
};
return this;
};
})(jQuery);
(function($) {
jQuery.fn.chker = function() {
var timer = $(this);
var timerId = 0;
var tickInterval = 1000;
var dd = timer.find('.day');
var hh = timer.find('.hr');
var mm = timer.find('.min');
var ss = timer.find('.sec');
var hs = timer.find('.hsec');
var start = timer.find('.start');
var stop = timer.find('.stop');
start.click(function() {
// prevent spamming the link
if (timerId === 0) {
timerId = setInterval(chkIt, tickInterval);
timer.addClass('ticking');
}
});
stop.click(function() {
clearInterval(timerId);
timerId = 0;
timer.removeClass('ticking');
});
var chkIt = function() {
// rubiks cube stopwatch (tickInterval = 10)
// chk.init().up(hs, 100).up(ss, 60);
// 100/th second year (tickInterval = 10)
// chk.init().up(hs, 100).up(ss, 60).up(mm, 60).up(hh, 24).up(dd, 365);
// egg timer
// chk.init().down(ss, 60).down(mm, 5);
// t-minus 10, 9, 8, ...
// chk.init().down(ss, 10).down(mm, 0);
// pomodoro timer
$(this).chk().down(ss, 60).down(mm, 25).up(dd, 100);
document.title = timer.find('p').text();
};
};
})(jQuery);
/* reset.css */
html,body,div,span,applet,object,iframe, h1,h2,h3,h4,h5,h6,p,blockquote,pre, a,abbr,acronym,address,big,cite,code, del,dfn,em,font,img,ins,kbd,q,s,samp, small,strike,strong,sub,sup,tt,var, dl,dt,dd,ol,ul,li, fieldset,form,label,legend, table,caption,tbody,tfoot,thead,tr,th,td{margin:0;padding:0;border:0;font-weight:inherit;font-style:inherit;font-size:100%;font-family:inherit;vertical-align:baseline;}
body{background:white;color:#333;font-family:helvetica,arial,sans-serif;line-height:1;}
/* style.css */
body{background-color:#333;color:#fff;font-family: Consolas, "Courier New";margin:0 auto;text-align:center;width:100%;}
h1 {font-size: 25px}
.chker > p{font-size:500%;}
/* neon */
.chker > p{text-shadow:0 0 1px #fff, 0 0 5px #fff, 0 0 5px #fff, 0 0 10px #ff00de, 0 0 10px #ff00de, 0 0 10px #ff00de, 0 0 20px #ff00de, 0 0 25px #ff00de;}
/**
* @link http://webdesign.tutsplus.com/tutorials/orman-clarks-chunky-3d-web-buttons-the-css3-version--webdesign-5731
*/
a.button {
display: inline-block;
/*float: left;*/
position: relative;
height: 25px;
width: 80px;
margin: 0 10px 18px 0;
text-decoration: none;
font: 12px "Helvetica Neue", Helvetica, Arial, sans-serif;
font-weight: bold;
line-height: 25px;
text-align: center;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
}
a.button:before,
a.button:after {
content: '';
position: absolute;
left: -1px;
height: 25px;
width: 80px;
bottom: -1px;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
}
a.button:before {
height: 23px;
bottom: -4px;
border-top: 0;
-webkit-border-radius: 0 0 3px 3px;
-moz-border-radius: 0 0 3px 3px;
border-radius: 0 0 3px 3px;
-webkit-box-shadow: 0 1px 1px 0px #bfbfbf;
-moz-box-shadow: 0 1px 1px 0px #bfbfbf;
box-shadow: 0 1px 1px 0px #bfbfbf;
}
/* GRAY */
a.gray,
a.gray:hover,
a.gray:visited {
color: #555;
border-bottom: 4px solid #b2b1b1;
text-shadow: 0px 1px 0px #fafafa;
background: #eee;
background: -webkit-gradient(linear, left top, left bottom, from(#eee), to(#e2e2e2));
background: -moz-linear-gradient(top, #eee, #e2e2e2);
box-shadow: inset 1px 1px 0 #f5f5f5;
}
.gray:before,
.gray:after {
border: 1px solid #cbcbcb;
border-bottom: 1px solid #a5a5a5;
}
a.gray:hover {
background: #e2e2e2;
background: -webkit-gradient(linear, left top, left bottom, from(#e2e2e2), to(#eee));
background: -moz-linear-gradient(top, #e2e2e2, #eee);
}
/* ACTIVE STATE */
a.button:active, a.button-activated {
border: none;
bottom: -4px;
margin-bottom: 22px;
-webkit-box-shadow: 0 1px 1px #fff;
-moz-box-shadow: 0 1px 1px #fff;
box-shadow: 1px 1px 0 #fff, inset 0 1px 1px rgba(0, 0, 0, 0.3);
}
a.button:active:before,
a.button:active:after,
a.button-activated:before,
a.button-activated:after {
border: none;
-webkit-box-shadow: none;
-moz-box-shadow: none;
box-shadow: none;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment