JSFiddle - React, Tailwind, and code Playground
HTML
<!DOCTYPE html>
<html>
<head>
<script type='text/javascript' src='jquery-2.1.0.js'></script>
<script type='text/javascript' src='squareProgress.js'></script>
<script type='text/javascript'>
</script>
<style type='text/css'>
canvas
{
transform: rotateZ(45deg);
padding: 40px;
}
</style>
</head>
<body>
<canvas id="canvas" width="200" height="200"></canvas>
</body>
</html>
JavaScript
var SquareProgress = function(canvas, pct){
this.canvas = canvas;
this.context = this.canvas.getContext("2d");
this.pct = pct;
this.x = 0;
this.y = 0;
this.width = 200;
this.height = 200;
this.innerWidth = 170;
this.innerHeight = 170;
this.innerX = 15;
this.innerY = 15;
this.centerInner = true;
this.duration = 8000;
this.animationStart = null;
this.ease = function (t) { return t<.5 ? 4*t*t*t : (t-1)*(2*t-2)*(2*t-2)+1 };
};
SquareProgress.prototype.init = function(){
if(this.centerInner){
this.centerInnerRect();
}
this.setCornerCoords();
this.reset();
this.animationStart = this.getTime();
};
SquareProgress.prototype.draw = function(){
this.init();
this.drawToPct(this.pct);
};
SquareProgress.prototype.getTime = function(){
return window.performance != undefined ? window.performance.now() : Date.now();
};
SquareProgress.prototype.animate = function(){
var self = this;
var currentTime = window.performance != undefined ? window.performance.now() : Date.now();
var timePassed = currentTime - this.animationStart;
var pctOfDuration = this.ease(timePassed / this.duration);
if(pctOfDuration >= 1){
return;
}
var currentFramePct = pctOfDuration * this.pct;
this.drawToPct(currentFramePct);
requestAnimationFrame(function(){
self.animate();
});
};
SquareProgress.prototype.centerInnerRect = function(){
this.innerX = ((this.width - this.innerWidth) / 2) + this.x;
this.innerY = ((this.height - this.innerHeight) / 2) + this.y;
};
SquareProgress.prototype.getOuterPointFromPct = function(pct){
var width = this.width,
height = this.height,
x = this.x,
y = this.y;
var rectC = (width + height) * 2;
var ptAlongC = rectC * pct;
var sideLimits = [
width, // side 1
width + height, // side 2,
width * 2 + height, // side 3,
rectC // side 4
];
var lastLimit = -1;
var sideContainingPt = 0;
while(ptAlongC > lastLimit && sideContainingPt < 4){
lastLimit =...