简体   繁体   English

CSS3 转换:matrix3d 在 Chrome、Edge 和 Safari 与 Firefox 中给出其他结果

[英]CSS3 transform: matrix3d gives other results in Chrome, Edge & Safari vs Firefox

I am trying to place 2 images on top of each other in an SVG using the css transform matrix3d.我正在尝试使用 css 变换矩阵 3d 在 SVG 中将 2 个图像彼此叠加。 In Firefox this looks fine, but in Chrome, Safari & Edge I get a different result.在 Firefox 中,这看起来不错,但在 Chrome、Safari 和 Edge 中,我得到了不同的结果。

Anyone has got any idea what I am doing wrong or if there are some sort of limitations?任何人都知道我做错了什么或者是否存在某种限制?

Relevant code:相关代码:

<svg width="1920" height="1080" class="picture">
    <image xlink:href="/images/psv/screenreplace/exposure-led-wall.jpg" width="1920" height="1080"></image>
    <image id="screen-image-0" xlink:href="https://youreka-virtualtours.be/screenreplacer/362/1/logos/wallpaper4-1670251089552.jpg" width="640" height="252"></image>
    <defs>
        <style>
            #screen-image-0 {
                transform:matrix3d(1.52966, 0.704576, 0, 0.00068864, -0.0772169, 1.48607, 0, -0.00014322, 0, 0, 1, 0, 910, 299, 0, 1);
            } 
        </style>
    </defs>
</svg>

The result in Firefox: Firefox中的结果: 火狐

The result in the other browsers:其他浏览器的结果: 铬等

The issue is that Safari and Chrome do convert your 3D matrix to a 2D one.问题是 Safari 和 Chrome 确实将您的 3D 矩阵转换为二维矩阵。
It's not entirely clear who is right here.目前还不完全清楚谁就在这里。

Some CSS attributes must map to SVG presentation attributes .有些CSS属性必须map到SVG 表示属性 transform is one of these, so it's normal you can set an SVG element's transform through CSS. However, the SVG transform attribute is far from being clear. transform就是其中之一,所以通过 CSS 设置一个 SVG 元素的transform是正常的。但是,SVG transform属性远未明确。 Current specs state当前规格 state

8.5. 8.5. The 'transform' property “变换”属性

User agents must support the transform property and presentation attribute as defined in [css-transforms-1] .用户代理必须支持[css-transforms-1]中定义的transform属性和 presentation 属性。

And when we follow this [css-transforms-1] we end on two links, both stating当我们遵循这个[css-transforms-1]时,我们以两个链接结束,都说明

This specification is the convergence of the CSS 2D Transforms and SVG transforms specifications.该规范是CSS 二维变换SVG 变换规范的集合。

Only this latter document does talk about 3D transforms.只有后一个文档确实讨论了 3D 次转换。 But the "convergence" documents, that do actually rule, completely ignore it.但实际上确实有规定的“融合”文件却完全忽略了它。

Even the DOM interfaces that are supposed to reflect the current transformation matrix applied on the element are defined to be 2D only.甚至应该反映应用于元素的当前变换矩阵的DOM 界面也被定义为仅 2D。

So what should happen when we apply a 3D matrix to an SVG element?那么当我们将 3D 矩阵应用于 SVG 元素时会发生什么?

Interop issues apparently.互操作问题显然。

Chrome and Safari behavior kind of makes sense, they "filter" the matrix component to be only 2D just like what would happen if you were to modify the element's .transform.baseVal SVGTransformList . Chrome 和 Safari 的行为是有道理的,它们将矩阵组件“过滤”为仅 2D,就像您修改元素的.transform.baseVal SVGTransformList时会发生的情况一样。 Ie they do map 1-1 CSS and presentation attributes.即他们做 map 1-1 CSS 和表示属性。 Firefox on the other hand does what one would probably want to happen, ie they do respect the authored CSS rule.另一方面,Firefox 做了人们可能希望发生的事情,即他们确实尊重编写的 CSS 规则。
Once again, I'm not entirely sure which is correct.再一次,我不完全确定哪个是正确的。

 const button = document.querySelector("button"); const el = document.querySelector(".trans"); const list = el.transform.baseVal; const matrix = new DOMMatrix("matrix3d(1.5, 0.7, 0, 0.0007, -0.07, 1.48, 0, -0.00014, 0, 0, 1, 0, -800, 0, 0, 1)"); let newTransform; try { newTransform = list.createSVGTransformFromMatrix(matrix); } catch(err) { // Chrome doesn't support createSVGTransformFromMatrix(DOMMatrix)... const { a, b, c, d, e, f } = matrix; const mat = document.querySelector("svg").createSVGMatrix(); Object.assign(mat, { a, b, c, d, e, f }); newTransform = list.createSVGTransformFromMatrix(mat); } button.onclick = (evt) => { el.classList.remove("trans"); list.clear(); list.appendItem(newTransform); // Won't change anything in Chrome and Safari // Will make Firefox behave like the others };
 svg { height: 500px }.trans { transform: matrix3d(1.5, 0.7, 0, 0.0007, -0.07, 1.48, 0, -0.00014, 0, 0, 1, 0, -800, 0, 0, 1); }
 <button>apply matrix</button><br> <svg width="1920" height="1080" viewBox="0 0 1900 1200"> <rect class="trans" width="640" height="252"/> </svg>

Note that both Safari and Chrome do support 3D transforms on the root <svg> element, so you might be able to achieve the same result by using an other <svg> just to render that transformed image, but that enters the hack area and might not be trivial to get it right.请注意,Safari 和 Chrome 都支持根<svg>元素上的 3D 转换,因此您可以通过使用其他<svg>来渲染转换后的图像来获得相同的结果,但它会进入 hack 区域并可能做到正确并非易事。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM