使用transform:scale防止模糊渲染 [英] Preventing blurry rendering with transform: scale

查看:329
本文介绍了使用transform:scale防止模糊渲染的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用transform属性缩放了一个 div ,但我想保留它的子元素(它们的 1px 宽度或高度)相同的大小。我用 .5 对它们进行反比例缩放,预期结果是 1px 的元素缩放2,然后.5,最终应该回到 1px ,但它们会产生模糊的 2px



缩放前的方框如下:

  .container {width:200px; height:200px; margin:100px;背景颜色:#EEE; position:absolute;}。outline {position:absolute;背景:#1899ef; z-index:999999; opacity:1!important;}。outlineBottom,.outlineTop {width:100%; height:1px;} outlineLeft,.outlineRight {height:100%; width:1px;} outlineRight {right:0px;}。outlineBottom {bottom:0px;}  

 < div class =container> < div class =outline outlineTop>< / div> < div class =outline outlineRight>< / div> < div class =outline outlineBottom>< / div> < div class =outline outlineLeft>< / div>< / div>  

正如您所看到的,边缘的元素是一个清晰的,深色的 1px 蓝色。不过,缩放后的框看起来像是

=truedata-console =falsedata-babel =false>

  .container {width:200px; height:200px; margin:100px;背景颜色:#EEE;位置:绝对; transform:scale(2);}。outline {position:absolute;背景:#1899ef; z-index:999999;不透明度:1!重要; transform:scale(.5);}。outlineBottom,.outlineTop {width:100%; height:1px; transform:scale(1,.5);}。outlineLeft,.outlineRight {height:100%;宽度:1px; transform:scale(.5,1);}。outlineRight {right:0px;}。outlineBottom {bottom:0px;}  

 < div class =container> < div class =outline outlineTop>< / div> < div class =outline outlineRight>< / div> < div class =outline outlineBottom>< / div> < div class =outline outlineLeft>< / div>< / div>  

此处是来自Chrome 41.0.2272.89的后期比例呈现 Mac,这就是我正在运行的。



添加 transform-3d(0,0,0) 似乎没有帮助。使用解决方案。使用css-transform-scale-in-chrome> zoom 属性,但由于缩放没有得到很好的支持我想避免这种情况。添加 filter:blur(0px); 也没有任何效果。



在聊天中假定可能儿童首先被缩放为 .5 ,然后将其大小加倍,使它们缩小到 .5px ,然后从那里备份。有没有办法确保它们被渲染的顺序导致它们首先被放大到 2px 然后减半?根据我的判断,我尝试强制JS使用渲染命令,但毫不奇怪的是,没有(但有趣的是,最底层的元素保持了原来的颜色)。



如果失败了,还有其他的解决方案吗?我不能成为唯一遇到这个问题的人。 c> transform-origin 在缩放的元素上。对于任何正在转换的元素,它默认为 50%50%,但在缩小1px值时会产生问题,因为它必须以 code>放在一个半像素上,并且元素的渲染从此出现问题。你可以看到它在 transform-origin 中移动到每个项目的相关极值。



有点显示这种相同的模糊会发生在任何尺寸的缩放元素上,其中缩放最终将像素减半。

body {padding:1em ;}。container {width:200px; height:200px; margin:100px;背景颜色:#EEE;位置:绝对; transform:scale(2);}。outline {position:absolute;背景:#1899ef; z-index:999999; opacity:1!important;}。outlineBottom,.outlineTop {width:100%; height:1px; transform:scale(1,0.5);}。outlineBottom {bottom:0; transform-origin:0 100%;}。outlineTop {transform-origin:0 0;}。outlineLeft,.outlineRight {height:100%;宽度:1px; transform:scale(.5,1);}。outlineRight {right:0px; transform-origin:100%0;}。outlineLeft {left:0px; transform-origin:0 0;}

< div class = 容器 > < div class =outline outlineTop>< / div> < div class =outline outlineRight>< / div> < div class =outline outlineBottom>< / div> < div class =outline outlineLeft>< / div>< / div>

b

I'm scaling a div up with the transform property, but I want to keep its children (which have 1px width or height) the same size. I counter-scaled them by .5, with the expected result that an element of 1px scaled by 2, and then .5, should end up back at 1px, but they wind up a blurry 2px.

Here's the box before scaling it:

.container {
    width: 200px;
    height: 200px;
    margin: 100px;
    background-color: #EEE;
    position: absolute;
}

.outline {
    position: absolute;
    background: #1899ef;
    z-index: 999999;
    opacity: 1 !important;
}

.outlineBottom, .outlineTop {
  width: 100%;
  height: 1px;
}

.outlineLeft, .outlineRight {
    height: 100%;
    width: 1px;
}

.outlineRight {
    right: 0px;
}

.outlineBottom {
    bottom: 0px;
}

<div class="container">
    <div class="outline outlineTop"></div>
    <div class="outline outlineRight"></div>
    <div class="outline outlineBottom"></div>
    <div class="outline outlineLeft"></div>
</div>

As you can see, the elements at the edges are a clear, dark 1px blue. Here's what the box looks like after scaling, though:

.container {
    width: 200px;
    height: 200px;
    margin: 100px;
    background-color: #EEE;
    position: absolute;
    transform: scale(2);
}

.outline {
    position: absolute;
    background: #1899ef;
    z-index: 999999;
    opacity: 1 !important;
    transform: scale(.5);
}

.outlineBottom, .outlineTop {
  width: 100%;
  height: 1px;
  transform: scale(1,.5);
}

.outlineLeft, .outlineRight {
    height: 100%;
    width: 1px;
    transform: scale(.5,1);
}

.outlineRight {
    right: 0px;
}

.outlineBottom {
    bottom: 0px;
}

<div class="container">
    <div class="outline outlineTop"></div>
    <div class="outline outlineRight"></div>
    <div class="outline outlineBottom"></div>
    <div class="outline outlineLeft"></div>
</div>

And here's a post-scaled render from Chrome 41.0.2272.89 Mac, which is what I'm running.

Adding transform-3d(0, 0, 0) didn't appear to help. A solution was found using the zoom property, but since zoom isn't well supported I'd like to avoid that. Adding filter: blur(0px); didn't appear to have any effect either.

It was posited in chat that perhaps the children are first scaled to .5 and then doubled in size, causing them to be scaled down to .5px and then back up from there. Is there any way to ensure the order that they're rendered in causes them to first be scaled up to 2px and then halved? Against my better judgement, I tried forcing the render order with JS, but unsurprisingly, that didn't have any effect (though, interestingly, the bottom element did maintain its original color).

Failing that, are there any other solutions floating around out there? I can't be the only one who's run into this problem.

解决方案

It is to do with the default transform-origin on the scaled elements. It defaults to 50% 50% for any element being transformed, but this has issues when scaling down 1px values as it has to centre the scale on a half pixel and the rendering of the elements has issues from here on out. You can see it working here with the transform-origin moved to the relevant extremes for each item.

A bit of playing about shows that this same blurring happens on scaled elements for any dimension where the scaling ends up halving a pixel.

body {
    padding: 1em;
}

.container {
    width: 200px;
    height: 200px;
    margin: 100px;
    background-color: #EEE;
    position: absolute;
    transform: scale(2);
}

.outline {
    position: absolute;
    background: #1899ef;
    z-index: 999999;
    opacity: 1 !important;
}

.outlineBottom, .outlineTop {
    width: 100%;
    height: 1px;
    transform: scale(1, 0.5);
}

.outlineBottom {
    bottom: 0;
    transform-origin: 0 100%;
}

.outlineTop {
    transform-origin: 0 0;
}

.outlineLeft, .outlineRight {
    height: 100%;
    width: 1px;
    transform: scale(.5,1);
}

.outlineRight {
    right: 0px;
    transform-origin: 100% 0;
}

.outlineLeft {
    left: 0px;
    transform-origin: 0 0;
}

<div class="container">
    <div class="outline outlineTop"></div>
    <div class="outline outlineRight"></div>
    <div class="outline outlineBottom"></div>
    <div class="outline outlineLeft"></div>
</div>

这篇关于使用transform:scale防止模糊渲染的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆