如何相对于其中心点旋转或缩放(变换)SVG 路径?

Posted

技术标签:

【中文标题】如何相对于其中心点旋转或缩放(变换)SVG 路径?【英文标题】:How do I rotate or scale (transform) an SVG path relative to its center point? 【发布时间】:2014-02-20 03:10:27 【问题描述】:

我正在尝试围绕中心点旋转和缩放 SVG 中的形状。我研究了几个库,包括 Jquery、Greensock、D3、RaphaelJS,但我找不到任何提供直接方法来完成此任务的库。每个都从原点为形状设置动画(我理解这是默认设置)。我希望能够围绕其中心点旋转形状或从中心点向上或向下缩放。

这里有几个使用 Greensock 和 D3 的示例来说明默认行为:http://jsbin.com/AHEXiPa/1/edit?html,js,output

这些示例中的每一个都从左上角反弹进出,而不是保持静止并从三角形的中心向各个方向扩展。

我提到的其中一个库可以做到这一点,还是我应该考虑其他库或方法?

理想情况下,我需要能够将动画/变换应用于 DOM 中的现有对象。例如,D3 擅长这一点,但 Raphael 似乎需要先将 SVG 转换为 Raphael,然后再将其注入 DOM。

【问题讨论】:

您是否尝试使用短语“svg rotate around center”搜索 SO?你会得到很多答案,包括 Raphael、D3 和纯 javascript 的解决方案。 【参考方案1】:

真的是选择适合您需要的库,然后您会想办法。正如 BigBadaboom 所说,如果您进行搜索,则有很多解决方案。

为了尝试结合您的问题,因为有时棘手的一点是使用现有的 DOM 对象,我在 Snap.svg 中包含了一个示例。在大多数库中,您通常可以执行类似的操作。

jsfiddle 在这里 Fiddle 使用您现有的 html。

s = Snap("#mySVGContainer1");   // create a canvas from existing svg

var triangle1 = s.select("#myShape1").transform("r90"); //select&transform existing object


p = Snap("#mySVGContainer2");

var triangle2 = p.select("#myShape2");
var bbox = triangle2.getBBox(); //bounding box, centre cx/cy

//rotate and scale with transform string (raphael/snap format)
triangle2.animate( transform: "r180," + bbox.cx + ',' + bbox.cy + "s3,3," + bbox.cx + "," + bbox.cy , 2000);  

【讨论】:

这是迄今为止我最喜欢的选项。我真的在寻找尽可能少坐立不安的东西,因此将项目包装在额外的组中(这似乎是其他线程中的主流选项)不太理想。做得很好,感谢您的帮助!【参考方案2】:

对于旋转,正如@Ian 指出的那样,您可以指定旋转中心。对于其他转换,更改是相对于路径的 (0,0) 点定义的。

让变换相对于路径中心起作用的最简单方法是:

    定义路径,使其以 (0,0) 点为中心;或 将路径包裹在 <g> 元素中,然后平移它,使其以 <g> 元素坐标系的 (0,0) 点为中心。

然后,您可以应用旋转、缩放和变换(在 <g> 元素上,如果使用的话),它们都会很好地居中。

最棘手的部分是找出任意形状的“中心”。 @Ian 使用边界框中心的方法通常会产生不错的结果。如果您的形状是多边形,则有d3 functions you could use。

显示随鼠标移动的形状、旋转和更改比例的示例,均以边界框的中心为中心:http://fiddle.jshell.net/LgfE3/

编辑: simplier jsfiddle

【讨论】:

真的很喜欢你的例子,尤其是使用不同的库。【参考方案3】:

我已经找了很久了,下面会满足的。

1.在坐标 x:0,y:0 处设计您的 svg 形状。

2. 手动识别旋转中心,例如 center = [ x:50,y:100]。

3. 构建一个spinIt() 函数,例如:

function spinIt() 
    needle.transition()
        .duration(2000)
        .attrTween("transform", tween);
    function tween() 
        return d3.interpolateString("rotate(-180, 50, 100)", "rotate(90, 50, 100)");
    

4.在触发器上使用它:

svg.on("click", spinIt);

http://jsfiddle.net/SHF2M/79/

【讨论】:

以上是关于如何相对于其中心点旋转或缩放(变换)SVG 路径?的主要内容,如果未能解决你的问题,请参考以下文章

svg子元素上的CSS变换原点问题

提供 x,y,width 和 height 值,我如何获得从中心缩放的 svg 变换矩阵

可以将 SVG 剪辑路径相对于其容器居中吗?

使用SVG内置API计算图形或点经过transform之后的新坐标

使用 CSS 变换在悬停时缩放 SVG 矩形

最快的变换方式(移动、旋转、缩放)