CSS плохой рендеринг в translateZ () vs scale()

Я заметил, что есть большая разница в качестве при преобразовании текста в этом 2 способами:

.text1 {
  width: 200px;
  height: 22px;
  position: absolute;
  top: 40%;
  left: 0;
  transform-origin: 50% 50%;
  transform: scale(2); /* here */
  color: red;
  text-align: center;
  font-size: 22px;
}
.text2 {
  width: 200px;
  height: 22px;
  position: absolute;
  top: 60%;
  left: 0;
  transform-origin: 50% 50%;
  transform: translateZ(400px); /* here */
  text-align: center;
  font-size: 22px;
}
.perspective {
  width: 200px;
  height: 200px;
  perspective: 800px;
  transform-style: preserve-3d;
}
<div class="perspective">
  <div class="text1">Text</div>
  <div class="text2">Text</div>
</div>

есть ли способ заставить лучший рендеринг при перемещении текста по оси Z?

2 ответов


причина, по которой текст размывается, когда вы трансформируетесь с translateZ(400px) это это 3D-преобразование ; браузер рассматривает элемент как текстуры вместо векторов, чтобы обеспечить аппаратное 3D-ускорение.
Поэтому в основном разрешение будет ниже при увеличении размера.

С другой стороны преобразование со шкалой-это 2D-преобразование, браузер рассматривает элемент как вектор, а размытие-нет происходить.


посмотрите, что происходит с scale как только мы начнем с 3d, фактически не устанавливая никаких translateZ значение:

.text1 {
    width: 200px;
    height: 22px;
    position: absolute;
    top: 40%;
    left: 0;
    transform-origin: 50% 50%;
    transform: scale(2);
    /* here */
    color: red;
    text-align: center;
    font-size: 22px;
}
.text1a {
    width: 200px;
    height: 22px;
    position: absolute;
    top: 40%;
    left: 50%;
    transform-origin: 50% 50%;
    transform: translateZ(0) scale(2);
    /* here */
    color: blue;
    text-align: center;
    font-size: 22px;
}
.text2 {
    width: 200px;
    height: 22px;
    position: absolute;
    top: 60%;
    left: 0;
    transform-origin: 50% 50%;
    transform: translateZ(400px);
    /* here */
    text-align: center;
    font-size: 22px;
}
.perspective {
    width: 200px;
    height: 200px;
    perspective: 800px;
    transform-style: preserve-3d;
}
<div class="perspective">
    <div class="text1">Text</div>
    <div class="text1a">Text</div>
    <div class="text2">Text</div>
</div>

единственный обходной путь, который я могу придумать на данный момент, - это проверка таблицы стилей через JS и переопределение translateZ С transform: scale

var styles = document.styleSheets;

//patterns
var perspPat = /perspective\s*?:\s*?(\d+)/;
var transZPat = /translateZ\(\s*?(\d+)/;

var perspective;
var translateZ = [];
[].slice.call(styles).forEach(function (x) {
    [].slice.call(x.rules).forEach(function (rule) {
        if (perspPat.test(rule.cssText)) {
            perspective = perspPat.exec(rule.cssText)[1]
        };
        if (transZPat.test(rule.cssText)) {
            translateZ.push([
            rule.selectorText,
            transZPat.exec(rule.cssText)[1]]);
        }


    });

})


translateZ.forEach(function (x) {
    document.querySelector(x[0]).style.transform = 'scale(' + perspective / x[1] + ')';

})

скрипка

как вы можете видеть, даже если он работает, нужно много оптимизации.. (Я не считал бы его готовым к производству в его текущем состоянии ).


вы можете добавить шрифт-smooth (для firefox) и сглаживание для webkit

 .text2 {
    -webkit-font-smoothing: antialiased;
    font-smooth: always;
 }

https://developer.mozilla.org/en-US/docs/Web/CSS/font-smooth

http://davidwalsh.name/font-smoothing