Анимация Webkit оставляет на экране ненужные пиксели - PullRequest
35 голосов
/ 03 апреля 2012

Следующий код помещает белое поле на экран.Если вы запустите его на iPad (вы можете настроить пиксели, чтобы запустить его и на iPhone), когда вы дотронетесь до рамки, он уйдет с экрана и оставит след пикселей белого цвета вдоль его нижнего края.

<!DOCTYPE HTML>
<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <meta name="viewport" content="width=device-height, user-scalable=no, maximum-scale=1, minimum-scale=1" />
    <title>Line Bug Demo</title>
    <style>
body {
  background: black;
}
.panel {
  background: white;
  position: absolute;
  z-index: 2;
  width: 1000px;
  height: 500px;
  top: 34px;
  left: 12px;
  -webkit-border-radius: 20px;
  -webkit-transition: left 0.333s ease-in-out;
}
.panel.hide {
  left: -1000px;
}
    </style>
  </head>
  <body>
    <div class="panel" onclick="this.setAttribute('class', 'panel hide')"></div>
  </body>
</html>

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

Вот обходные пути, которые я нашел до сих пор:

.panel.hide { -webkit-border-radius: 0; }

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

Другой:

.panel { -webkit-transform: translateZ(0); }

Это помещает панель в аппаратный конвейер, которыйделает композитинг правильно.Хотя это работает с этой простой демонстрацией, использование аппаратного конвейера в моем реальном веб-приложении вызывает ошибки нехватки памяти.(О радикальном, огромном, непосредственном разнообразии.)

Любые другие идеи о том, как я мог бы избавиться от этого следа?

Ответы [ 2 ]

58 голосов
/ 24 июля 2013

Решение

box-shadow: 0 0 1px rgba(0, 0, 0, 0.05);

Вы можете использовать цвет фона вашей коробки в качестве цвета box-shadow, если считаете, что это слишком заметно.

В качестве альтернативы, в соответствии с этим ответьте на похожую проблему в Chrome (спасибо Себастьяну в комментариях к подсказке), вы можете попробовать:

outline: 1px solid transparent;

Что происходит?

Я дал довольно длинное объяснение в другом месте, но вот короткая версия.Из соображений производительности WebKit перекрашивает только те части страницы, которые, по его мнению, могли измениться.Тем не менее, реализация iOS (до 7) Safari сглаживания радиуса границы на несколько пикселей превышает расчетные размеры блока.Поскольку WebKit не знает об этих пикселях, они не перерисовываются;вместо этого они остаются позади и накапливаются в каждом кадре анимации.

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

Использование box-shadow решает проблему более непосредственно: расширяет размеры перерисовкикоробки, заставляя WebKit перекрашивать лишние пиксели.Известные последствия для производительности box-shadow в мобильных браузерах напрямую связаны с используемым радиусом размытия, поэтому тень в один пиксель не должна давать никакого эффекта.

8 голосов
/ 30 апреля 2013

Что бы я сделал:

  • -webkit-backface-visibility: hidden
  • анимировать с помощью -webkit-transform:translateX(left value here) // или translate-3d(x,y,z), влево должно быть отключено [*]

Обязательно проверьте, имеет ли какое-либо значение включение аппаратного ускорения на parent .

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

[*] полагаться на 3d-преобразования - это взлом, и его следует использовать с осторожностью, и это компромисс между GPU и памятью, в некоторых случаях это может привести к задержке анимации илипроблемы с памятью (подумайте - мобильность, форсирование ускорения графического процессора на больших площадях). Свойство

CSS will-change будет правильным местом для пометки свойств, которые можно оптимизировать заранее.

...