Animated Canvas Arc
by navinleon
HTML
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css">
<div class="progress heart completed">
<canvas id="bar" width="140" height="140"></canvas>
</div>
SCSS
*,*:before,*:after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
body {
padding: 10px;
background: #ccc;
}
// Start here
.progress {
position: relative;
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
width: 140px;
height: 140px;
padding: 0;
&:before {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
width: 132px;
height: 132px;
border: 2px solid #fff;
border-radius: 50%;
// preset color and font
color: white;
font-family: fontAwesome;
font-size: 48px;
}
// Specific Variant center
&.heart {
&:before {
content: "\0f21e"; // Use correct FontAwesome character
padding-top: 6px; // Vertical adjust to center
}
}
// Completed Flag
&.completed {
&:after {
position: absolute;
top: 6.25%;
right: 6.25%;
height: 32px;
width: 32px;
border-radius: 50%;
background-color: #FF5300; /// set to client color
display: block;
border: 2px solid #fff;
text-align: center;
font-family: fontAwesome;
content: "\0f00c";
color: white;
font-size: 14px;
line-height: 2em;
}
}
}
#bar {
position: absolute;
top: 0px;
left: 50%;
transform: translateX(-50%);
opacity: 1;
}
// end here
JavaScript
// CANVAS
var canvas = document.getElementById('bar'),
width = canvas.width,
height = canvas.height;
console.log("width: " + width);
console.log("height: " + height);
// CANVAS PROPERTIES
var ctx = canvas.getContext('2d');
ctx.lineWidth = 7;
ctx.strokeStyle = '#fff';
ctx.shadowOffsetX = 0;
ctx.shadowOffsetY = 0;
ctx.shadowBlur = 1;
ctx.shadowColor = '#fff';
// CANVAS MATH
var x = width / 2,
y = height / 2,
radius = 65,
circum = Math.PI * 2,
start = Math.PI / -2, // Start position (top)
finish = 65, // Final position of the draw (in %)
curr = 10; // Current position the draw starts (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();
// 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)
// arc(x, y, radius, startAngle, endAngle, anticlockwise)
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 is reached (use requestAnimationFrame, and not setTimeout or setInterval!)
requestAnimationFrame(function() {
animate(circum * curr / 100 + start);
});
}
}
animate();
// origins: http://stackoverflow.com/questions/15692353/animate-a-canvas-circle-to-draw-on-load & http://jsfiddle.net/loktar/uhVj6/4/