Вопросы о Запрос кадра анимации

Я пытаюсь создать сайт параллакса, который будет перемещать несколько элементов при прокрутке сайта. Но вместо использования прослушивателя событий прокрутки я использую requestAnimationFrame после прочтения это сообщение Пола Айриша и это видео, в котором говорится, что слушатель прокрутки немного глючит. Мои вопросы:

  1. В Chrome он выглядит довольно плавно, но в Firefox он плохо мерцает. Я сделал что-то не так здесь?
  2. Действительно ли мой код занимает больше ресурсов, чем обычный прослушиватель событий прокрутки? Я слышу, как вентилятор моего ноутбука пылает каждый раз, когда я играю с этим кодом.

Мой файл находится по адресу http://www.socialbuzz.com.au/index.html и, пожалуйста, прокрутите страницу вниз, чтобы увидеть элемент, которым манипулируют с помощью javascript.


person Zendy    schedule 15.05.2012    source источник
comment
Вы должны добавить соответствующий код, который использует requestAnimationFrame к вашему вопросу, для будущих читателей после того, как вы обновите свой сайт.   -  person Kevin Reid    schedule 15.05.2012
comment
Кроме того, вы имели в виду эту статью о requestAnimationFrame?   -  person Kevin Reid    schedule 15.05.2012


Ответы (3)


У вас должно быть событие прокрутки, запускающее цикл requestAnimationFrame. Не инициируйте requestAnimationFrame самим событием прокрутки. У вас должно получиться что-то вроде var scrolling = true; Пока это происходит, запустите цикл requestAnimationFrame, который ссылается на данные события из события прокрутки. Вам нужно будет отменить событие прокрутки, чтобы отключить цикл, как только вы закончите, это рутинная работа, но результаты того стоят. Надеюсь это поможет.

person tencircles    schedule 16.05.2012
comment
Итак, у меня есть один объект requestAnimationFrame, и если браузер находится в поле зрения, я запускаю цикл requestAnimationFrame. Как только это не в поле зрения, я останавливаю цикл? - person Zendy; 16.05.2012
comment
Глядя на ваш код, ваш rAF находится внутри каждой функции jQuery, поэтому вы фактически вызываете ее 4 раза в каждом кадре. Моя первоначальная точка зрения заключалась в том, что вы можете сохранить свой прослушиватель прокрутки. Единственное, что нужно сделать вашему прослушивателю прокрутки, это получить нужные вам числа (scrollTop или что-то еще) и сообщить requestAnimationFrame, что ему нужно начать работу (через переменную прокрутки). Как только пользователь прекратил прокрутку, вы устанавливаете переменную в false. Ваш цикл должен выглядеть примерно так. (function animloop(){ if(scrolling){ requestAnimFrame(animloop); render(); })(); - person tencircles; 17.05.2012
comment
хорошо.. и как остановить запуск rAF? я должен сделать как var raf1 = requestAnimFrame(animloop);, а потом, когда я хочу остановить это, я делаю window.cancelAnimFrame(raf1)? - person Zendy; 18.05.2012
comment
Я делаю это путем устранения дребезга в основном. Поэтому, когда запускается событие прокрутки, оно просто вызывает функцию, которая устанавливает var scrolling = true и вызывает animLoop(). Чтобы отменить его, установите тайм-аут каждый раз, когда вызывается событие прокрутки, если оно существует, когда вызывается функция, очистите его. По завершении обратный вызов setTimeout должен отключить ваш цикл. Таким образом, ваше событие прокрутки просто включает функцию animLoop, и она отключится через x миллисекунд (независимо от того, на что у вас установлен debounce setTimeout). Внутри вашего анимлупа это должно выглядеть примерно так: if(scrolling) rAF(animLoop); РендерАнимация(); - person tencircles; 09.06.2012

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

Цель requestAnimationFrame — обеспечить оптимальное поведение для непрерывной анимации; ни одно из его преимуществ здесь не применимо. Зацикленный requestAnimationFrame, который ничего не делает внутри цикла, как у вас сейчас, вполне уместно, если каждый шаг цикла каким-то образом обновляет графику, но поскольку здесь ничего не меняется, когда пользователь не прокручивает, цикл ничего не делает, кроме как тратит ЦП. время.

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

person Kevin Reid    schedule 15.05.2012
comment
да, я понимаю, что вы имеете в виду, requestAnimationFrame не подходит для моей проблемы. Но вернемся к моей основной проблеме — эффекту дрожания в Firefox. Можно ли что-нибудь сделать, чтобы сделать его более плавным? - person Zendy; 16.05.2012
comment
Я не вижу никакого дрожания или мерцания при просмотре в Firefox 12.0 на Mac OS X, поэтому я не могу изучить эту проблему, извините. Однако, если вы отвечаете на прокрутку, то будут такие эффекты, если ответ будет задержан, что именно и происходит, когда вы отвечаете на прокрутку не непосредственно внутри обработчика прокрутки, поэтому я предлагаю вам выньте requestAnimationFrame и посмотрите, что произойдет. - person Kevin Reid; 16.05.2012
comment
Я думаю, что этот ответ неверен ... Трудно сказать без исходного сайта из вопроса, но часто целесообразно реализовать кадр анимации запроса с операцией прокрутки. Событие прокрутки запускается несколько случайным образом, и вы получите более плавный внешний вид с помощью requestAnimationFrame. См.: youtube.com/. - person prauchfuss; 29.07.2012
comment
да, это видео, которое я смотрел раньше. но да, я еще не получил удовлетворительного ответа .. - person Zendy; 01.08.2012
comment
Я думаю, что ваше первоначальное утверждение о том, что «вы не выполняете анимацию», немного вводит в заблуждение. Хотя это и правда, движение диктуется действиями пользователя, движение все же необходимо регулировать (иногда это неправильно называют устранением дребезга). С этой целью requestAnimationFrame полезен и следует использоваться для ограничения большого количества запускаемых событий прокрутки. - person Matt; 05.02.2013
comment
Этот ответ неверен и вводит в заблуждение тех людей, которые впервые сталкиваются с requestAnimationFrame. rAF запускается, когда браузер пытается выполнить операцию рисования — частота этого определяется факторами на уровне оборудования/ОС, но в идеале это происходит при 60 кадрах в секунду. Событие прокрутки запускается так часто, как позволяет однопоточный javascript, обычно намного ниже 60 кадров в секунду. Следовательно, любой javascript, который постоянно меняет представление (анимация), должен работать в rAF, чтобы максимизировать производительность. - person Simon Robb; 14.10.2015
comment
@SimonRobb Возможно, вы правы в том, что мой ответ — плохой совет (я думал о создании настоящей тестовой страницы для сравнения результатов вычислений и/или нагрузки рендеринга), но rAF так же подвержен «однопоточному javascript», ограничения как события. Вы не можете выйти из одного потока, не используя Web Workers или что-то подобное. - person Kevin Reid; 14.10.2015
comment
@KevinReid, это правда, я плохо выразился. Более важно то, что rAF синхронизирован с циклом рисования браузера. Мне было бы интересно увидеть вашу тестовую страницу, если вы соберетесь ее создать! - person Simon Robb; 19.10.2015

У меня был аналогичный опыт, и после долгих экспериментов с прослушивателями движения мыши и setInterval для увеличения частоты шагов анимации я вернулся к простому использованию onscroll и обнаружил, что на FF10 и FF 15 он отлично работает.

Возможно, мои требования не совпадают с вашими - это элемент, который отслеживает полосу прокрутки, поэтому onscroll был сигналом для изменения положения поля. Он отставал и дергался на FF, но отлично работал на WebKit и IE. Я обнаружил, что onscroll срабатывает не так часто в FF, как в Chrome/IE.

Когда я впервые попробовал это, это было на FF 5 или 6. Используя прослушиватель движения мыши или частый интервал, я смог увеличить частоту, с которой вызывается моя функция прокрутки ручки, но на самом деле это привело к тому, что позиционирование стало более прерывистым. Просто использование onscroll, похоже, теперь работает для меня на 10 ESR и 15, может быть, они что-то исправили.

person Steven Wood    schedule 12.09.2012
comment
да, я вернулся к onmousescroll событию. Затем, чтобы уменьшить эффект прерывистости, я использовал css transition вместо jquery анимации. Это работает лучше.. но я хотел бы узнать больше о request animation frame Я считаю, что это хорошая техника.. - person Zendy; 13.09.2012