【问题标题】:rotate and zoom svg with d3 javascript使用 d3 javascript 旋转和缩放 svg
【发布时间】:2017-09-14 20:51:04
【问题描述】:

我想使用 D3.js 围绕其中心旋转和缩放图形。当我缩放图形时,我想以当前的纵横比缩放它,反之亦然,当我旋转图形时,我想将它缩放到鼠标指向的当前点。我使用鼠标滚轮进行缩放,使用鼠标按钮进行旋转。

var svg = d3.select("svg"),
    width = +svg.attr("width"),
    height = +svg.attr("height"),
    transform = d3.zoomIdentity;

var points = d3.range(2000).map(phyllotaxis(10));

var g = svg.append("g");

g.append("line")
    .attr("x1", "20")
    .attr("y1", "20")
    .attr("x2", "60")
    .attr("y2", "60")
    .attr("stroke", "black")
    .attr("stroke-width", "10");

  svg.call(d3.drag()
      .on("drag",onDrag)
  )
  // ##########################
  var boxCenter = [100, 100];
  // #############################
  function onDrag(){

    var x = d3.event.sourceEvent.pageX,
    y = d3.event.sourceEvent.pageY;

    var angle = Math.atan2(x - boxCenter[0],
        - (y - boxCenter[1]) )*(180/Math.PI);

    g.attr("transform", "rotate("+angle+")");
  }

svg.call(d3.zoom()
    .scaleExtent([1 / 2, 8])
    .on("zoom", zoomed));

function zoomed() {
      g.attr("transform", d3.event.transform);
  }


function phyllotaxis(radius) {
  var theta = Math.PI * (3 - Math.sqrt(5));
  return function(i) {
    var r = radius * Math.sqrt(i), a = theta * i;
    return {
      x: width / 2 + r * Math.cos(a),
      y: height / 2 + r * Math.sin(a)
    };
  };
}

这是我的例子: https://jsfiddle.net/6Lyjz35L/

【问题讨论】:

    标签: javascript d3.js


    【解决方案1】:

    为了在初始缩放时围绕中心旋转正确,您需要为“g”添加一个“transform-origin”属性。

    g.attr("transform-origin", "50% 50%");
    

    您遇到的其他问题源于在两个不同的位置分配“转换”属性。一个元素 ('g') 一次只能应用一个 'transform' 属性,因此每次旋转或缩放时都会覆盖其中一个。要解决此问题,您可以创建一个辅助方法,它将您想要的两个转换附加到一个字符串中。

    var currentAngle = 0;
    var currentZoom = '';
    
    function getTransform(p_angle, p_zoom) {
      return `${p_zoom} rotate(${p_angle})`;
      // return p_zoom + " rotate(" + p_angle + ")";
    }
    
    // In the rotate:
    currentAngle = angle;
    g.attr("transform", getTransform(currentAngle, currentZoom));
    
    // In the zoom:
    currentZoom = d3.event.transform;
    g.attr("transform", getTransform(currentAngle, currentZoom));
    

    缩放还引入了一个问题,那就是您必须在不同的缩放级别计算新的变换原点。 我所说的缩放引入的问题实际上是按错误顺序应用操作的结果。最初我应用了旋转,然后是平移。它实际上需要反转,平移然后旋转。这将保持正确的变换原点。

    以下是这些更改的一个小技巧:https://jsfiddle.net/scmxcszz/1/

    【讨论】:

    • 谢谢它对我有帮助 我还添加了两个 g 元素,一个用于旋转,另一个用于缩放,两者的处理程序都是 svg 元素
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-21
    • 2015-09-21
    • 2022-01-21
    • 2012-03-20
    相关资源
    最近更新 更多