Forked from Larry Williamson's Pen Countdown Rings.
A Pen by Andreas Gehrke on CodePen.
| <div id="canvastimer" | |
| class="count-down" | |
| data-timeend="Fri Dec 31 2016 23:59:59 GMT+0100 (CET) | |
| "> | |
| </div> | |
| <div id="canvastimer1" | |
| class="count-down" | |
| data-timeend="Fri Dec 30 2016 23:59:59 GMT+0100 (CET) | |
| "> | |
| </div> | |
Forked from Larry Williamson's Pen Countdown Rings.
A Pen by Andreas Gehrke on CodePen.
| function createRinger() { | |
| // This needs to be defined to allow scoping. Otherwise it would be a global variable used by all instances of ringer. | |
| // I would recommend to rewrite the ringer object using a more object-oriented approach, | |
| // e.g. class or similar where all state is encapsulated inside object itself, and not relay on javascript closures and scoping for the $r varible to work. | |
| var $r = null; | |
| return { | |
| countdown_to:"", | |
| rings: { | |
| 'Dage': { | |
| s: 86400000, // mseconds in a day, | |
| max: 14 | |
| }, | |
| 'Timer': { | |
| s: 3600000, // mseconds per hour, | |
| max: 24 | |
| }, | |
| 'Minutter': { | |
| s: 60000, // mseconds per minute | |
| max: 60 | |
| }, | |
| 'Sekunder': { | |
| s: 1000, | |
| max: 60 | |
| }, | |
| 'MICROSEC': { | |
| s: 10, | |
| max: 100 | |
| } | |
| }, | |
| r_count: 4, | |
| r_spacing: 30, // px | |
| r_size: 140, // px | |
| r_thickness: 4, // px | |
| update_interval: 1000, // ms | |
| init: function(element){ | |
| $r = this; | |
| $r.countdown_to = $(element).data("timeend"); | |
| $r.cvs = document.createElement('canvas'); | |
| $r.size = { | |
| w: ($r.r_size + $r.r_thickness) * $r.r_count + ($r.r_spacing*($r.r_count-1)), | |
| h: ($r.r_size + $r.r_thickness) | |
| }; | |
| //added devicePixelRatio for retina screens | |
| $r.cvs.setAttribute('width',$r.size.w * window.devicePixelRatio); | |
| $r.cvs.setAttribute('height',$r.size.h * window.devicePixelRatio); | |
| $r.ctx = $r.cvs.getContext('2d'); | |
| //*1 multiply for non-retinas | |
| $r.ctx.scale(window.devicePixelRatio, window.devicePixelRatio); | |
| $(element).append($r.cvs); | |
| $r.cvs = $($r.cvs); | |
| $r.ctx.textAlign = 'center'; | |
| $r.actual_size = $r.r_size + $r.r_thickness; | |
| $r.countdown_to_time = new Date($r.countdown_to).getTime(); | |
| $r.cvs.css({ width: $r.size.w+"px", height: $r.size.h+"px" }); | |
| setInterval($r.go,$r.update_interval); | |
| $r.go(); | |
| }, | |
| ctx: null, | |
| go: function(){ | |
| var idx=0; | |
| $r.time = (new Date().getTime()) - $r.countdown_to_time; | |
| for(var r_key in $r.rings) $r.unit(idx++,r_key,$r.rings[r_key]); | |
| }, | |
| unit: function(idx,label,ring) { | |
| var x,y, value, ring_secs = ring.s; | |
| value = parseFloat($r.time/ring_secs); | |
| $r.time-=Math.round(parseInt(value)) * ring_secs; | |
| value = Math.abs(value); | |
| x = ($r.r_size*.5 + $r.r_thickness*.5); | |
| x +=+(idx*($r.r_size+$r.r_spacing+$r.r_thickness)); | |
| y = $r.r_size*.5; | |
| y += $r.r_thickness*.5; | |
| // calculate arc end angle | |
| //console.log(value); | |
| if (value < 1){ | |
| value = 0; | |
| } | |
| var degrees = 270-(value / ring.max) * 360.0; | |
| var endAngle = degrees * (Math.PI / 180); | |
| $r.ctx.save(); | |
| $r.ctx.translate(x,y); | |
| $r.ctx.clearRect($r.actual_size*-0.5,$r.actual_size*-0.5,$r.actual_size,$r.actual_size); | |
| // first circle | |
| $r.ctx.strokeStyle = "#efefef"; | |
| $r.ctx.beginPath(); | |
| $r.ctx.arc(0,0,$r.r_size/2,1.5*Math.PI,-0.5*Math.PI, 1); | |
| $r.ctx.lineWidth =$r.r_thickness; | |
| $r.ctx.stroke(); | |
| // second circle | |
| $r.ctx.strokeStyle = "#009890"; | |
| $r.ctx.beginPath(); | |
| $r.ctx.arc(0,0,$r.r_size/2,1.5*Math.PI,endAngle, 1); | |
| $r.ctx.lineWidth =$r.r_thickness; | |
| $r.ctx.stroke(); | |
| // label | |
| $r.ctx.fillStyle = "#999"; | |
| $r.ctx.font = '200 14px sans-serif'; | |
| $r.ctx.fillText(label, 0, 34); | |
| $r.ctx.font = '200 38px sans-serif'; | |
| $r.ctx.fillStyle = "#000"; | |
| $r.ctx.fillText(Math.floor(value), 0, 8); | |
| $r.ctx.restore(); | |
| } | |
| }; | |
| } | |
| var $getCountsWrapper = $(".count-down"); | |
| $getCountsWrapper.each(function( index ) { | |
| var ringer = createRinger(); | |
| ringer.init(this); | |
| }); |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script> |
| #canvastimer{ | |
| margin:50px; | |
| } |