如何在 Safari 中进行 WebKit 3D 转换后强制重新渲染

发布于 2024-10-11 00:31:46 字数 358 浏览 6 评论 0原文

我使用 CSS 3D 转换来缩放 div,例如:

-webkit-transform: scale3d(2,2,1);

缩放本身在任何 WebKit 浏览器中都可以正常工作。但是,在 Safari(移动设备或 Windows)上使用此功能时,div 的内容不会重新呈现。结果是缩放后内容变得模糊。

仅当使用 3D 变换时才会出现此效果。 时一切正常

使用-webkit-transform:scale(2);

。为了在 iPhone/iPad 上利用硬件加速,最好使用 3D 转换。

有谁知道如何告诉 Safari 以新的比例重新渲染 div?

I'm using CSS 3D transformations to zoom a div, for example:

-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.

This effect only occurs when using 3D transformations. Everything works fine when using

-webkit-transform: scale(2);.

In order to exploit hardware acceleration on iPhone/iPad, it would be nice to use the 3D transformations.

Does anybody know how to tell Safari to re-render a div with the new scale?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

零度℉ 2024-10-18 00:31:46

文本模糊的原因是Webkit将文本视为图像,我猜这是硬件加速的代价。我假设您在 ui 中使用过渡或动画关键帧,否则性能提升可以忽略不计,您应该切换到非 3d 变换。

您可以:

• 为transitionend 添加一个事件侦听器,然后将3d 变换替换为标准变换,例如...

element.addEventListener("transitionend", function() {
  element.style.webkitTransform = 'scale(2,2)'
},false);

• 由于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);
}

并且你会在悬停时得到一个清晰的文本。我在这里做了一个演示(也适用于 iOS):

http://duopixel.com/stack/scale.html

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.

You can either:

• Add an eventlistener for transitionend and then replace the 3d transform for a standard transform, such as...

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...

 #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):

http://duopixel.com/stack/scale.html

倒数 2024-10-18 00:31:46

我发现当出于其他原因尝试在 safari 中强制重绘 div 时(重新计算悬停时的文本溢出),这很简单:

selector {
    /* your rules here */
}
selector:hover {
    /* your rules here */
}
selector:hover:after {
    content:"";
}

我在悬停时做了一些更改填充以适应某些按钮的操作,但在 safari/chrome 中却没有无法正确重新计算内容,添加 :after 伪类就可以解决问题。

I found when trying to force a redraw of a div in safari for other reasons (recalculate text-overflow on hover), that is simple:

selector {
    /* your rules here */
}
selector:hover {
    /* your rules here */
}
selector:hover:after {
    content:"";
}

I did something on hover that changes the padding to accommodate some buttons, but in safari/chrome it doesn't recalculate the content correctly, adding the :after pseudo-class did the trick.

初与友歌 2024-10-18 00:31:46

我正在尝试做同样的事情。我认为这里发生的事情是 Safari 只是缩放像素。也就是说,它执行所有“正常”浏览器渲染,然后缩放结果的像素。

示例:将相对高质量的图像(例如 1000x1000 像素)放置在一个小 div(200x200 像素)中,并将图像设置为 100% 宽度和高度。当您将 div 进行 3D 变换以缩放 5 倍时,结果在 Safari 中将变得模糊,而在 Chrome 中将变得清晰。使用 2D 变换,图像在两者中都会显得清晰。

解决方法是在完成 3D 变换后转换为 2D 变换。但是,我发现在转换之间进行转换时存在轻微的延迟,因此这对我来说效果不太好。

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.

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.

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.

沫离伤花 2024-10-18 00:31:46

我找不到在 Safari 中使放大不模糊的修复程序(桌面版 v7.0.2 以及 iOS 6.1.3 和 7.0.6 中包含的那个),但我在某个时候做到了,请注意,当我在我将比例设置为 5。我不知道为什么,因为我的代码版本在我所做的所有后续更改中都丢失了。所有其他比例因子都是模糊的。

由于 iPhone 和 iPad 是该项目的目标设备,我最终放弃了比例变换和动画图像高度。我很失望 Safari 团队决定以一种在很多情况下使它们成为不可行的选择的方式来实现转换。

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.

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.

热血少△年 2024-10-18 00:31:46

嗯...我在尝试使用 Chrome 53 放大谷歌地图图像(hidpi)时遇到了同样的问题。

到目前为止我找到的唯一解决方案是隐藏图像(或包含图像的 div),然后再次显示。可以使用 opacity=0 或visibility=hidden,但实际上它必须至少在一两帧内不可见。

顺便说一句,这甚至不是 3d 变换。只是 2D 的东西。

Hmmm... I'm getting the same issue trying to scale up google maps images (hidpi) with Chrome 53.

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.

This, BTW, isn't even a 3d transform. Just 2D stuff.

烟若柳尘 2024-10-18 00:31:46

嗯...我在尝试使用 Chrome 53 放大谷歌地图图像(hidpi)时遇到了同样的问题。

一种解决方案是隐藏(不透明度、可见性)图像几帧(或包装图像/图像的容器) /无论它是什么)......我在另一篇关于SO的文章中找到的更好的解决方案是这个(在包含DIV上发布):

e.style.transform = 'translateZ(0) scale(1.0, 1.0)'

顺便说一句,我的东西只是普通的2d东西,translateZ似乎有所作为,尽管我从来没有碰过任何 3d 的东西。

Hmmm... I'm getting the same issue trying to scale up google maps images (hidpi) with Chrome 53.

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):

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文