D
If you need to create a few timers, you can create a function-fib that will return the object of the timer.function ringerFactory(date) {
let $r;
const ringer = {
//countdown_to: "10/31/2014",
countdown_to: date,
rings: {
'DAYS': {
s: 86400000, // mseconds in a day,
max: 365
},
'HOURS': {
s: 3600000, // mseconds per hour,
max: 24
},
'MINUTES': {
s: 60000, // mseconds per minute
max: 60
},
'SECONDS': {
s: 1000,
max: 60
},
'MICROSEC': {
s: 10,
max: 100
}
},
r_count: 5,
r_spacing: 10, // px
r_size: 100, // px
r_thickness: 2, // px
update_interval: 11, // ms
init: function() {
$r = ringer;
$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)
};
$r.cvs.setAttribute('width', $r.size.w);
$r.cvs.setAttribute('height', $r.size.h);
$r.ctx = $r.cvs.getContext('2d');
$(document.body).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"
});
$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]);
setTimeout($r.go, $r.update_interval);
},
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
var degrees = 360 - (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 = "rgba(128,128,128,0.2)";
$r.ctx.beginPath();
$r.ctx.arc(0, 0, $r.r_size / 2, 0, 2 * Math.PI, 2);
$r.ctx.lineWidth = $r.r_thickness;
$r.ctx.stroke();
$r.ctx.fillStyle = "rgba(128,128,128,0.6)";
$r.ctx.fill();
// second circle
$r.ctx.strokeStyle = "rgba(253, 128, 1, 0.9)";
$r.ctx.beginPath();
$r.ctx.arc(0, 0, $r.r_size / 2, 0, endAngle, 1);
$r.ctx.lineWidth = $r.r_thickness;
$r.ctx.stroke();
// label
$r.ctx.fillStyle = "#ffffff";
$r.ctx.font = '12px Helvetica';
$r.ctx.fillText(label, 0, 23);
$r.ctx.fillText(label, 0, 23);
$r.ctx.font = 'bold 40px Helvetica';
$r.ctx.fillText(Math.floor(value), 0, 10);
$r.ctx.restore();
}
}
return ringer;
}
var ringer = ringerFactory('10/31/2019');
ringer.init();
var ringer2 = ringerFactory('3/31/2020');
ringer2.init();
var ringer3 = ringerFactory('10/31/2018');
ringer3.init();<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>