├── .gitignore ├── README.md ├── jquery.tinytimer.dev.js ├── jquery.tinytimer.js ├── jquery.tinytimer.min.js └── tinytimer.jquery.json /.gitignore: -------------------------------------------------------------------------------- 1 | /dist 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | jQuery TinyTimer Plugin 2 | ======================= 3 | 4 | TinyTimer is a very simple jQuery plugin that lets you create a countdown (or 5 | countup) timer on a web page. 6 | 7 | Basic Usage 8 | ----------- 9 | 10 | Create a HTML element for your timer somewhere in the page: 11 | 12 | ```html 13 |
14 | Time remaining: 15 |
16 | ``` 17 | 18 | Then, wrap that element in a jQuery object and call its `tinyTimer` method, 19 | passing the date to count to as the `to` option. Here's an example that starts a 20 | 30-minute countdown: 21 | 22 | ```javascript 23 | var d = new Date(); 24 | d.setMinutes(d.getMinutes() + 30); 25 | $('#timer').tinyTimer({ to: d }); 26 | ``` 27 | 28 | To create a timer counting up from a moment in time, use the `from` option 29 | instead of `to`. This produces a timer that shows the number of days since a 30 | specific date: 31 | 32 | ```javascript 33 | var d = new Date('January 1, 2013'); 34 | $('#timer').tinyTimer({ from: d, format: '%d' }); 35 | ``` 36 | 37 | Options 38 | ------- 39 | 40 | - `format` 41 | 42 | The format used to display the date/time. See [Time Format](#time-format) for 43 | details. 44 | 45 | - `from` 46 | 47 | Date/time to count (up) from. Can be a JavaScript Date object or a string 48 | ([IETF-compliant RFC 2822 49 | timestamp](http://tools.ietf.org/html/rfc2822#page-14)). 50 | 51 | - `to` 52 | 53 | Date/time to count (down) to. 54 | 55 | - `onTick` 56 | 57 | Callback function to be invoked on every tick (every second). See 58 | [Callback Functions](#callback-functions) for details. 59 | 60 | - `onEnd` 61 | 62 | Callback function to be invoked when the countdown is over. See 63 | [Callback Functions](#callback-functions) for details. 64 | 65 | 66 | Time Format 67 | ----------- 68 | 69 | The `format` option allows you to define how the time will be displayed. The 70 | different values are represented by tokens composed of a percent sign and a 71 | formatting character: 72 | 73 | - `%d` - days 74 | - `%h` - hours 75 | - `%m` - minutes 76 | - `%s` - seconds 77 | 78 | If the format character is preceded by `0` (e.g., `%0m`), then single-digit 79 | numbers will be displayed with a leading zero (e.g., `04:20` instead of `4:20`). 80 | If it is preceded by `-` (e.g., `%-h`), then the number won't be displayed if it 81 | is zero. The two modifiers can be combined (e.g., `%-0h`). 82 | 83 | The above format characters can also be used in uppercase form, in which case 84 | they represent _total_ quantities. For instance, if the current time is 2 days 85 | and 4 hours, `d` and `h` would be 2 and 4 respectively, while the values of `D` 86 | and `H` would be 2 and 52 (2 * 24 + 4 = 52). 87 | 88 | The format character can also be followed by a suffix, enclosed in curly braces, 89 | to denote the unit of time. You can set different suffixes for singular and 90 | plural form by separating them with `|`. For example, a format setting of `%d 91 | {day|days}` would output the number of days followed by the appropriate form. 92 | 93 | Anything else in the format string will be included in the output as it is. 94 | 95 | A few examples: 96 | - `%-d {day,|days,} %0h {hour|hours}` - 2 days, 07 hours 97 | - `%m minutes and %s seconds` - 12 minutes and 4 seconds 98 | - `%H:%0m:%0s` - 55:12:04 99 | 100 | The default format is `%-H{:}%0m:%0s`, which is the total number of hours (not 101 | displayed if zero), then minutes and seconds, separated by colons. 102 | 103 | 104 | Callback Functions 105 | ------------------ 106 | 107 | The `onTick` and `onEnd` callback functions take one argument, which is an 108 | object that represents the current value of the timer. This object has the 109 | following properties: 110 | 111 | - `s` - seconds 112 | - `m` - minutes 113 | - `h` - hours 114 | - `d` - days 115 | - `S` - total seconds 116 | - `M` - total minutes 117 | - `H` - total hours 118 | - `D` - total days (same as `d`) 119 | - `text` - textual representation of the current time (formatted according to 120 | the `format` option) 121 | 122 | Here's an example of a timer that counts from the time that the page is loaded 123 | and uses the `onTick` callback function to display an alert every minute: 124 | 125 | ```javascript 126 | $('#timer').tinyTimer({ 127 | from: Date.now(), 128 | onTick: function (val) { 129 | if (val.m > 0 && val.s == 0) 130 | alert('You decided to stay on this site for another minute! Yay!'); 131 | } 132 | }); 133 | ``` 134 | 135 | Using with Moment.js 136 | -------------------- 137 | 138 | TinyTimer can be used with the great [Moment.js](http://momentjs.com/) library, 139 | which makes date manipulation much easier than with plain Date objects. You just 140 | need to convert the moment object to `Date` using its `toDate` method before 141 | passing it as `to` or `from`: 142 | 143 | ```javascript 144 | // 30-minute countdown 145 | var m = moment().add('minutes', 30); 146 | $('#timer').tinyTimer({ to: m.toDate() }); 147 | 148 | // Hours since the beginning of the week 149 | var m = moment().startOf('week'); 150 | $('#timer').tinyTimer({ from: m.toDate(), format: '%H' }); 151 | ``` 152 | -------------------------------------------------------------------------------- /jquery.tinytimer.dev.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * tinyTimer jQuery plugin 3 | * version 0.1.4 4 | * 5 | * Copyright (c) 2013 Michal Wojciechowski (odyniec.net) 6 | * 7 | * Dual licensed under the MIT (http://opensource.org/licenses/MIT) 8 | * and GPL (http://opensource.org/licenses/GPL-2.0) licenses. 9 | * 10 | */ 11 | 12 | (function ($) { 13 | 14 | $.tinyTimer = function (options) { 15 | var 16 | /* This instance of tinyTimer */ 17 | tt = this, 18 | 19 | /* The jQuery object or DOM element to display the timer */ 20 | elem = (tt.options = options).element, 21 | 22 | /* Reference time (what we're counting from or counting to) */ 23 | ref = (new Date(options.from || options.to)).getTime(), 24 | 25 | /* Direction (1 when counting up, -1 when counting down) */ 26 | dir = !!options.from||-1, 27 | 28 | /* The function that will be called every second */ 29 | tick, 30 | 31 | /* "Math" is too long to type */ 32 | M = Math, 33 | 34 | /* A function that does nothing, to be used as the default callback */ 35 | doNothing = function () {}; 36 | 37 | tt.interval = setInterval(tick = function () { 38 | /* Don't do anything if the timer is paused */ 39 | if (tt.paused) return; 40 | 41 | /* Calculate the number of seconds from/to the reference time */ 42 | var sec = M.max(M.round((Date.now() - ref) * dir / 1000), 0); 43 | 44 | var val = { 45 | S: sec, /* Total number of seconds */ 46 | s: sec % 60, /* Seconds */ 47 | M: M.floor(sec /= 60), /* Total minutes */ 48 | H: M.floor(sec /= 60), /* Total hours */ 49 | D: M.floor(sec /= 24) /* Total days */ 50 | }; 51 | val.m = val.M % 60; /* Minutes */ 52 | val.h = val.H % 24; /* Hours */ 53 | val.d = val.D; /* Days */ 54 | 55 | /* Format the timer */ 56 | val.text = (options.format || '%-H{:}%0m:%0s').replace( 57 | /%(-?)(0?)([dhms])(\s*)(?:\{(.+?)\})?/ig, 58 | options.replacer || function (match, omit, zero, part, space, forms) { 59 | /* The value of the selected part */ 60 | var v = val[part]; 61 | 62 | /* 63 | * 'day' -> [ 'day', 'day', 'day' ] 64 | * 'day|days' -> [ 'day', 'days', 'days' ] 65 | */ 66 | (forms = (forms||'').split('|'))[2] = 67 | forms[2] || (forms[1] = forms[1] || forms[0]); 68 | 69 | /* 70 | * Return the output text, or an empty string if the value is 71 | * zero and isn't supposed to be shown 72 | */ 73 | return !v && omit ? '' : 74 | /* 75 | * Initialize the output text with the value (and optionally 76 | * a leading zero) 77 | */ 78 | (v > 9 ? '' : zero) + v + space + 79 | 80 | /* Add the appropriate form */ 81 | forms[+(v != 1) + 82 | (v != 1 && (v%10 < 2 || v%10 > 4) || 83 | (v > 10 && v < 20))]; 84 | }); 85 | 86 | /* 87 | * If we have an element, put the formatted text inside it 88 | * (otherwise, set "elem" to this instance of tinyTimer, so that it gets 89 | * passed to callbacks) 90 | */ 91 | elem ? $(elem).html(val.text) : elem = tt; 92 | 93 | /* Invoke the onTick callback (if defined) */ 94 | (options.onTick || doNothing).call(elem, tt.val = val); 95 | 96 | /* Did we just count down to zero? */ 97 | if (dir < 0 && !sec) { 98 | /* No more ticking */ 99 | clearInterval(tt.interval); 100 | /* Invoke the onEnd callback (if defined) */ 101 | (options.onEnd || doNothing).call(elem, val); 102 | } 103 | }, 1000); 104 | 105 | /* Do the first tick */ 106 | tick(); 107 | 108 | /* Instance methods */ 109 | 110 | tt.pause = tt.stop = function () { 111 | tt.paused = Date.now(); 112 | }; 113 | 114 | tt.resume = function () { 115 | ref -= (tt.paused - Date.now()) * dir; 116 | tt.paused = 0; 117 | }; 118 | 119 | tt.start = function () { 120 | tt.paused = 0; 121 | }; 122 | }; 123 | 124 | $.fn.tinyTimer = function (options) { 125 | return this.each(function () { 126 | $(this).data('tinyTimer', 127 | new $.tinyTimer($.extend(options, { element: $(this) }))); 128 | }); 129 | }; 130 | 131 | })(jQuery); 132 | -------------------------------------------------------------------------------- /jquery.tinytimer.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * tinyTimer jQuery plugin 3 | * version 0.1.4 4 | * 5 | * Copyright (c) 2013 Michal Wojciechowski (odyniec.net) 6 | * 7 | * Dual licensed under the MIT (http://opensource.org/licenses/MIT) 8 | * and GPL (http://opensource.org/licenses/GPL-2.0) licenses. 9 | * 10 | */ 11 | (function($) { 12 | $.tinyTimer = function(options) { 13 | var tick, tt = this, elem = (tt.options = options).element, ref = new Date(options.from || options.to).getTime(), dir = !!options.from || -1, M = Math, doNothing = function() {}; 14 | tt.interval = setInterval(tick = function() { 15 | if (!tt.paused) { 16 | var sec = M.max(M.round((Date.now() - ref) * dir / 1e3), 0), val = { 17 | S: sec, 18 | s: sec % 60, 19 | M: M.floor(sec /= 60), 20 | H: M.floor(sec /= 60), 21 | D: M.floor(sec /= 24) 22 | }; 23 | val.m = val.M % 60, val.h = val.H % 24, val.d = val.D, val.text = (options.format || "%-H{:}%0m:%0s").replace(/%(-?)(0?)([dhms])(\s*)(?:\{(.+?)\})?/gi, options.replacer || function(match, omit, zero, part, space, forms) { 24 | var v = val[part]; 25 | return (forms = (forms || "").split("|"))[2] = forms[2] || (forms[1] = forms[1] || forms[0]), 26 | !v && omit ? "" : (v > 9 ? "" : zero) + v + space + forms[+(1 != v) + (1 != v && (2 > v % 10 || v % 10 > 4) || v > 10 && 20 > v)]; 27 | }), elem ? $(elem).html(val.text) : elem = tt, (options.onTick || doNothing).call(elem, tt.val = val), 28 | 0 > dir && !sec && (clearInterval(tt.interval), (options.onEnd || doNothing).call(elem, val)); 29 | } 30 | }, 1e3), tick(), tt.pause = tt.stop = function() { 31 | tt.paused = Date.now(); 32 | }, tt.resume = function() { 33 | ref -= (tt.paused - Date.now()) * dir, tt.paused = 0; 34 | }, tt.start = function() { 35 | tt.paused = 0; 36 | }; 37 | }, $.fn.tinyTimer = function(options) { 38 | return this.each(function() { 39 | $(this).data("tinyTimer", new $.tinyTimer($.extend(options, { 40 | element: $(this) 41 | }))); 42 | }); 43 | }; 44 | })(jQuery); -------------------------------------------------------------------------------- /jquery.tinytimer.min.js: -------------------------------------------------------------------------------- 1 | /*! tinytimer 0.1.4 */ (function(t){t.tinyTimer=function(e){var n,a=this,i=(a.options=e).element,o=new Date(e.from||e.to).getTime(),r=!!e.from||-1,u=Math,s=function(){};a.interval=setInterval(n=function(){if(!a.paused){var n=u.max(u.round((Date.now()-o)*r/1e3),0),l={S:n,s:n%60,M:u.floor(n/=60),H:u.floor(n/=60),D:u.floor(n/=24)};l.m=l.M%60,l.h=l.H%24,l.d=l.D,l.text=(e.format||"%-H{:}%0m:%0s").replace(/%(-?)(0?)([dhms])(\s*)(?:\{(.+?)\})?/gi,e.replacer||function(t,e,n,a,i,o){var r=l[a];return(o=(o||"").split("|"))[2]=o[2]||(o[1]=o[1]||o[0]),!r&&e?"":(r>9?"":n)+r+i+o[+(1!=r)+(1!=r&&(2>r%10||r%10>4)||r>10&&20>r)]}),i?t(i).html(l.text):i=a,(e.onTick||s).call(i,a.val=l),0>r&&!n&&(clearInterval(a.interval),(e.onEnd||s).call(i,l))}},1e3),n(),a.pause=a.stop=function(){a.paused=Date.now()},a.resume=function(){o-=(a.paused-Date.now())*r,a.paused=0},a.start=function(){a.paused=0}},t.fn.tinyTimer=function(e){return this.each(function(){t(this).data("tinyTimer",new t.tinyTimer(t.extend(e,{element:t(this)})))})}})(jQuery); -------------------------------------------------------------------------------- /tinytimer.jquery.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tinytimer", 3 | "title": "TinyTimer", 4 | "version": "0.1.4", 5 | "description": "TinyTimer is a very simple plugin that lets you create a countdown (or countup) timer on a web page.", 6 | "keywords": [ "timer", "countdown", "clock" ], 7 | "author": { 8 | "name": "Michał Wojciechowski", 9 | "email": "odyniec@odyniec.net", 10 | "url": "http://odyniec.net/" 11 | }, 12 | "licenses": [ 13 | { 14 | "type": "GPL-2.0", 15 | "url": "http://opensource.org/licenses/GPL-2.0" 16 | }, 17 | { 18 | "type": "MIT", 19 | "url": "http://opensource.org/licenses/MIT" 20 | } 21 | ], 22 | "dependencies": { 23 | "jquery": ">=1.7" 24 | } 25 | } --------------------------------------------------------------------------------