在变换上舍入CSS子像素

时间:2015-03-25 21:02:08

标签: css3 rendering transform css-transforms

所以,此问题已经出现过,例如:Translate + Canvas = Blurry Text 在这里:Is it possible to "snap to pixel" after a CSS translate?

似乎没有任何关于这些链接的结论 - 或者我读过的任何其他文章。一些响应者并不认为这很重要,所以这就是为什么我的情况是:Screenshot in Chrome 41.0.2272.104 Chrome浏览器中的屏幕截图41.0.2272.104

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

在Safari中查看详细信息? (看看航天飞机图像中的结构,或第3张图像中岩石中的细节)

这些人的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的黑客,比如使用scale3d但没有成功。如果有人有任何JS免费解决方案,我将非常感谢共享知识。

1 个答案:

答案 0 :(得分:2)

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

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

应该导致2.55px向上舍入到3px。该 支持浏览器的是Chrome和Opera,而不支持的浏览器是IE和Firefox。我不确定Safari。值得庆幸的是,不支持的浏览器,IE& Firefox,只是将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 + ')') + ';';
})();
&#13;
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>
&#13;
&#13;
&#13;

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

我创建的测试页面:purposeful-rounding-errors browser support test

请注意,虽然上面的图表功能目前支持浏览器,但它很容易改变,因为利用舍入错误是一种非标准:W3C规范仅在浮点数的定义中暗示它们,但是没有明确说明浏览器需要实现亚正常浮点表示法或舍入错误。

P.S。如果有权访问Safari的人可以访问test page,将页面保存为PDF或拍照,并在下面的评论中发布链接,以便我可以确认Safari是否支持此功能,那么这将是多少非常感谢。