Ответ 1
У меня была такая же проблема с моим плагином liteAccordion. Его можно устранить, установив видимость обратной стороны на скрытый элемент, который вы анималируете, как вы можете видеть здесь: http://jsfiddle.net/ZPQBp/1/
Как эксперимент, я пытаюсь реплицировать функциональность Sprite AS3 в JavaScript без использования объекта canvas. Я думал, что использование абсолютно позиционированных divs и управление их свойствами css было бы неинтересным, однако в Chrome анимация вводит странные артефакты (по-видимому, из-за проблем с перерисованием).
Я не могу найти то, что я делаю неправильно? Код, на самом деле, довольно прост. Вот несколько моментов, которые я пробовал, которые не помогли:
Здесь вы можете увидеть упрощенную скрипту: http://jsfiddle.net/BVJYJ/2/
EDIT: http://jsfiddle.net/BVJYJ/4/
И здесь вы можете увидеть артефакты в моем браузере:
Это может быть ошибка в моей настройке (Windows 7 64 бит, Chrome 21.0.1180.75). Никакие другие браузеры не демонстрируют такого поведения. Я был бы очень признателен, если бы кто-нибудь мог прокомментировать, что я могу делать неправильно. Мне больше любопытно, чем это объясняется, а не обходным путем. Тем не менее, каждое объяснение приветствуется.:)
РЕДАКТИРОВАТЬ: В образце кода произошла ошибка, которая привела к использованию setTimeout, даже когда у меня создалось впечатление, что используется RAF. requestAnimationFrame решает проблему с базовым преобразованием, но проблема остается с преобразованиями CSS, такими как вращение.
У меня была такая же проблема с моим плагином liteAccordion. Его можно устранить, установив видимость обратной стороны на скрытый элемент, который вы анималируете, как вы можете видеть здесь: http://jsfiddle.net/ZPQBp/1/
Некоторые исследования показывают, что setTimeout
может вызывать проблемы по различным причинам. Вы действительно должны использовать requestAnimationFrame
:
Таймеры не точно соответствуют миллисекунде. Вот несколько общих таймеров резолюции 1:
- Internet Explorer 8 и более ранние версии имеют разрешение таймера 15.625мс
- Internet Explorer 9 и более поздние версии имеют разрешение таймера 4 мс. Firefox
- и Safari имеют разрешение таймера ~ 10 мс.
- Chrome имеет разрешение таймера 4 мс.
Internet Explorer до версии 9 имеет разрешение таймера 15,625 ms 1, поэтому любое значение от 0 до 15 может быть 0 или 15, но ничего больше. Internet Explorer 9 улучшил разрешение таймера до 4 мс, но это все еще не очень специфично, когда дело касается анимации.
Разрешение таймера Chromes составляет 4 мс, а Firefox и Safaris - 10 мс. Поэтому, даже если вы установите интервал для оптимального отображения, вы все равно только приближаясь к желаемому сроку.
Ссылка: http://www.nczonline.net/blog/2011/05/03/better-javascript-animations-with-requestanimationframe/
Кроме
setTimeout
не учитывает, что еще происходит в браузер. Страница может быть скрыта за вкладкой, забивая ваш процессор, когда это не нужно, или сама анимация могла быть прокручена на странице, что делает вызов обновления лишним. Chrome делает throttle setInterval и setTimeout до 1fps в скрытых вкладках, но это на всех браузерах не следует полагаться.Во-вторых,
setTimeout
только обновляет экран, когда захочет, а не когда компьютер способен. Это означает, что ваш плохой браузер должен жонглировать, перерисовывая анимацию при перерисовке всего экрана и если частота кадров анимации не синхронизирована с перерисовкой вашего экрана, он может занять больше вычислительной мощности. Это значит более высокий уровень использования ЦП и вентиляторы ваших компьютеров, или дренирование аккумулятор на вашем мобильном устройстве. Николас Закас делает отличную работу объяснение разрешения таймера воздействия на анимацию в связанной статья.
Ссылка: http://creativejs.com/resources/requestanimationframe/
Это как-то связано с подпиксельным позиционированием. Если вы округлите до ближайшего пикселя, вы не увидите эти ошибки рендеринга:
thisRef.block.style.left = Math.round((x + (mouseX - ox - x) * .125)) + "px";
thisRef.block.style.top = Math.round((y + (mouseY - oy - y) * .125)) + "px";