Basically I try to animate the lines in a donut chart (see example), so that each of them is counted up with document.ready. I tried to adopt the solution from here and here
As you can see, the countUp solution is already working well, but it needs to be connected to the chart, so that it is drawn on page load.
My knowledge regarding canvas isn´t amazing. I would be very happy, if anybody could help. Here is the code: https://jsfiddle.net/9oyoh67x/10/
$(document).ready(function () {
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
console.log(ctx);
ctx.lineWidth = 19;
ctx.lineCap = 'round';
ctx.shadowBlur = 10;
donutChart();
function degtoRad(degree) {
var factor = Math.PI / 180; // = 1 deg = 0.01745 rad
return degree * factor; // for 360 = 6.28 = 360°
}
/*function move() {
var elem = document.getElementById("canvas");
var width = 0;
var id = setInterval(countUp, 1000); }
*/
$(function () {
var countUp = setInterval(function () { donutChart }, 40);
function count($this) {
var current = parseInt($this.html(), 10);
$this.html(++current);
if (current !== $this.data('count')) {
setTimeout(function () { count($this) }, 50);
}
}
$(".testspan1").each(function () {
$(this).data('count', parseInt($(this).html(), 10));
$(this).html('0');
count($(this));
});
$(".testspan2").each(function () {
$(this).data('count', parseInt($(this).html(), 10));
$(this).html('0');
count($(this));
});
$(".testspan3").each(function () {
$(this).data('count', parseInt($(this).html(), 10));
$(this).html('0');
count($(this));
});
$(".testspan4").each(function () {
$(this).data('count', parseInt($(this).html(), 10));
$(this).html('0');
count($(this));
});
});
function donutChart() {
var factor_calc = Math.PI / 180;
var record = $('.testspan1').text(); // equal to 100% or 360°
var average = $('.testspan2').text();
var income = $('.testspan2').text();
var target = $('.testspan3').text();
// Record
ctx.strokeStyle = 'rgba(115, 100, 164, 1)';
ctx.beginPath();
ctx.arc(250, 250, 200, degtoRad(270), degtoRad(270 + (record / record) * 360));
ctx.stroke();
// Average
ctx.strokeStyle = 'rgba(125, 131, 164, 1)';
ctx.beginPath();
ctx.arc(250, 250, 170, degtoRad(270), degtoRad(270 + (average / record) * 360));
ctx.stroke();
//Income
ctx.strokeStyle = 'rgba(75, 181, 164, 1)';
ctx.beginPath();
ctx.arc(250, 250, 140, degtoRad(270), degtoRad(270 + (income / record) * 360));
ctx.stroke();
// Target
ctx.strokeStyle = 'rgba(26, 221, 164, 1)';
ctx.beginPath();
ctx.arc(250, 250, 110, degtoRad(270), degtoRad(270 + (target / record) * 360));
ctx.stroke();
// Record
ctx.font = "25px Philosopher";
ctx.fillStyle = 'rgba(115, 100, 164, 1)';
ctx.fillText(record, 220, 200);
//Average
ctx.font = "25px Philosopher";
ctx.fillStyle = 'rgba(125, 131, 164, 1)';
ctx.fillText(average, 220, 230);
//Income
ctx.font = "30px Philosopher";
ctx.fillStyle = 'rgba(75, 181, 164, 1)';
ctx.fillText(income, 220, 260);
// Target
ctx.font = "35px Philosopher";
ctx.fillStyle = 'rgba(26, 221, 164, 1)';
ctx.fillText(target, 220, 290);
// Euro
ctx.font = "60px Philosopher";
ctx.fillStyle = 'rgba(26, 221, 164, 1)';
ctx.fillText('€', 280, 255);
}
var options = {
useEasing: true,
useGrouping: true,
separator: ',',
decimal: '',
prefix: '',
suffix: '€'
};
});
HTML:
<div class="canvasdiv">
<canvas id="canvas" width="500" height="500"></canvas>
<img id="myImage" />
<span class='testspan1'>1250</span>
<span class='testspan2'>250</span>
<span class='testspan3'>450</span>
<span class='testspan4'>130</span>
</div>
For people with similar problems, here are some further related links (using no canvas):
I made it. Here is my solution (https://jsfiddle.net/9oyoh67x/12/):
// requestAnimationFrame Shim
(function start() {
var requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame ||
window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
window.requestAnimationFrame = requestAnimationFrame;
})();
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
console.log(ctx);
ctx.lineWidth = 19;
ctx.lineCap = 'round';
ctx.shadowBlur = 10;
var record = 820; // equal to 100% or 360°
var record_count = (record / record * 100)
var average = (229 / record * 100);
var income = (490 / record * 100);
var target = (750 / record * 100);
var counterClockwise = true;
var circ = Math.PI * 2;
var quart = Math.PI / 2;
var startTime1 = null;
var startTime2 = null;
var startTime3 = null;
var startTime4 = null;
var duration = null;
var duration1 = null;
var duration2 = null;
var duration3 = null;
var duration4 = null;
var options = {
useEasing: true,
useGrouping: true,
separator: ',',
decimal: '0',
prefix: '',
suffix: ''
};
function animate_rec(time) {
if (!startTime1) {
startTime1 = time;
}
var delta1 = Math.min(1, (time - startTime1) / duration1);
var curPerc = ((2 * Math.PI) / 100) * (record_count * delta1);
console.log(curPerc)
var innerNumRec = (record * delta1);
//console.log(innerNumRec);
ctx.strokeStyle = 'rgba(115, 100, 164, 1)';
ctx.beginPath();
ctx.arc(250, 250, 200, -quart, curPerc - quart);
ctx.stroke();
if (delta1 < 1) {
requestAnimationFrame(animate_rec);
ctx.clearRect(215, 180, 50, 30);
} else {
startTime1 = null;
ctx.clearRect(215, 180, 50, 30);
}
// Record
ctx.font = "25px Philosopher";
ctx.fillStyle = 'rgba(115, 100, 164, 1)';
ctx.fillText(Math.round(innerNumRec), 220, 200);
}
var startAnim_rec = function () {
duration1 = 3000;
requestAnimationFrame(animate_rec);
};
function animate_avg(time) {
if (!startTime2) {
startTime2 = time;
}
var delta2 = Math.min(1, (time - startTime2) / duration2);
var curPerc = ((2 * Math.PI) / 100) * (average * delta2);
var innerNumAvg = ((average * record / 100) * delta2);
console.log(innerNumAvg);
ctx.strokeStyle = 'rgba(125, 131, 164, 1)';
ctx.beginPath();
ctx.arc(250, 250, 170, -quart, curPerc - quart);
ctx.stroke();
if (delta2 < 1) {
requestAnimationFrame(animate_avg);
ctx.clearRect(215, 210, 70, 50);
} else {
startTime2 = null;
ctx.clearRect(215, 210, 70, 50);
}
// Average
ctx.font = "30px Philosopher";
ctx.fillStyle = 'rgba(125, 131, 164, 1)';
ctx.fillText(Math.round(innerNumAvg), 220, 230);
}
var startAnim_avg = function () {
duration2 = 3200;
requestAnimationFrame(animate_avg);
};
function animate_inc(time) {
if (!startTime3) {
startTime3 = time;
}
var delta3 = Math.min(1, (time - startTime3) / duration3);
var curPerc = ((2 * Math.PI) / 100) * (income * delta3);
var innerNumInc = ((income * record / 100) * delta3);
console.log(innerNumInc);
ctx.strokeStyle = 'rgba(75, 181, 164, 1)';
ctx.beginPath();
ctx.arc(250, 250, 140, -quart, curPerc - quart);
ctx.stroke();
if (delta3 < 1) {
requestAnimationFrame(animate_inc);
ctx.clearRect(215, 230, 70, 50);
} else {
startTime3 = null;
ctx.clearRect(215, 230, 70, 50);
}
// Income
ctx.font = "35px Philosopher";
ctx.fillStyle = 'rgba(75, 181, 164, 1)';
ctx.fillText(Math.round(innerNumInc), 220, 260);
}
var startAnim_inc = function () {
duration3 = 3400;
requestAnimationFrame(animate_inc);
};
function animate_tar(time) {
if (!startTime4) {
startTime4 = time;
}
var delta4 = Math.min(1, (time - startTime4) / duration4);
var curPerc = ((2 * Math.PI) / 100) * (target * delta4);
var innerNumTar = ((target * record / 100) * delta4);
console.log(innerNumTar);
ctx.strokeStyle = 'rgba(26, 221, 164, 1)';
ctx.beginPath();
ctx.arc(250, 250, 110, -quart, curPerc - quart);
ctx.stroke();
if (delta4 < 1) {
requestAnimationFrame(animate_tar);
ctx.clearRect(220, 260, 70, 50);
} else {
startTime4 = null;
ctx.clearRect(220, 260, 70, 50);
}
// Target
ctx.font = "40px Philosopher";
ctx.fillStyle = 'rgba(26, 221, 164, 1)';
ctx.fillText(Math.round(innerNumTar), 220, 290);
}
var startAnim_tar = function () {
duration4 = 3600;
requestAnimationFrame(animate_tar);
};
startAnim_rec();
startAnim_avg();
startAnim_inc();
startAnim_tar();
// Euro
ctx.font = "60px Philosopher";
ctx.fillStyle = 'rgba(26, 221, 164, 1)';
ctx.fillText('€', 280, 255);});