Как заставить повторную визуализацию после преобразования WebKit 3D в Safari

Я использую CSS 3D-преобразования для увеличения div, например:

-webkit-transform: scale3d(2,2,1);

Сам масштабирование отлично работает в любом браузере WebKit. Однако при использовании этого в Safari (мобильный или Windows) содержимое div не повторно отображается. В результате содержимое становится размытым после масштабирования.

Этот эффект возникает только при использовании 3D-преобразований. Все работает отлично при использовании

-webkit-transform: scale(2);.

Чтобы использовать аппаратное ускорение на iPhone/iPad, было бы неплохо использовать 3D-преобразования.

Кто-нибудь знает, как сказать Safari повторно отобразить div с новым масштабом?

Ответ 1

Причина размытости текста заключается в том, что Webkit обрабатывает текст как изображение, я предполагаю, что цена на аппаратное ускорение. Я предполагаю, что вы используете переходы или ключевые кадры анимации в своем ui, в противном случае прирост производительности пренебрежимо мал, и вы должны переключиться на не-3d-преобразования.

Вы можете:

• Добавить eventlistener для перехода и затем заменить 3D-преобразование стандартным преобразованием, например...

element.addEventListener("transitionend", function() {
  element.style.webkitTransform = 'scale(2,2)'
},false);

• Так как Webkit рассматривает материал как изображение, лучше начинать большие и уменьшать масштаб. Итак, напишите свой css в своем "конечном состоянии" и уменьшите его для нормального состояния...

 #div {
  width: 200px; /*double of what you really need*/
  height: 200px; /*double of what you really need*/
  webkit-transform: scale3d(0.5, 0.5, 1);
}

 #div:hover {
  webkit-transform: scale3d(1, 1, 1);
}

И вы получите хрустящий текст при наведении. Я сделал демо здесь (тоже работает на iOS):

http://duopixel.com/stack/scale.html

Ответ 2

Я обнаружил, что при попытке заставить перерисовать div в сафари по другим причинам (пересчитать переполнение текста при наведении), это просто:

selector {
    /* your rules here */
}
selector:hover {
    /* your rules here */
}
selector:hover:after {
    content:"";
}

Я сделал что-то на hover, которое меняет прописку, чтобы разместить некоторые кнопки, но в сафари /chorme он не пересчитывает содержимое правильно, добавив: после псевдокласса сделал трюк.

Обратите внимание, что я нигде не нашел этого в Интернете, я обнаружил его во время игры.

Ответ 3

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

Пример. Поместите изображение с относительно высоким качеством (скажем, 1000x1000 пикселей) в маленьком div (200x200 пикселей) и установите для изображения 100% ширину и высоту. Когда вы 3D преобразуете div в 5 раз, результат будет размытым в Safari и четким в Chrome. Используйте 2D-преобразование, и изображение будет выглядеть четким в обоих.

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

Ответ 4

Я не смог найти исправление для того, чтобы сделать невозможным смазывание в Safari (рабочий стол v7.0.2 и тот, который включен в iOS 6.1.3 и 7.0.6), но в какой-то момент я заметил, что у меня есть sharp png, когда я устанавливаю масштаб на 5. Я не знаю, почему, поскольку эта версия моего кода теряется во всех последующих изменениях, которые я сделал. Все другие масштабные факторы были размытыми.

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

Ответ 5

Хммм... Я получаю ту же проблему, которая пытается увеличить изображения карт Google (hidpi) с помощью Chrome 53.

Единственное решение, которое я нашел до сих пор, - это скрыть изображение (или div, содержащее изображения), а затем снова показать его. Может быть с opacity = 0 или visibility = hidden, но на самом деле он должен быть невидим для хотя бы кадра или двух.

Это, BTW, даже не является 3D-преобразованием. Просто 2D-материал.

Ответ 6

Хммм... Я получаю ту же проблему, которая пытается увеличить изображения карт Google (hidpi) с помощью Chrome 53.

Одним из решений является скрыть (непрозрачность, видимость) изображение для нескольких кадров (или контейнер, обертывающий изображение/изображения/что бы это ни было)... лучшее решение, которое я нашел в другом сообщении на SO, было таким ( выданное на DIV):

e.style.transform = 'translateZ(0) scale(1.0, 1.0)'

Кстати, мои вещи были всего лишь обычным 2-м материалом, переводчик Z, похоже, имеет значение, хотя я никогда не касался ничего 3d.