Холст перестает рисовать фигуры после обрезки изображения

Я работаю над холстом, показывающим уровни в соответствии с приведенными ниже пользователями, - это мой код, проблема в том, что после клипа изображения на первом уровне следующий рисунок и анимация перестают работать.

Холст содержит массив json, который используется для рисования уровней. Класс levels. содержит метод отключения статических форм и функций, начиная с animate, использует кадры анимации для анимации линий или кругов. HTML:

<!DOCTYPE html>
<html>
<head>
    <title>Canvas</title>
</head>
<body>

    <canvas id = "levelchart" data-levels = "[{&quot;text&quot;:&quot;Mark&quot;,&quot;dotcolor&quot;:&quot;#28912e&quot;,&quot;linecolor&quot;:&quot;#28912e&quot;,&quot;current&quot;:&quot;0&quot;,&quot;completed&quot;:&quot;1&quot;,&quot;image&quot;:&quot;http://nessgoods.com/timthumb.php?src=http://www.nessgoods.com/upload/users/3/pills_311869.jpg&amp;q=100&quot;},{&quot;text&quot;:5,&quot;dotcolor&quot;:&quot;#28912e&quot;,&quot;linecolor&quot;:&quot;#28912e&quot;,&quot;current&quot;:&quot;0&quot;,&quot;pending&quot;:&quot;0&quot;,&quot;completed&quot;:&quot;1&quot;},{&quot;text&quot;:25,&quot;dotcolor&quot;:&quot;#28912e&quot;,&quot;linecolor&quot;:&quot;#28912e&quot;,&quot;current&quot;:&quot;0&quot;,&quot;pending&quot;:&quot;0&quot;,&quot;completed&quot;:&quot;1&quot;},{&quot;text&quot;:125,&quot;dotcolor&quot;:&quot;#28912e&quot;,&quot;linecolor&quot;:&quot;#28912e&quot;,&quot;current&quot;:&quot;0&quot;,&quot;pending&quot;:&quot;0&quot;,&quot;completed&quot;:&quot;1&quot;},{&quot;text&quot;:625,&quot;dotcolor&quot;:&quot;#28912e&quot;,&quot;linecolor&quot;:&quot;#28912e&quot;,&quot;current&quot;:&quot;0&quot;,&quot;pending&quot;:&quot;0&quot;,&quot;completed&quot;:&quot;1&quot;},{&quot;text&quot;:3125,&quot;dotcolor&quot;:&quot;#28912e&quot;,&quot;linecolor&quot;:&quot;#28912e&quot;,&quot;current&quot;:&quot;0&quot;,&quot;pending&quot;:&quot;0&quot;,&quot;completed&quot;:&quot;1&quot;},{&quot;text&quot;:15625,&quot;dotcolor&quot;:&quot;#3498db&quot;,&quot;linecolor&quot;:&quot;#3498db&quot;,&quot;current&quot;:&quot;1&quot;,&quot;completed&quot;:&quot;1&quot;,&quot;pending&quot;:&quot;3125&quot;},{&quot;text&quot;:78125,&quot;dotcolor&quot;:&quot;#3498db&quot;,&quot;linecolor&quot;:&quot;#3498db&quot;,&quot;current&quot;:0,&quot;pending&quot;:&quot;0&quot;,&quot;completed&quot;:0},{&quot;text&quot;:390625,&quot;dotcolor&quot;:&quot;#3498db&quot;,&quot;linecolor&quot;:&quot;#3498db&quot;,&quot;current&quot;:0,&quot;pending&quot;:&quot;0&quot;,&quot;completed&quot;: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>
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Введение в CSS
Введение в CSS
CSS является неотъемлемой частью трех основных составляющих front-end веб-разработки.
Как выровнять Div по центру?
Как выровнять Div по центру?
Чтобы выровнять элемент <div>по горизонтали и вертикали с помощью CSS, можно использовать комбинацию свойств и значений CSS. Вот несколько методов,...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Ангулярный шаблон для бронирования путешествий
Toor - Travel Booking Angular Template один из лучших Travel & Tour booking template in the world. 30+ валидированных HTML5 страниц, которые помогут...
0
0
37
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В функции 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 = "";

                }

Другие вопросы по теме