如何找到旋转角度,使SVG弧与css3d“站起来”

时间:2016-12-19 22:51:50

标签: javascript d3.js 3d css-transforms vector-graphics

enter image description here

我有 arcs 连接d3力导向图中的节点,整个SVG用CSS转换。现在弧线感觉并不像躺在地上那么好,所以我想让它们“站起来”,或者旋转X,Y,Z来获得效果。

我已经将变换原点设置为连接节点的线的中心,但是现在我发现了我必须旋转弧以使它们站起来的角度。任何有关寻找角度的想法/公式都非常受欢迎。

我现在在tick函数中的代码如下所示:

  force.on("tick", function() {
    path.attr("d", function (d) {
      var dx = d.target.x - d.source.x,
          dy = d.target.y - d.source.y,
          dr = Math.sqrt(dx * dx + dy * dy) -200;
      return "M" + d.source.x + "," + d.source.y + "A" + dr + "," + dr + " 0 0,1 " + d.target.x + "," + d.target.y;
      })
      .attr('style', function(d){
          var rotateX = 0, rotateY = 0, rotateZ = 0;
          return "transform-origin:" + (d.source.x + d.target.x)/2 + "px " + (d.source.y + d.target.y)/2 + "px" + 
                 ";transform:rotateX("+rotateX+"deg) rotateY("+rotateY+"deg) rotateZ("+rotateZ+"deg)";
      });
我正在寻找

rotateX,rotateY和rotateZ角度!

1 个答案:

答案 0 :(得分:1)

我没有d3的实际知识,所以我已经解决了标准javascript布局的问题。

希望程序应该是一样的。

在演示中,单击2次以设置弧的开始和结束。然后再次单击以查看它在3d中旋转。

您可以重复循环次数。

在变换演算中,我们只计算atan2平面中的角度以及水平和垂直差异。真正的诀窍是设置90度,使得元素在(表示法)平面旋转后垂直

请注意,在片段中我没有应用90度,但是80度,因此从上方看时弧仍然可见。

var sequence = 0;
var x1, y1, x2, y2;

function getCursorPosition(event) {
  var x = event.clientX;
  var y = event.clientY;
  var ele = document.getElementById('container');
  if (sequence == 0) {
    x1 = x;
    y1 = y;
    sequence = 1;
    ele.classList.remove("animate");
  } else if (sequence == 1) {
    x2 = x;
    y2 = y;
    sequence = 2;
    Compute();
  } else {
    ele.classList.add("animate");
    sequence = 0;
  }
}

function Compute() {
  var ele = document.getElementById('inner');
  var width = Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));

  ele.style.width = width + "px ";
  ele.style.height = width / 2 + "px ";
  ele.style.left = x1 + "px ";
  ele.style.top = y1 + "px ";
  var angle = Math.atan2(y2 - y1, x2 - x1);
  var deg = angle * 180.0 / Math.PI;

  ele.style.transform = "rotate(" + deg + "deg) rotateX(80deg) "
    /*
        var style = "width:" + width + "px ";
        style += "left: " + x1 + "px ";
        style += "top: " + y1 + "px ";
        ele.setAttribute("style",style);
    */
}
.container {
  width: 600px;
  height: 400px;
  border: solid 1px green;
  perspective: 1000px;
  transform-style: preserve-3d;
  position: absolute;
  background-image: repeating-linear-gradient(white 0px, wheat 50px, white 100px);
}
#inner {
  width: 100px;
  height: 50px;
  border-radius: 0px 0px 100px 100px;
  background-color: green;
  position: absolute;
  transform-origin: left top;
  transform-style: preserve-3d;
}
.animate {
  animation: rota 15s 1;
}
@keyframes rota {
  from {
    transform: perspective(1000px) rotateX(0deg);
  }
  to {
    transform: perspective(1000px) rotateX(360deg);
  }
}
<div class="container" id="container" onclick="getCursorPosition(event)">
  <div id="inner">
  </div>
</div>