SVG转换 - 起源不适用于Chrome

Uco*_*dia 5 svg google-chrome

我有一个基于SVG的应用程序,大量使用转换,如翻译,旋转和缩放.虽然我在Firefox中没有问题,但在Chrome中,该transform-origin属性不会被考虑在内.它似乎应用了用户代理默认值0px 0px 0.

这是一个例子(JSFiddle):

<svg width="400" height="400">
  <defs>
    <rect id="shape" width="200" height="200"/>
  </defs>
  <g transform="translate(100,100)">
    <use xlink:href="#shape" style="stroke: lightgray; fill: transparent;"/>
    <ellipse cx="100" cy="100" rx="3" ry="3" style="fill: black;"/>
    <g transform="translate(0,0) scale(0.5) rotate(45)" style="transform-origin: 100px 100px;">
      <use xlink:href="#shape" style="stroke: black; fill: transparent;"/>
    </g>
  </g>
</svg>
Run Code Online (Sandbox Code Playgroud)

变换起源问题

正如您所看到的,无论定义的原点如何,Chrome都会应用从形状左上角开始的所有变换,而Firefox则会考虑定义的原点.

我错过了一些关于如何transform-origin使用SVG的内容吗?

有没有人真正找到一种方法来解决这个问题而不用翻译补偿?

Uco*_*dia 11

我正在回答我自己的问题,以便完全澄清transform-originSVG 1.1转换函数的属性以及如何在Chrome 48中克服这个问题.


首先,transform-origin是纯CSS 3属性,它与SVG 1.1完全无关.尽管transform听起来很像transform-origin,但它们适用于不同的系统.transform存在于CSS 3和SVG 1.1中,但具有单独的实现.transform-origin 仅存在于CSS 3中,因此不应影响SVG 1.1.transform-origin预计对Chrome 48中的SVG没有影响的事实.

那么为什么transform-origin在Firefox 44中应用SVG呢?原因并不完全清楚,但似乎是Mozilla正在努力慢慢为Firefox中的SVG 2提供支持的一部分.事实上,对于SVG 2,一切都将成为CSS 3转换(没有单独的实现),因此SVG将获得支持transform-origin.我在Sara Soueidan的关于SVG坐标系的优秀文章中发现了这一点.


现在怎么可以说在Chrome 48要克服这是相当简单的,但如果你想申请translate(),scale()rotate()所有的同时,你还需要计算偏移引起的缩放,并在您的翻译补偿.

正如Bobby Orndorff在他的回答中提到的,实际上可以rotate()通过提供额外的x和y参数来为函数提供旋转中心.这已经是一个很大的进步.但不幸的是,该scale()功能不支持这样的功能,并且总是从其父级的左上角缩放.因此,您仍需要更正翻译,以便模拟中心周围的比例.

以下是适用于Chrome 48和Firefox 44的最终解决方案:

<svg width="400" height="400">
  <defs>
    <rect id="shape" width="200" height="200"/>
  </defs>
  <g transform="translate(100,100)">
    <use xlink:href="#shape" style="stroke: lightgray; fill: transparent;"/>
    <ellipse cx="100" cy="100" rx="3" ry="3" style="fill: black;"/>
    <g transform="translate(50,50) scale(0.5) rotate(45, 100, 100)">
      <use xlink:href="#shape" style="stroke: black; fill: transparent;"/>
    </g>
  </g>
</svg>
Run Code Online (Sandbox Code Playgroud)