Я работаю над холстом, показывающим уровни в соответствии с приведенными ниже пользователями, - это мой код, проблема в том, что после клипа изображения на первом уровне следующий рисунок и анимация перестают работать.
Холст содержит массив json, который используется для рисования уровней. Класс levels.
содержит метод отключения статических форм и функций, начиная с animate, использует кадры анимации для анимации линий или кругов.
HTML:
<!DOCTYPE html>
<html>
<head>
<title>Canvas</title>
</head>
<body>
<canvas id = "levelchart" data-levels = "[{"text":"Mark","dotcolor":"#28912e","linecolor":"#28912e","current":"0","completed":"1","image":"http://nessgoods.com/timthumb.php?src=http://www.nessgoods.com/upload/users/3/pills_311869.jpg&q=100"},{"text":5,"dotcolor":"#28912e","linecolor":"#28912e","current":"0","pending":"0","completed":"1"},{"text":25,"dotcolor":"#28912e","linecolor":"#28912e","current":"0","pending":"0","completed":"1"},{"text":125,"dotcolor":"#28912e","linecolor":"#28912e","current":"0","pending":"0","completed":"1"},{"text":625,"dotcolor":"#28912e","linecolor":"#28912e","current":"0","pending":"0","completed":"1"},{"text":3125,"dotcolor":"#28912e","linecolor":"#28912e","current":"0","pending":"0","completed":"1"},{"text":15625,"dotcolor":"#3498db","linecolor":"#3498db","current":"1","completed":"1","pending":"3125"},{"text":78125,"dotcolor":"#3498db","linecolor":"#3498db","current":0,"pending":"0","completed":0},{"text":390625,"dotcolor":"#3498db","linecolor":"#3498db","current":0,"pending":"0","completed":0}]" width = "1360" height = "380"></canvas>
</body>
JS:
<script
src = "https://code.jquery.com/jquery-2.2.4.min.js"
integrity = "sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44 = "
crossorigin = "anonymous"></script>
<script type = "text/javascript">
class levels{
constructor(){
var x = 0;
var y = 0;
var height = 0;
var width = 0;
var canvas = 0;
var fill = 0;
var start = 0;
var end = 0;
var lineWidth = 0;
var color = 0;
var gradient = 0;
var lineCap = "square";
var to = 0;
var data = 0;
var counter = 0;
var circleanimate = 0;
var percent=0;
var completed = 0;
var imagee = "";
}
config(){
}
line(){
// console.info(this.end);
this.canvas.beginPath();
this.canvas.moveTo(this.start, this.y);
this.canvas.lineTo(this.end, this.y);
this.canvas.lineWidth = this.lineWidth;
this.canvas.strokeStyle = this.color;
this.canvas.lineCap = this.lineCap
this.canvas.stroke();
};
circle(){
this.canvas.beginPath();
this.canvas.moveTo(this.end, this.y);
this.canvas.arc(this.end, this.y, this.radius, 0, 2 * Math.PI);
this.canvas.fillStyle = this.color;
this.canvas.fill();
this.canvas.closePath();
}
baloon(){
var bheight = (10 - lv.counter + lv.counter * 8 / 100 * canvas.height);
var totheight = canvas.height - (60 + bheight);
var height = totheight + 80 / 100 * bheight;
this.canvas.beginPath();
//console.info("check "+bheight+" "+totheight+" "+height);
var last = (lv.end-30) + (15 / 100 * bheight);
var y = lv.y-50;
this.canvas.moveTo(last + (12 / 100 * bheight), height - (13 / 100 * bheight));
this.canvas.bezierCurveTo(last - (16 / 100 * bheight), y, last - (16 / 100 * bheight), y, last - (16 / 100 * bheight), y);
this.canvas.bezierCurveTo(last - (36 / 100 * bheight), height, last - (36 / 100 * bheight), height, last - (36 / 100 * bheight), height);
this.canvas.arc(last - (18 / 100 * bheight), totheight + (38 / 100 * bheight), (last + (14 / 100 * bheight)) - (last - (28 / 100 * bheight)), 0.75 * Math.PI, 0.25 * Math.PI);
this.canvas.strokeStyle = lv.color;
this.canvas.lineWidth=3;
this.canvas.stroke();
// count++;
console.info(lv.imagee+" as");
if (this.imagee != "") {
var img = new Image();
img.src = this.imagee;
var newcanvas = this.canvas;
img.onload = function (e)
{
newcanvas.beginPath();
newcanvas.moveTo(last - (18 / 100 * bheight), totheight + (38 / 100 * bheight));
newcanvas.arc(last - (18 / 100 * bheight), totheight + (38 / 100 * bheight), (last + (14 / 100 * bheight)) - (last - (28 / 100 * bheight)) - 1, 0, 2 * Math.PI);
newcanvas.strokeStyle = "#fff";
newcanvas.stroke();
newcanvas.clip();
newcanvas.drawImage(img,last - (18 / 100 * bheight)-(1.5/100*canvas.width),totheight + (38 / 100 * bheight)-(1.5/100*canvas.width));
lv.canvas.beginPath();
// lv.image = "";
}
}
}
}
function animateCircle() {
if (lv.circleanimate<2.1){
requestAnimationFrame(animateCircle);
lv.canvas.beginPath();
lv.canvas.moveTo(lv.end, lv.y);
lv.canvas.arc(lv.end, lv.y, lv.radius, (lv.circleanimate-0.1) * Math.PI, lv.circleanimate * Math.PI);
lv.canvas.fillStyle = lv.color;
lv.strokeStyle = "none";
lv.canvas.fill();
lv.canvas.closePath();
lv.circleanimate=lv.circleanimate+0.1;
}else{
lv.circleanimate=0;
if (lv.end == 0) {
lv.start = 0;
lv.end = 0;
lv.to = 30;
lv.color = lv.data[0].linecolor;
lv.style = "normal";
if (lv.data[0].hasOwnProperty("image")){
lv.imagee = lv.data[0].image;
}
} else {
lv.style = "bold";
lv.start = lv.end + 10;
var index = lv.counter-1;
if (lv.counter>=8){
index = 8;
}
console.info(index+" c ");
lv.imagee = "";
if (lv.data[index].hasOwnProperty("image")){
var w = 3/100*canvas.width;
lv.imagee = lv.data[index].image+"&w = "+w+"&h = "+w;
}
lv.color = lv.data[index].linecolor;
lv.percent = (Number(lv.data[index].pending) / Number(lv.data[index].text) * 100);
lv.completed = lv.data[index].completed;
lv.end = lv.start;
var p = (lv.counter * 2)+2;
lv.to = lv.to + ((p / 100) * workarea);
}
animateElipse();
animateLineFill();
}
}
function animateElipse(){
if (lv.circleanimate<2.1){
requestAnimationFrame(animateElipse);
var bheight = (10 - lv.counter + lv.counter * 8 / 100 * canvas.height);
var totheight = canvas.height - (60 + bheight);
var height = totheight + 80 / 100 * bheight;
var last = lv.end-25;
var y = lv.y-48;
lv.canvas.beginPath();
lv.canvas.moveTo(last, y);
lv.canvas.ellipse(last, y, 8, 2, 0,0, lv.circleanimate * Math.PI);
lv.canvas.fillStyle = "#e4e5e7";
lv.canvas.fill();
lv.circleanimate=lv.circleanimate+0.1;
}else{
lv.baloon();
}
}
function animateLineFill(){
if (lv.end<lv.to){
requestAnimationFrame(animateLineFill);
}else if (lv.counter<lv.count){
lv.circleanimate=0;
if (lv.end == 0) {
lv.start = 0;
lv.end = 0;
lv.to = 30;
lv.color = lv.data[0].linecolor;
lv.style = "normal";
} else {
lv.style = "bold";
lv.start = lv.end + 8;
var index = lv.counter;
if (lv.counter>=8){
index = 8;
}
lv.imagee = "";
if (lv.data[index].hasOwnProperty("image")){
var w = 3/100*canvas.width;
lv.imagee = lv.data[index].image+"&w = "+w+"&h = "+w;
}
lv.color = lv.data[index].linecolor;
lv.end = lv.start;
// var p = (lv.counter+1.9 * 5);
// lv.to = lv.to + ((p / 100) * workarea);
}
animateCircle();
lv.counter++;
}
lv.line();
lv.end++;
}
var lv = new levels();
var canvas = document.querySelector("canvas#levelchart");
/*canvas.width = (98 / 100) * $("div.team_link").width();
canvas.height = (28 / 100) * canvas.width;*/
canvas.width = (98 / 100) * $(window).width();
canvas.height = (28 / 100) * canvas.width;
var c = canvas.getContext('2d');
var workarea = (canvas.width);
var points = workarea / 10;
var start = canvas.width - 10;
var last = 0;
var y = canvas.height - 10;
var cheight = canvas.height;
var data = document.getElementById("levelchart").getAttribute("data-levels");
data = JSON.parse(data);
var i = 0;
var style = "normal";
lv.start = start;
lv.end = last;
lv.canvas = c;
lv.color = "#000000";
lv.y = y;
lv.start = 50;
lv.end = workarea-50;
lv.lineWidth = 4;
lv.color = "#eee";
lv.lineCap = "round";
lv.line();
lv.end = 0;
lv.radius = 5;
lv.count = data.length;
lv.data = data;
lv.counter = 0;
if (lv.end == 0) {
lv.start = 0;
lv.end = 0;
lv.to = 30;
lv.color = lv.data[0].linecolor;
lv.style = "normal";
}
animateLineFill();
</script>






В функции image.load мы должны вызвать .save() на холсте, а после clip() мы должны вызвать функцию .restore(), как определено в приведенном ниже коде.
img.onload = function (e)
{
newcanvas.save();
newcanvas.beginPath();
newcanvas.moveTo(last - (18 / 100 * bheight), totheight + (38 / 100 * bheight));
newcanvas.arc(last - (18 / 100 * bheight), totheight + (38 / 100 * bheight), (last + (14 / 100 * bheight)) - (last - (28 / 100 * bheight)) - 1, 0, 2 * Math.PI);
newcanvas.strokeStyle = "#fff";
newcanvas.stroke();
newcanvas.clip();
newcanvas.drawImage(img,last - (18 / 100 * bheight)-(1.5/100*canvas.width),totheight + (38 / 100 * bheight)-(1.5/100*canvas.width));
newcanvas.restore();
// lv.image = "";
}