Почему в мобильных браузерах наблюдаются полосы с вращением <canvas>?
Я выполняю ротацию двухмерного холста, который довольно хорошо работает на рабочем столе, но есть одна маленькая проблема в мобильном пространстве. Вот увеличенное изображение на скриншоте:
Изображение большого пальца поворачивается на 0.2рад в течение 500 мс. Я думаю, что весь соответствующий код встроен ниже. Как видите, у каждого из верхних углов изображения есть своего рода "след".
var duration = 500;
var start = 0;
var stop = 0.287554326;
var step = (stop - start) / 10;
var steps = (stop - start) / step;
var current = 0;
var delay = duration / steps;
var first = true;
if (navigator.userAgent.match(/iP(hone|[ao]d)|android/i)) step *= 1.5;
var rotate_int = setInterval(function() {
if (current >= stop) {
clearInterval(rotate_int);
callback && callback();
return;
}
ctx.clearRect(0, 0, cvs.width, cvs.height);
ctx.translate(cvs.width / 2, cvs.height / 2);
ctx.rotate(step);
current += step;
ctx.translate(cvs.width / -2, cvs.height / -2);
ctx.drawImage(i, 0, 0);
if (first) {
first = false;
thumb.hide();
}
}, delay);
Заметки:
- Код очень хорошо работает на рабочем столе (самые последние версии Firefox, Chrome, Safari, Opera и даже IE)
- Я протестировал следующие устройства и браузеры:
- iPhone 3GS: сафари, опера мини
- iPhone 4S: Safari
- iPad (1-го поколения): Safari
- Android Galaxy S (с пряниками): браузер по умолчанию, Firefox mobile
- Motorola Droid X (с пряниками): браузер по умолчанию, мобильный Firefox
- Я не нашел настольный браузер (поддерживающий
<canvas>
) который демонстрирует поведение - Я не нашел мобильное устройство, которое не показывает поведение
- Выложенное изображение - увеличенный скриншот с iPad
- Если это имеет значение,
<canvas>
(во время вращения) анимируется (через jQuery), чтобы проходить через изображение позади него и останавливаться, что видно на скриншоте. - Есть второй
<canvas>
на странице также. Он использует тот же файл thumbs-up .png и вращается с использованием того же кода, который был размещен выше, а также анимирован для перемещения по другому фоновому изображению (но в противоположном направлении, т.е. один "большой палец вверх" перемещается на северо-запад, а другой на юго-восток), и следы появляются там же, в том же месте относительно контекста холста.
Я вылил всю грязь на эту стену, о которой я могу думать, в надежде, что что-то может привести к диагнозу. Кто-нибудь еще видел что-то подобное раньше? Что я мог попробовать по-другому? Я пропустил где-то большой красный ярлык с предупреждением на сайте учебника по HTML5, который предупреждает о таком поведении?
== РЕДАКТИРОВАТЬ 1==
Согласно комментарию @GGG, я удалил снифф UA (который предназначен для уменьшения количества и частоты перерисовок холста, потому что мобильные браузеры все пускают пыль, если я использую те же настройки, что и для рабочего стола), но это только заставило трейлы становиться более выраженными (например толще). Затем я поэкспериментировал, вернув нюхатель UA обратно, но вместо того, чтобы уменьшить петли на 50%, я увеличил их на 500%. Снова, это заставило следы стать еще более явными. Однако кажется, что это утолщение является асимптотическим - другими словами, есть предел тому, насколько толстым я могу быть, чтобы настроить трейлы, настраивая параметры скорости анимации.
== РЕДАКТИРОВАТЬ 2==
В соответствии с другим комментарием @GGG, я решил отредактировать изображение, чтобы добавить прозрачные данные в попытке найти подходящий обходной путь. Я увидел, что изображение выдвинуто к верхнему и левому краям холста (это "холст Photoshop ", а не "HTML5"). <canvas>
"). Когда я добавил равные отступы прозрачных данных к верхней и левой сторонам, проблема с полосами исчезла. Здесь был оригинальный PSD (pre me-добавление-extra-spacing):
Поэтому возникает вопрос: даже если изображение заполняет (непрозрачными пикселями) весь холст [Photoshop], почему мой контекст холста не является clearRect()
ведешь себя? Разве это не должно стирать что-либо в пределах холста? Если так, то почему он оставляет эти несколько пикселей?
== РЕДАКТИРОВАТЬ 3==
После некоторых исследований выяснилось, что Cairo довольно часто используется несколькими основными движками рендеринга (по крайней мере, WebKit и Gecko). Может ли быть так, как @JonasWielicki впервые предположил, что библиотека Cairo - когда она оптимизирована для мобильного исполнения - возможно, немного переусердствовала?
1 ответ
В качестве обходного пути попробуйте добавить несколько прозрачных пикселей по краю изображения.
Я действительно понятия не имею, почему это происходит. Я думаю, что это как-то связано со странной обработкой альфа-каналов на мобильных устройствах, но это всего лишь предположение.
Я заметил, что мобильные браузеры, кажется, отбрасывают или "оценивают" альфа-канал при прокрутке (медленно прокручивайте вверх и вниз, даже шрифты выглядят более "хрустящими"). Интересно, они отрисовывают вещи в два этапа, оставляя альфа-канал для второго этапа и пропуская второй этап, если есть еще один "кадр" для рендеринга сразу после текущего "кадра", если это имеет смысл. Возможно, это каким-то образом вводит в заблуждение то, что он не рисует вещи в тех местах, где он есть.
Во всяком случае, это, вероятно, заслуживает сообщения об ошибке. Мне было бы интересно услышать реальное объяснение того, что происходит, если ничего больше.