Подтвердить что ты не робот

Анимация Webkit оставляет на экране нежелательные пиксели

Следующий код помещает на экран белое окно. Если вы запустите это на 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); }

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

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

4b9b3361

Ответ 1

Решение

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

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

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

outline: 1px solid transparent;

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

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

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

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

Ответ 2

Что я буду делать:

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

Обязательно проверьте, не влияет ли разрешающее аппаратное ускорение на родителя.

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

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

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