代码之家  ›  专栏  ›  技术社区  ›  mrbrahman

D3拖动模糊/抖动控制柄

  •  0
  • mrbrahman  · 技术社区  · 7 年前

    这是D3V4。

    我试图创建一个可扩展的矩形区域,有边界(有点像一个受约束的d3画笔)。我加了一个出现在鼠标上的手柄。

    var rectHeight = 80, rectWidth = 100, maxWidth = 200;
    var svg = d3.select("svg");
    
    var brect = svg.append("g")
      .attr("id", "brect");
    
    brect.append("rect")
      .attr("id", "dataRect")
      .attr("width", rectWidth)
      .attr("height", rectHeight)
      .attr("fill", "green");
    
    var handleResizeGroup = brect.append("g")
      .attr("id", "handleResizeGroup")
      .attr("transform", `translate(${rectWidth})`)
      .call(d3.drag()
        .on("start", dragStarted)
        .on("drag", dragged)
        .on("end", dragEnded));
    
    function dragStarted() {
      d3.select(this.previousSibling).classed("active", true);
    }
    
    function dragEnded() {
      d3.select(this.previousSibling).classed("active", false);
    }
    
    function dragged(d) {
      var h = d3.select(this);
      var r = d3.select(this.previousSibling);
      var currWidth = r.attr("width");
    
      var t = (d3.event.x >= 0 && d3.event.x <= maxWidth) ? d3.event.x : currWidth;
    
      r.attr("width", t);
      h.attr("transform", `translate(${t})`)
    }
    
    handleResizeGroup.append("path")
      .attr("fill-opacity", 0)
      .attr("stroke-opacity", 0)
      .attr("stroke", "grey")
      .attr("cursor", "ew-resize")
      .attr("d", resizePath);
    
    handleResizeGroup.append("rect")
      .attr("id", "resizeRect")
      .attr("width", "8")
      .attr("fill-opacity", 0)
      .attr("cursor", "ew-resize")
      .attr("height", rectHeight)
      //.attr("pointer-events", "all")
      .on("mouseover", function(){
        d3.select(this.previousSibling)
          .attr("stroke-opacity", "100%");
      })
      .on("mouseout", function() {
        d3.select(this.previousSibling)
          .attr("stroke-opacity", "0");
      });
    
    function resizePath(d) {
      var e = 1,
        x = e ? 1 : -1,
        y = rectHeight / 3;
      return "M" + (.5 * x) + "," + y
        + "A6,6 0 0 " + e + " " + (6.5 * x) + "," + (y + 6)
        + "V" + (2 * y - 6)
        + "A6,6 0 0 " + e + " " + (.5 * x) + "," + (2 * y)
        + "Z"
        + "M" + (2.5 * x) + "," + (y + 8)
        + "V" + (2 * y - 8)
        + "M" + (4.5 * x) + "," + (y + 8)
        + "V" + (2 * y - 8);
    }
    rect.active {
      stroke-width: 1;
      stroke: rgb(0,0,0);
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
    <svg width=1200 height=500></svg>

    我注意到两个问题

    1. 当我拖动控制柄时,我看到控制柄本身有一个抖动(可能是因为控制柄仅在鼠标悬停时显示?)
    2. 如果我把鼠标拖得太快,比如向左,矩形就跟不上

    有人能帮助了解发生了什么,以及如何解决这些问题吗?

    谢谢您!

    1 回复  |  直到 7 年前
        1
  •  0
  •   Michael Slevin    7 年前

    对于第一期,添加 .attr('pointer-events', 'none') to the green 复习。控制柄抖动是因为光标移动的速度比控制柄稍快—所以在移动时,您不断地向外移动,然后向控制柄内移动,它会跟上。

    我真的不明白你在干什么 resizePath . 是不是在矩形周围加上了灰色的笔划?为什么不添加/移除笔划?您的第二个问题可能是由于不断调整路径。