Постепенно рисовать линии анимации на холсте

0

Поэтому я хочу оживить рисование строки на холсте HTML 5 с помощью requestAnimationFrame.

Я сделал это

function animateWrapper(centerX, centerY, xAngle, yAngle, width, height) {
    var request = requestAnimationFrame(animate);
    var canvas = document.getElementById("drawing");
    var context = canvas.getContext('2d');  
    function animate (centerX, centerY, xAngle, width, height) {
        drawLine(centerX,centerY, centerX, centerY - height, context, request);
    }
}

function drawLine(startX, startY, endX, endY, context, request) {
    context.beginPath();
    context.moveTo(startX, startY);
    step += 0.05;
    // if (step > 1) step = 1;
    var newX = startX + (endX - startX) * step;
    var newY = startY + (endY - startY) * step;
    context.lineTo(newX, newY);
    context.stroke();
    if (Math.abs(newX) >= Math.abs(endX) && Math.abs(newY) >= Math.abs(endY)) {
        cancelAnimationFrame(request);
        step = 0;
    }
}

$(document).ready(function(){
    animateWrapper(100, 100, 40, 40, 400, 400);
});

Прямо сейчас centerY, xAngle, width, height не определены (что имеет смысл - они не передаются). Это приводит к тому, что endY становится NaN, поэтому анимация не возникает.

Я не уверен, как это исправить - как передать эти аргументы в рамке анимации запроса?

Теги:
canvas
animation

2 ответа

0
Лучший ответ

В вашем коде есть первая проблема: анимация не произойдет, поскольку вы только один раз вызываете requestAnimationFrame (rAF). Вы можете думать о rAF как setTimeout, который будет срабатывать, как только появится следующий экран времени, а не setInterval, который будет вызывать снова и снова каждый раз.

Вторая проблема - классическая проблема с закрытием/привязкой/расширением javascript.
Поэтому первым решением было бы перейти на более современный язык, такой как Google Dart (:-)).
Другим решением является, например, привязка вашей функции анимации к ее параметрам.
В javascript, если вы это сделаете:

var myBoundFunction = someFunction.bind(null, arg1, arg2, arg3);

затем позже, позвонив

myBoundFunction();

будет иметь тот же эффект, что и вызов:

someFunction(arg1, arg2, arg3);

посмотрите здесь более подробную информацию и об использовании первого аргумента:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

Я мог бы дать вам подсказку о том, как изменить код, но в любом случае, я думаю, вам нужно оживить несколько строк, поэтому вы должны изменить способ его работы, чтобы сделать его более гибким.
Я настоятельно рекомендую вам перейти к объекту и определить строку как объект, имеющий (x, y,...) и метод рисования и обновления.

Что-то вроде (используя закрытие на этот раз):

var canvas   = ... ;    // do the DOM access only once
var context  = ... ;   // do the DOM accessd only once      
var myObjectsToDraw = [];

function animate() {
       ... return and stop animation if some condition is met ...
       requestAnimationFrame(animate);
       ... clear screen ..
       // draw all objects
       for (var i in myObjectsToDraw) myObjectsToDraw[i].draw();
       // update all objects
       for (var i in myObjectsToDraw) myObjectsToDraw[i].update();
}

myObjectsToDraw.push ( ... some object ... );
animate();

((если вам интересно, вот цикл анимации, который я использую: http://jsfiddle.net/gamealchemist/KVDsc/
и моя базовая скрипка с кучей небольших утилит http://jsfiddle.net/gamealchemist/Vn2Nt/))

  • 0
    ааа, я вижу это - поэтому я попробовал это - stackoverflow.com/questions/23616171/… но это не зациклится - почему?
  • 0
    Вы запрашиваете один раз анимацию, которая ничего не запрашивает. Пожалуйста, удалите этот другой вопрос, это шум. Надеюсь, мой ответ может привести вас к решению, которое вы ищете.
Показать ещё 2 комментария
1

Это должно работать:

function animateWrapper(centerX, centerY, xAngle, yAngle, width, height) {
    function animate () {
        drawLine(centerX,centerY, centerX, centerY - height, context, request);
    }

    var request = requestAnimationFrame(animate);
    var canvas = document.getElementById("drawing");
    var context = canvas.getContext('2d');  
}

Вам не нужно вызывать animate() с любыми аргументами, поскольку переменные centerX, centerY ,... и height находятся в области видимости, когда animate() определен (т.е. они были известны в то время, поэтому вы можете просто использовать их внутри функции).

Ответ на этот вопрос перечисляет всевозможные способы, по которым переменные становятся/становятся видимыми/пригодными для использования в JavaScript: какова область переменных в JavaScript?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню