CSS 如何在 Safari 中的 WebKit 3D 转换后强制重新渲染
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4641522/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to force re-render after a WebKit 3D transform in Safari
提问by FatCat123
I'm using CSS 3D transformations to zoom a div, for example:
我正在使用 CSS 3D 转换来缩放 div,例如:
-webkit-transform: scale3d(2,2,1);
The scaling itself works fine in any WebKit browser. However, when using this on Safari (mobile or Windows), the content of the div is not re-rendered. The result is that the content gets blurred after scaling.
缩放本身在任何 WebKit 浏览器中都可以正常工作。但是,在 Safari(移动设备或 Windows)上使用它时,不会重新渲染 div 的内容。结果是缩放后内容变得模糊。
This effect only occurs when using 3D transformations. Everything works fine when using
此效果仅在使用 3D 转换时发生。使用时一切正常
-webkit-transform: scale(2);
.
-webkit-transform: scale(2);
.
In order to exploit hardware acceleration on iPhone/iPad, it would be nice to use the 3D transformations.
为了在 iPhone/iPad 上利用硬件加速,最好使用 3D 转换。
Does anybody know how to tell Safari to re-render a div with the new scale?
有人知道如何告诉 Safari 使用新比例重新渲染 div 吗?
回答by methodofaction
The reason why the text is blurry is because Webkit is treating the text as an image, I guess it's the price of being hardware accelerated. I'm assuming you are using transitions or animation keyframes in your ui, otherwise the performance gains are negligible and you should switch to non-3d transforms.
文字模糊的原因是因为Webkit 把文字当做图像处理,我猜这是硬件加速的代价。我假设您在 ui 中使用过渡或动画关键帧,否则性能提升可以忽略不计,您应该切换到非 3d 转换。
You can either:
您可以:
? Add an eventlistener for transitionend and then replace the 3d transform for a standard transform, such as...
? 为 transitionend 添加事件侦听器,然后将 3d 变换替换为标准变换,例如...
element.addEventListener("transitionend", function() {
element.style.webkitTransform = 'scale(2,2)'
},false);
? Since Webkit treats stuff as an image, it's better to start big and scale down. So, write your css in your "end state" and scale it down for your normal state...
? 由于 Webkit 将内容视为图像,因此最好从大开始并按比例缩小。所以,在你的“最终状态”中编写你的 css 并将其缩小到你的正常状态......
#div {
width: 200px; /*double of what you really need*/
height: 200px; /*double of what you really need*/
webkit-transform: scale3d(0.5, 0.5, 1);
}
#div:hover {
webkit-transform: scale3d(1, 1, 1);
}
And you get a crispy text on hover. I made a demo here (works on iOS too):
你会在悬停时得到一个清晰的文本。我在这里做了一个演示(也适用于 iOS):
回答by Rodrigo
I found when trying to force a redraw of a div in safari for another reasons (recalculate text-overflow on hover), that is simple:
我发现当由于另一个原因(重新计算悬停时的文本溢出)而试图在 safari 中强制重绘 div 时,这很简单:
selector {
/* your rules here */
}
selector:hover {
/* your rules here */
}
selector:hover:after {
content:"";
}
I did something on hover that changes the padding to accomodate some buttons, but in safari/chorme it doesnt recalculate the content correctly, adding the :after pseudoclass did the trick.
我在悬停时做了一些改变填充以适应一些按钮的事情,但是在 safari/chorme 中它没有正确地重新计算内容,添加 :after 伪类做到了这一点。
Note that I did not find this anywhere on the internet, I discovered it when fiddling.
请注意,我没有在互联网上的任何地方找到它,我是在摆弄时发现的。
回答by JoshNaro
I'm trying to do the same thing. I think what's happening here is that Safari is just scaling pixels. That is, it does all its "normal" browser rendering and then scales the pixels of the result.
我正在尝试做同样的事情。我认为这里发生的事情是 Safari 只是缩放像素。也就是说,它执行所有“正常”浏览器渲染,然后缩放结果的像素。
Example: Place a relatively high quality image (say 1000x1000 pixels) in a small div (200x200 pixels) and set the image to 100% width and height. When you 3D transform the div to scale 5 times, the result will be blurry in Safari and crisp in Chrome. Use a 2D transform and the image will appear crisp in both.
示例:将相对高质量的图像(例如 1000x1000 像素)放在一个小 div(200x200 像素)中,并将图像设置为 100% 的宽度和高度。当您将 div 3D 转换为缩放 5 倍时,结果在 Safari 中会很模糊,而在 Chrome 中会很清晰。使用 2D 变换,图像在两者中都会显得清晰。
A workaround is to convert to a 2D transform after you are done with the 3D. However, I've found there is a slight delay when converting between transforms so this isn't working too well for me.
解决方法是在完成 3D 后转换为 2D 变换。但是,我发现在转换之间进行转换时会有轻微的延迟,因此这对我来说效果不佳。
回答by Hoby
I couldn't find a fix for making zoom-ins not blur in Safari (desktop v7.0.2 and the one included in iOS 6.1.3 and 7.0.6) but I did at some point, notice that I got a sharp png when I set the scale to 5. I don't know why, since that version of my code is lost in all the subsequent changes I made. All other scale factors were blurry.
我找不到在 Safari(桌面版 v7.0.2 和 iOS 6.1.3 和 7.0.6 中包含的那个)中使放大不模糊的修复程序,但我在某个时候做了,注意我得到了一个清晰的 png我将比例设置为 5。我不知道为什么,因为我所做的所有后续更改都丢失了该版本的代码。所有其他比例因子都是模糊的。
Since the iPhone and iPad are target devices for this project I ended up abandoning scale transform and animating image height instead. I'm disappointed that the Safari team decided to implement transforms in a way that make them an unviable option in so many cases.
由于 iPhone 和 iPad 是这个项目的目标设备,我最终放弃了缩放变换和动画图像高度。我很失望 Safari 团队决定以某种方式实现转换,使它们在许多情况下成为不可行的选择。
回答by Orwellophile
Hmmm... I'm getting the same issue trying to scale up google maps images (hidpi) with Chrome 53.
嗯......我在尝试使用 Chrome 53 放大谷歌地图图像(hidpi)时遇到了同样的问题。
The only solution I've found so far is to hide the image (or a div that contains the images) and then show it again. Can be with opacity=0 or visibility=hidden, but it actually has to be invisible for at least a frame or two.
到目前为止,我找到的唯一解决方案是隐藏图像(或包含图像的 div),然后再次显示它。可以使用 opacity=0 或visibility=hidden,但实际上它必须至少在一两帧内不可见。
This, BTW, isn't even a 3d transform. Just 2D stuff.
顺便说一句,这甚至不是 3d 变换。只是二维的东西。
回答by Orwellophile
Hmmm... I'm getting the same issue trying to scale up google maps images (hidpi) with Chrome 53.
嗯......我在尝试使用 Chrome 53 放大谷歌地图图像(hidpi)时遇到了同样的问题。
One solution is to hide (opacity, visibility) the image for a few frames (or a container wrapping the image/images/whatever it is)... the better solution which I found in another post on SO was this (issued on the containing DIV):
一个解决方案是隐藏(不透明度,可见性)几帧的图像(或包装图像/图像/无论它是什么的容器)......我在另一篇关于 SO 的帖子中找到的更好的解决方案是这个(发布于包含 DIV):
e.style.transform = 'translateZ(0) scale(1.0, 1.0)'
BTW, my stuff was just ordinary 2d stuff, the translateZ seems to make the difference though, even though I never touched anything 3d.
顺便说一句,我的东西只是普通的 2d 东西,尽管我从未接触过任何 3d 东西,但 translateZ 似乎有所作为。