在变换上舍入 CSS 子像素

问题描述 投票:0回答:2

所以,这个问题以前曾出现过,如下所示:翻译 + 画布 = 模糊文本 这里:CSS 翻译后是否可以“捕捉到像素”?

这些链接或我读过的任何其他文章似乎都没有任何结论。一些回复者认为这不够重要,值得关心,所以在我的情况下,这是因为:Screenshot in Chrome 41.0.2272.104Chrome 41.0.2272.104 中的屏幕截图

Screenshot in Safari 8.0.4 (10600.4.10.7)Safari 8.0.4 (10600.4.10.7) 中的屏幕截图

在 Safari 中查看损失详情? (看航天飞机图像中的结构,或第三张图像中岩石的细节)

这些家伙的 CSS 是

width: 100%;
height: auto;
position: relative;
top: 50%;
-webkit-transform: translateY(-50%);

因此,在某些情况下,translateY 最终会变成半个像素。左边的第一张图像最终得到一个变换矩阵,如下所示:

-webkit-transform: matrix(1, 0, 0, 1, 0, -56.5);

目前,chrome 似乎渲染得很好(我看到有些人说不同的浏览器在不同的版本中产生了这个问题),但目前 Safari 遇到了这个问题。所以,我解决这个问题的假设是确保只有整个像素,我已经通过在 JavaScript 中进行数学计算和应用转换来完成这一点,但是在运行大量图像时,这会花费更多的性能时间.

我尝试过一些仅 CSS 的 hack,例如使用scale3d,但没有成功。如果有人有任何无 JS 的解决方案,我将非常感谢分享的知识。

css rendering transform css-transforms
2个回答
4
投票

在某些浏览器中,您可以利用 calc 中的浮点舍入误差将数字舍入到所需的最接近的增量:

calc((2.55px * 5e-324) / 5e-324)

应使 2.55px 向上舍入为 3px。支持的浏览器为 Chrome(包括 Brave、Electron、Edge 和 Opera 等衍生品),不支持的浏览器为 IE、Firefox 和 Safari(包括 Midori 等衍生品)。值得庆幸的是,不支持的浏览器(IE、Firefox 和 Safari)只是将 calc 视为无效属性值而忽略,因为使用的数字超出了可接受的范围。因此,要利用此功能,只需使用下面的示例来生成 CSS 以满足您的需求。是的,我知道这个生成器并不总是组合相似的术语,是的,有一个原因:组合这些相似的术语会创建一个无法存储的数字。

var unit = document.getElementById('unit'),
  precision = document.getElementById('precision'),
  property = document.getElementById('prop'),
  output = document.getElementById('output');

function formatProp(x) {
  return (property.value.indexOf('%s') ?
      property.value.replace(/%s/g, x) :
      proprty.value + x).replace(/\\n/g, '\n')
    .replace(/\\t/g, '\t').replace(/\\r/g, '\r');
}
(unit.oninput = precision.oninput = property.oninput = function() {
  var Val = parseFloat(precision.value),
    V1 = "5e-324",
    V2 = "5e-324";
  if (Val < 1)
    V1 = V2 = '' + 5e-324 / Val;
  else if (Val > 1)
    V2 += ' * ' + Val, V1 += ' / ' + Val;

  output.textContent = formatProp(unit.value) + ';       /* for IE and FF*/\n' + formatProp('calc((' + unit.value + ' * ' + V1 + ') / ' + V2 + ')') + ';';
})();
CSS Unit: <input type="text" id="unit" value="-50%" style="width:14em" /><br /> Property : <input type="text" id="prop" value="-webkit-transform: translateY(%s);\ntransform: translateY(%s)" style="width:40em" /><br /> Round to: <input type="number" id="precision"
  value="1" style="width:14em" /> pixels (can be decimal)<b5 />
<pre id="output" style="background:#eee"> </pre>

请注意,根据实时响应的语言定义,是的,您可以在上面的演示中输入自己的值,是的,将实时生成相应的CSS。

我创建的测试页面:有目的的舍入错误浏览器支持测试

请注意,虽然上面的图表目前支持浏览器,但它很可能会发生变化,因为利用舍入误差有点不标准:W3C 规范仅在浮点数的定义中暗示它们,但永远不会明确指出浏览器需要实现次正常浮点表示法或舍入错误。


0
投票

.my-thing {
    /* Some %-based transform causing the element 
       to fall on a sub-pixel and blur on screen. */
    transform: translateX(-50%);

    /* Snaps transform to whole px values to avoid blurry lines */
    perspective: 1px;
}

这对我今天有用(在 Chrome 中测试)

© www.soinside.com 2019 - 2024. All rights reserved.