Simple Canvas Progress Pie Graph
by sjmcpherson
HTML
<div class="progress">
<ul><li>Completed</li></ul>
<canvas id="bar" width="200" height="200"></canvas>
</div>
CSS
*,*:before,*:after{box-sizing:border-box;margin:0;padding:0;}
body{font-family:arial;}
ul{list-style:none;width:100%;}
li{margin-left:35%;position:absolute;top:88px;}
li:before{content:"";top:5px;left:-15px;position:absolute;width:10px;height:10px;border-radius:50%;background-color:#f00;display:block;}
.progress {
margin:0 auto;
position: relative;
width: 200px;
height: 200px;
text-align:center;
}
.progress:before {
content: "";
display: block;
width: 100%;
height: 100%;
border: 30px solid #444;
border-radius: 50%;
}
#bar {
position: absolute;
top: 0;
left: 0;
}
JavaScript
// CANVAS
var canvas = document.getElementById('bar'),
width = canvas.width,
height = canvas.height;
// CANVAS PROPERTIES
var ctx = canvas.getContext('2d');
ctx.lineWidth = 30;
ctx.strokeStyle = '#f00';
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
ctx.shadowBlur = 0;
ctx.shadowColor = '#f00';
// CANVAS MATHS
var x = width / 2,
y = height / 2,
radius = 85,
circum = Math.PI * 2,
start = Math.PI / -2, // Start position (top)
finish = 67, // Finish (in %)
curr = 0; // Current position (in %)
// CANVAS ANIMATION
// Enables browser-decided smooth animation (60fps)
var raf =
window.requestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.msRequestAnimationFrame;
window.requestAnimationFrame = raf;
// Animate function
function animate(draw_to) {
// Clear off the canvas
ctx.clearRect(0, 0, width, height);
// Start over
ctx.beginPath();
// arc(x, y, radius, startAngle, endAngle, anticlockwise)
// Re-draw from the very beginning each time so there isn't tiny line spaces between each section (the browser paint rendering will probably be smoother too)
ctx.arc(x, y, radius, start, draw_to, false);
// Draw
ctx.stroke();
// Increment percent
curr++;
// Animate until end
if (curr < finish + 1) {
// Recursive repeat this function until the end it reached
requestAnimationFrame(function () {
animate(circum * curr / 100 + start);
});
}
}
animate();