9

我正处于 JS 项目的早期阶段。到目前为止一切都很好,除了一个形状的定位。有问题的形状是蓝绿色钻石(方形旋转 45 度)。我可以让屏幕上的正方形没问题,但是当我添加时:

    .attr("transform", "rotate(45)")

正方形可以正确旋转,但会向屏幕的左侧移动,如下所示:

在此处输入图像描述

我不确定是什么导致了这种情况发生。如果有帮助,这里有一些产生这个结果的代码:

var svg = d3.select("body")
            .append("svg")
            .attr("width", w)
            .attr("height", h);
        svg
            .append("rect")
            .attr("transform", "rotate(45)")
            .attr("x", 250)
            .attr("height", w / 10)
            .attr("width", w / 10)
            .attr("fill", "teal")

注意:如果我把“y”属性放进去,正方形就完全消失了。

这是什么原因造成的?我是不是做错了什么我看不到的事情?

4

3 回答 3

18

旋转矩形时,也会旋转其坐标系。因此,当您稍后将其沿 x 轴移动 250 度时,实际上您将其沿 45 度轴移动了 250 个单位——这是旋转的结果。

通常,当您像为 所做的那样引入一个transform属性时rotate,您应该通过此属性进行所有转换。所以,你需要使用translate而不是使用"x"属性。然后它看起来像这样:

svg
  .append("rect")
  .attr("transform", "translate(250, 0) rotate(45)")
  // remove this: .attr("x", 250)
  .attr("height", w / 10)
  ...

这将为您提供我认为您正在寻找的结果。现在请注意,这里的转换顺序很重要:如果您的转换是"rotate(45) translate(250, 0)"(即先旋转然后平移),您将得到与之前相同的错误结果。这是因为当您首先旋转时,您的平移会像以前一样沿旋转的 x 轴进行。

于 2012-06-11T18:24:39.140 回答
11

在 SVG 中,您必须设置变换原点以使其从中心旋转,例如...

.attr("transform", "rotate(45, 250, 100)");

250, 100矩形的 x 和 y 位置减去它的半径在哪里。把它们放在一起看起来像......

var svg = d3.select("body")
            .append("svg")
            .attr("width", 400)
            .attr("height", 300);
        svg
            .append("rect")
            .attr("transform", "rotate(30,"+ (diamond.x+diamond.width/2) + ","+ (diamond.y+diamond.width/2) +")")
            .attr("x", diamond.x)
            .attr("y", diamond.y)
            .attr("height", diamond.width)
            .attr("width", diamond.width)
            .attr("fill", "teal")​

您可以在此处查看演示:

http://jsfiddle.net/uwM8u/

于 2012-06-11T18:35:50.613 回答
0

这是一种与 Duopixel 给出的答案略有不同的方法。在这里,您不会重复 X 和 Y 的计算。在 Duopixel 的示例中,这是一个微不足道的改进,因为他只是引用了一个结构。通常情况下 X 和 Y 是函数,我不想在两个地方维护该日志。这种方法允许您设置 X 和 Y 一个节点,然后在该节点的中心旋转。

您可能会发现,旋转后,您仍然想调整最终位置,这可以通过另一个变换来完成,或者在 TEXT 的情况下,您可以使用 dx, dy。

    svgNode.attr("transform", function (d) {

                    var w = +d3.select(this).attr("x") +  (this.getBBox().width / 2) ;
                    var h = +d3.select(this).attr("y") + (this.getBBox().height / 2);

                    return  "rotate(90," + w + "," + h + ")";

                })
于 2014-05-21T17:29:44.407 回答