Фоновое изображение Chrome растекается по краям с применением масштабных преобразований CSS

Я наблюдаю странное поведение после применения пары преобразований к элементам с фоновыми изображениями в Chrome.

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

Проблема в том, что я вижу верхний или левый край соседних кадров на изображении моего персонажа. Теперь это происходит только в определенных масштабах, но это хорошо видно и отвлекает. Для демонстрации я использую изображение размером 364x1328 с двумя кадрами. Верхний кадр содержит черный ящик без красного цвета в границах 364x664. Нижняя рамка сплошного красного цвета. Верхний кадр с выбранными границами отображается в моем редакторе изображений слева, а вывод из Chrome вставляется справа:

Границы кадра слева (364x664), вывод из Chrome справа

На выходе из Chrome вы можете четко видеть красную рамку внизу. Учитывая, что мое фоновое изображение содержится в поле размером 364x664, я ожидаю, что будут отображаться только пиксели, видимые в этом поле. Другими словами, я хотел бы видеть то, что я вижу в scale(1), но в уменьшенном масштабе. Кажется, что Chrome по какой-то причине передискретизирует фоновое изображение.

Чтобы упростить демонстрацию, я включил скрипт JS: http://jsfiddle.net/CL5Gh/.

<!DOCTYPE html>
<html>
<head>
<style>

#b
{
    -webkit-transform: scale(0.4775);
    -webkit-transform-origin: 0 0;
}

#d
{
    height: 664px;
    width: 364px;
    background-image: url(data:image/png,%89PNG%0D%0A%1A%0A%00%00%00%0DIHDR%00%00%01l%00%00%050%02%03%00%00%00%1A%F2%87%B5%00%00%00%2CtEXtCreation%20Time%00Sun%2017%20Feb%202013%2022%3A08%3A49%20%2B1000%FC%E8%C07%00%00%00%07tIME%07%DD%02%11%0B%1B%0B%C2%A0%3B8%00%00%00%09pHYs%00%00%1E%C1%00%00%1E%C1%01%C3iTS%00%00%00%04gAMA%00%00%B1%8F%0B%FCa%05%00%00%00%09PLTE%00%00%00%00%00%00%FF%00%00%3D%FB%DD-%00%00%00%01tRNS%00%40%E6%D8f%00%00%01%A4IDATx%DA%ED%CC1%0D%000%08%000%9EI%C4%24*11%C8%92%B5%02%1A%01%00%00%00%00%00%FC%E4%E45n%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%DB%ED%06%00%00%00%00%00%DESs%DCn%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%DB%EDv%BB%DDn%B7%7B%F3n%80%3C%CA%A7%B6%23%99%BC%00%00%00%00IEND%AEB%60%82);
    -webkit-transform: scale(0.4375);
}

</style>
</head>
<body>
  <div id="b">
    <div id="d">
    </div>
  </div>
</body>
</html>

Теперь я не уверен, что это каким-то образом зависит от видеокарты или машины. В скрипте вы увидите два примененных масштабных преобразования. Это имитация того, что происходит в моей игре. Первый — это масштабирование фона, а второй — масштабирование главного героя.

Буду признателен за любую помощь. Я рассматривал возможность заполнения каждого кадра отступом в 50 пикселей (сколько достаточно?), чтобы устранить проблему, но это кажется ужасно хакерским, и мне нужен реальный ответ.


person Benjamin Penney    schedule 17.02.2013    source источник
comment
я столкнулся с той же проблемой. похоже, это ошибка Chrome, поскольку последние версии Safari и Firefox отображают изображение отлично, с четкими краями.   -  person gondo    schedule 18.04.2014


Ответы (1)


Кажется, это потому, что преобразования CSS могут интерполировать субпиксельные позиции, поэтому, если позиция вашего элемента не соответствует пикселям, вы видите «эффект дабстепа» (см. http://paulirish.com/2012)./почему-перемещение-элементов-с-переводом-лучше-чем-posabs-topleft/).

Поскольку scale нельзя эмулировать с помощью CSS2 (в отличие от translate в статье), боюсь, решения нет.

Если конкретное правило CSS3 не существует или не будет существовать, я ищу его.

РЕДАКТИРОВАТЬ: -webkit-backface-visibility: hidden; сделать трюк на Chromium, не знаю, почему...

person MatTheCat    schedule 17.02.2013
comment
Спасибо! Это работает, хотя каким-то образом изменяет алгоритм изменения размера. Края кажутся менее гладкими, и я не знаю, почему. - person Benjamin Penney; 18.02.2013
comment
Упс, кажется, я говорил слишком рано. Хотя это делает изображение намного более четким, все еще есть случаи, когда я получаю кровотечение за пределами кадра. Я думаю, что мне действительно нужно что-то, что имитирует -moz-image-rect, чтобы нарезать изображение. - person Benjamin Penney; 18.02.2013