Очистить холст при изменении размера окна

Я пытаюсь сбросить свое кольцо прогресса, которое рисуется с помощью холста при изменении размера.

В настоящее время, когда я изменяю размер своего окна, функция снова запускается, как и ожидалось, но вместо сброса холста на том же холсте рисуется другое кольцо прогресса, см. снимок экрана ниже:

Очистить холст при изменении размера окна

Я нашел clearRect() в ответе здесь: Как очистить холст для перерисовки и аналогичные решения, но, похоже, это не решает мою проблему.

Пожалуйста, найдите мой codepen с кодом: https://codepen.io/MayhemBliz/pen/OJQyLbN

Javascript:

// Progress ring
function progressRing() {
    
    const percentageRings = document.querySelectorAll('.percentage-ring');

    for (const percentageRing of Array.from(percentageRings)) {

        console.info(percentageRing.offsetWidth)

        var percentageRingOptions = {
            percent: percentageRing.dataset.percent,
            size: percentageRing.offsetWidth,
            lineWidth: 30,
            rotate: 0
        }

        var canvas = document.querySelector('.percentage-ring canvas');
        var span = document.querySelector('.percentage-ring span');

        span.textContent = percentageRingOptions.percent + '%';

        if (typeof (G_vmlCanvasManager) !== 'undefined') {
            G_vmlCanvasManager.initElement(canvas);
        }

        var ctx = canvas.getContext('2d');
    
    //clear canvas for resize
        ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
        ctx.beginPath();
    // end clear canvas
    
        canvas.width = canvas.height = percentageRingOptions.size;

        percentageRing.appendChild(span);
        percentageRing.appendChild(canvas);

        ctx.translate(percentageRingOptions.size / 2, percentageRingOptions.size / 2); // change center
        ctx.rotate((-1 / 2 + percentageRingOptions.rotate / 180) * Math.PI); // rotate -90 deg

        //imd = ctx.getImageData(0, 0, 240, 240);
        var radius = (percentageRingOptions.size - percentageRingOptions.lineWidth) / 2;

        var drawCircle = function (color, lineWidth, percent) {
            percent = Math.min(Math.max(0, percent || 1), 1);
            ctx.beginPath();
            ctx.arc(0, 0, radius, 0, Math.PI * 2 * percent, false);
            ctx.strokeStyle = color;
            //ctx.lineCap = 'round'; // butt, round or square
            ctx.lineWidth = lineWidth
            ctx.stroke();
        };

        drawCircle('#efefef', percentageRingOptions.lineWidth, 100 / 100);

        var i = 0; var int = setInterval(function () {
            i++;
            drawCircle('#555555', percentageRingOptions.lineWidth, i / 100);
            span.textContent = i + "%";
            if (i >= percentageRingOptions.percent) {
                clearInterval(int);
            }
        }, 50);

    }
}

window.addEventListener('load', progressRing);
window.addEventListener('resize', progressRing);

HTML:

<div class = "percentage-ring" data-percent = "88">
  <span>88%</span>
  <canvas></canvas>
</div>

Ваша помощь будет принята с благодарностью.

заранее спасибо

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
29
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

1. Очистить проблему с размером

var canvas = document.querySelector('.percentage-ring canvas');

var ctx = canvas.getContext('2d');

ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);

Вы должны указать размер холста с помощью (canvas.width, canvas.height) вместо ctx.canvas.width, ctx.canvas.height

ctx.clearRect(0, 0, canvas.width, canvas.height);

2. Проблема использования интервального таймера

Если progressRing() вызывается снова после setInterval() без clearInterval(), например, из-за изменения размера, он будет продолжать работать с сохранением предыдущего интервального выполнения. Это приведет к тому, что кольцо будет нарисовано дважды, трижды и более.

Поместите var int = 0; вне функций. Это сначала инициализирует int значением 0.

И измените var int = setInterval( на int = setInterval(

Затем поместите следующий код в начало progressRing()

if (int) {
    clearInterval(int);
    int = 0;
}

А также поставить int = 0; сразу после звонка clearInterval(), который уже был.

Спасибо за ваш ответ, я изменил код в codepen с вашим предложением, но холст по-прежнему не сбрасывается и дублируется, когда я изменяю размер окна.

MayhemBliz 05.05.2022 16:06

Итак, теперь он очищается правильно. И я нашел еще одну проблему и добавил решение для нее в свой ответ. Возможно, именно эту проблему вы имели в виду с самого начала.

Itagaki Fumihiko 05.05.2022 18:48

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

MayhemBliz 05.05.2022 19:25

Переместите var int = 0; за пределы всех функций, включая progressRing(). Лучше всего первая линия.

Itagaki Fumihiko 06.05.2022 02:16

Итагаки; Большое спасибо за вашу постоянную помощь в этом.

MayhemBliz 06.05.2022 11:22

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