JavaScript: достижение точных конечных значений анимации? - PullRequest
0 голосов
/ 19 апреля 2010

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

Сейчас я нацеливаюсь только на позиционную анимацию (слева, сверху, справа, снизу). Когда мои анимации завершатся, они получат погрешность в 5px ~ для более быстрых анимаций и 0.5px ~ для анимаций 1000+ мс или больше. Вот основная часть обратного вызова, с примечаниями после.

var current = parseFloat( this[0].style[prop] || 0 )
    // If our target value is greater than the current
    , gt = !!( value > current )
    , delta = ( Math.abs(current - value) / (duration / 13) ) * (gt ? 1 : -1)
    , elem = this[0]
    , anim = setInterval( function(){
        elem.style[prop] = ( current + delta ) + 'px';
        current = parseFloat( elem.style[prop] );
        if ( gt && current >= value || !gt && current <= value ) clearInterval( anim );
     }, 13 );

this[0] и elem оба ссылаются на целевой элемент DOM.

prop ссылается на свойство для анимации, left, top, bottom, right и т. Д.

current - текущее значение свойства элемента DOM.

value - желаемое значение для анимации.

duration - указанная продолжительность (в мс), в течение которой анимация должна продолжаться.

13 - это задержка setInterval (которая должна быть примерно минимальной для всех браузеров).

gt - это var, то есть true, если value превышает начальное current, иначе это false.

Как я могу устранить ошибку?

Ответы [ 2 ]

1 голос
/ 19 апреля 2010

В дополнение к тому, что говорит Алекс, вам, как правило, лучше использовать расчеты на основе времени, а не пытаться делать отдельные шаги. Это обеспечивает точность и позволяет анимации работать с разумной скоростью, когда браузер недостаточно быстр, чтобы надежно перезванивать вам каждые n микросекунд.

function animate(element, prop, period, value) {
    var v0= parseFloat(element.style[prop] || 0); // assume pre-set in px
    var dv= value-v0;
    var t0= new Date().getTime();
    var anim= setInterval(function() {
        var dt= (new Date().getTime()-t0)/period;
        if (dt>=1) {
            dt= 1;
            clearInterval(anim);
        }
        element.style[prop]= v0+dv*dt+'px';
    }, 16);
}
1 голос
/ 19 апреля 2010

Вы можете столкнуться с ошибками округления, которые в итоге приведут к значению, отличному от ожидаемого. Вы могли бы взглянуть на действительно простую библиотеку анимации и увидеть метод, который они используют для преодоления этого (а также некоторые методы ослабления). Вот Эмиль Томаса Фукса, который содержит около 50 строк кода:

http://github.com/madrobby/emile/blob/master/emile.js

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...