2012-06-11 54 views
8

我正处于一个JS项目的早期阶段。除了一个形状的定位之外,一切都很顺利。有问题的形状是深青色钻石(正方形旋转45度)。我可以在屏幕上的方没有问题,但是当我添加:d3.js奇数旋转行为

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

方形旋转正常,但移动向屏幕的左侧部分,像这样:

enter image description here

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

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”属性中,广场上完全消失。

这是什么造成的?我做了什么我看不到的错误吗?

回答

15

当您旋转矩形时,还可以旋转其坐标系。所以当你稍后沿x轴移动它250时,实际上是沿着45度轴移动它250个单位 - 这是旋转的结果。

通常,当您像rotate一样引入transform属性时,应该通过此属性执行所有转换。因此,您需要使用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轴发生。

+0

啊,你是绝对正确的。非常感谢。所以现在我需要这个形状正好在中心。使用毕达哥拉斯理论,我找到了横截面的长度,并将其除以2.这个方程的结果是我想在翻译语句中设置的y坐标(从画布高度/当然减去) 。看起来好像我不能在这里使用变量。你知道我该怎么做吗? – 1080p

+2

只要按照正确的顺序进行转换,就不需要使用毕达哥拉斯。假设'w'和'h'是画布大小,'rw'和'rh'是Rect的大小,这应该做你所问的:'.attr(“transform”,“translate(”+(w/2)+“,”+(h/2)+“)rotate(45)translate(”+(-rw/2)+“,”+(-rh/2)+“)”'换句话说,首先将矩形的左上角移动到中心,然后旋转45°,然后向后移回矩形的半宽和半高 - 沿着45度轴 - 以画布为中心,如果画布为300x300且矩形为100x100: “翻译(150,150)旋转(45)翻译(-50,-50)”' – meetamit

+0

有趣的是,我已经在我的代码中设置了Pythagorean,但是如果你的方法更快,我可以把它换掉。帮助 – 1080p

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/

+0

已经得到了旋转的答案,但是你的代码片段帮助我了解了旋转属性的语法,谢谢了很多 – 1080p

+0

谢谢,我有问题让他们围绕他们的中心旋转,非常有帮助。 – greg

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 + ")"; 

       })