Анимация холста Javascript не появляется - PullRequest
0 голосов
/ 26 ноября 2018

Я пытаюсь создать анимацию холста с 2 объектами: окружность и закрашенный круг.Моя цель - создать впечатление, что окружность представляет орбиту кругов.Однако при попытке анимации анимация отсутствует, и только когда я нажимаю, чтобы остановить страницу, изображение появляется с кружком в произвольной позиции на орбите (это означает, что движущаяся часть работает).Спасибо за ваше время и вот код:

function restartAnimate(){
    runAnimation(0);
    setTimeout(restartAnimate(),1000);
}

function runAnimation(i){
    let animation = document.getElementById("Animation");
    let anim = animation.getContext("2d");
    anim.clearRect(0,0,300,150);
    anim.save();

    anim.strokeStyle = "#99ebff";
    anim.lineWidth = 10;
    anim.beginPath();
    anim.arc(150, 75, 40, 0, 2 * Math.PI);
    anim.stroke();

    anim.restore();
    anim.save()
    anim.fillStyle = "#000000";
    anim.translate(150,75);
    anim.rotate(2 * Math.PI * i / 1000);
    anim.translate(-150,-75);
    anim.beginPath();
    anim.arc(150 + 36.5, 75 ,13, 0, 2 * Math.PI);
    anim.fill();

    anim.restore();

    i += 16;
    if(i < 1000) setTimeout(runAnimation(i),16);
}

1 Ответ

0 голосов
/ 27 ноября 2018

Вы должны использовать requestAnimationFrame для анимации, чтобы результаты рендеринга отображались синхронно с аппаратным обновлением дисплея.

setTimeout очень неточно, и ваша функция со временем отстает.Если вы используете requestAnimationFrame, вы можете использовать первый аргумент (время в мс) для точного определения времени.

ctx.save и ctx.restore могут быть очень дорогими вызовами, и их следует избегать, если вы можете.Поскольку вы только восстанавливаете преобразование, вы можете установить его вручную при необходимости с помощью ctx.setTransform()

Нет необходимости перезапускать анимацию, просто дайте ей повториться.

Пример переписывает ваш код с приведенным вышеИмеются в виду и некоторые другие изменения.Для получения дополнительной информации см. Комментарии к коду.

// Define constants and query DOM outside animation functions
const canvas = document.getElementById("animCanvas");
const ctx = canvas.getContext("2d");
Math.PI2 = Math.PI * 2; 
var startTime;

restartAnimate();

function restartAnimate() {
    if (startTime === undefined) {
        requestAnimationFrame(runAnimation);
    } else {
        startTime = 0;  // next frame animation we have restarted
    }
    // setTimeout(restartAnimate(),1000); // No need to restart as angle is cyclic.
}

function runAnimation(time) {
    if (!startTime) { startTime = time }
    const currentTime = time - startTime;
    ctx.setTransform(1,0,0,1,0,0); // resets transform, better than using save and restore
    ctx.clearRect(0,0,ctx.canvas.width,ctx.canvas.height); // avoid magic numbers
    //ctx.save(); // not needed

    ctx.setTransform(1,0,0,1,150, 75); // last two values set the origin
                                       // and is the point we rotate around
    ctx.strokeStyle = "#99ebff";
    ctx.lineWidth = 10;
    ctx.beginPath();
    ctx.arc(0, 0, 40, 0, Math.PI2);  // rendering at the origin
    ctx.stroke();

    //ctx.restore(); // not needed
    //ctx.save();  // not needed
    ctx.fillStyle = "#000000";
    //ctx.translate(150,75);   // working from origin so don't need to translate
    ctx.rotate(Math.PI2 * currentTime / 1000);
    //ctx.translate(-150,-75); // working from origin so don't need to translate
    ctx.beginPath();
    ctx.arc(36.5, 0 ,13, 0, Math.PI2);
    ctx.fill();

    //ctx.restore(); not needed

    requestAnimationFrame(runAnimation);
}
<canvas id="animCanvas"></canvas>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...