JSFiddle - React, Tailwind, and code Playground

by Amar Nyayapati

HTML

<canvas id="test" width="160" height="160"></canvas>

CSS

article, aside, figure, footer, header, hgroup, 
  menu, nav, section { display: block; }

JavaScript

var Timer = function(canvasId, timeMax, refreshRate, timeoutCallback, strokeColor, fillColor) {
	var canvas = document.getElementById(canvasId),
		ctx = canvas.getContext("2d"),
		cwidth = canvas.width,
		cheight = canvas.height,
		timeMax = timeMax,
		timeLeft = timeMax,
		refreshRate = refreshRate,
		middleX = cwidth / 2,
		middleY = cheight / 2,
		maxRadius = cwidth / 2,
		strokeColor = strokeColor || "#000",
		fillColor = fillColor || "red",
		radianStart = Math.PI - 0.5,
		radianMax = Math.PI * 2,
		arcNorth = Math.PI * -0.5,
		stepTimer = null;

	var redrawInitials = function() {
		// circle draw
		ctx.strokeStyle = strokeColor;
		ctx.fillStyle = fillColor;
		ctx.lineWidth = 1;
		redrawInitials = function() {
			ctx.clearRect(0, 0, cwidth, cheight);
			ctx.beginPath();
			ctx.arc(middleX, middleY, maxRadius, 0, radianMax, false);
			ctx.stroke();
		};
		redrawInitials();
		return redrawInitials;
	}

	var proceed = function() {
		var newTimeLeft = timeLeft - refreshRate
		timerObj.setTimeLeft(newTimeLeft) && drawTimestep();
		if (newTimeLeft < 0) {
			timerObj.stop();
			if (timeoutCallback) {
				timeoutCallback.call(null, newTimeLeft);
			}
		}
	}

	var drawTimestep = function() {
		var timeUsedPercent = (timeMax - timeLeft) / timeMax;
		var rmax = radianMax * timeUsedPercent;
		ctx.beginPath();
		ctx.moveTo(middleX, middleY);
		ctx.arc(middleX, middleY, maxRadius, arcNorth, arcNorth + rmax, false);
		ctx.fill();
	}

	var timerObj = {
		setTimeLeft: function(time) {
			if (time > timeMax) {
				return false;
			} else if (time > timeLeft) redrawInitials();
			timeLeft = time;
			return true;
		},

		start: function() {
			stepTimer = setInterval(proceed, refreshRate);
		},

		stop: function() {
			clearInterval(stepTimer);
		}
	};

	var init = (function() {
		redrawInitials();
		timerObj.setTimeLeft(timeMax);
	})()

	return timerObj;
};


var myTime = new Timer("test", 20000, 500, function() { alert('timeout!') }, "blue", "cyan");
myTime.start();