旋转嵌套的SVG

4

我正在使用SVG.js尝试对SVG进行一些操作。之前我使用的是画布,但是我对它生成的图片质量非常失望,所以我决定使用纯SVG。

我已经将所有东西都改成了纯SVG方法,除了一个问题:旋转。

我无法使其工作。我很想使用SVG.js库提供的功能,但那没用。我也尝试过在元素内部调整,但也没有成功。到目前为止,我找到的最好的链接是这个,虽然他能够单独旋转图像,但没有显示如何同时旋转所有内容(这是我的情况)

我想要什么

我希望能够旋转我在Inkscape中创建的SVG图像(非常简单)

问题

完全没有旋转,尝试了几种方法和互联网上的意见。

我尝试过的方法

  • 使用transform属性和rotate(45)
  • 使用SVG.js内置方法
  • 阅读关于旋转不能应用于<g>标签的文章
  • 阅读有关SVG旋转与CSS不同的文章,尤其是在坐标系方面(例如css-tricks上的这个链接

问题示例

这里有一个简单的SVG播放器图像,我将其作为JS变量。该图像已创建并移动到坐标=(50,50)。最后我尝试将其旋转45度。(这没有帮助)

const player = '<svg width="11.214mm" height="6.3195mm" version="1.1" viewBox="0 0 11.214 6.3195" xmlns="http://www.w3.org/2000/svg">&gt;\n' +
    ' <g transform="translate(-172.04 62.213)">\n' +
    '  <g transform="matrix(.429 0 0 .429 160.68 -80.101)">\n' +
    '   <g stroke="#000">\n' +
    '    <path d="m39.592 42.246c-4.5716 0.02368-12.788-1.0453-12.77 6.7945 0.01784 7.8398 12.788 6.8319 12.788 6.8319s12.667 1.041 12.681-6.9252-8.1273-6.7249-12.699-6.7012z" fill="#ff2a2a" stroke-width=".20436px"/>\n' +
    '    <circle cx="39.556" cy="49.061" r="7" fill="#ffb380" stroke-width=".26458"/>\n' +
    '   </g>\n' +
    '  </g>\n' +
    ' </g>\n' +
    '</svg>';

    if (SVG.supported) {
     const drawArea = SVG('svgDrawArea').size(300, 300);
      
      const group = drawArea.nested();
      group.svg(player);
      group.move(50, 50);
      
      group.transform({ rotation: 45 });
    } else {
        alert('SVG not supported')
    }
    
#svgDrawArea{
  /* background-color: red; */
  height: 300px;
  width:300px;
  border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/svg.js/2.6.4/svg.min.js"></script>
<div id="svgDrawArea"></div>

如果有人能够解释为什么旋转不起作用,或者指引我去某个地方让我自己弄明白原因,我会很高兴的!


我看不出任何问题。如果我执行那段代码片段,玩家就会旋转,正如它应该的一样。 - ccprog
有趣...既然你提到了,我打开了其他浏览器...这在Firefox上似乎可以运行,但在Chrome上却不行。 - fditz
所以看起来我正在寻找一个跨浏览器的解决方案... - fditz
2个回答

12
你的问题源于在SVG 1.1中,<svg>元素不允许使用transform属性。虽然在SVG 2中已经允许使用,但目前只有Firefox实现了这一功能,Chrome还未支持。

解决方案是先附加一个组,然后将SVG放入该组中。然后你可以对该组进行转换,它将在两个浏览器中起作用。

正如@noob在他们的回答中所建议的那样。如果您喜欢,可以自由接受他们的答案。


我会接受这个,因为@noob重用了我的代码,虽然变量组被命名,但最终我使用了“嵌套”方法,它不会创建一个“g”标签,而是创建一个“svg”标签。 - fditz
感谢您对这个错误进行解释和说明。 - fditz

1
抱歉,我只能提供解决方案,但无法给出解释(因为我自己也在处理旋转SVG路径的问题,我理解你的痛苦)。
我使用了:
group.transform({ x: 50, y:50});
group.transform({ rotation: 45 });

const player = '<svg width="11.214mm" height="6.3195mm" version="1.1" viewBox="0 0 11.214 6.3195" xmlns="http://www.w3.org/2000/svg">&gt;\n' +
    ' <g transform="translate(-172.04 62.213)">\n' +
    '  <g transform="matrix(.429 0 0 .429 160.68 -80.101)">\n' +
    '   <g stroke="#000">\n' +
    '    <path d="m39.592 42.246c-4.5716 0.02368-12.788-1.0453-12.77 6.7945 0.01784 7.8398 12.788 6.8319 12.788 6.8319s12.667 1.041 12.681-6.9252-8.1273-6.7249-12.699-6.7012z" fill="#ff2a2a" stroke-width=".20436px"/>\n' +
    '    <circle cx="39.556" cy="49.061" r="7" fill="#ffb380" stroke-width=".26458"/>\n' +
    '   </g>\n' +
    '  </g>\n' +
    ' </g>\n' +
    '</svg>';

    if (SVG.supported) {
     const drawArea = SVG('svgDrawArea').size(300, 300);
      
      const group = drawArea.nested();
      group.svg(player);
      
     // group.rotate(45);
      //group.move(50, 50);
      group.transform({ x: 50, y:50});
      group.transform({ rotation: 45 });
    } else {
        alert('SVG not supported')
    }
    
#svgDrawArea{
  /* background-color: red; */
  height: 300px;
  width:300px;
  border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/svg.js/2.6.4/svg.min.js"></script>
<div id="svgDrawArea"></div>


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接