带有鼠标事件的贝塞尔曲线

时间:2016-12-30 20:12:14

标签: javascript d3.js mouseevent bezier

我想用鼠标事件绘制贝塞尔曲线。

function draw(selection)
{
    var keep = false, path, xy0;
    line = d3.svg.line()
        .interpolate(function(points) {return points.join("M10 80 C 40 10, 65 10, 95 80 S 150 150, 180 80"); })
        .x(function(d) {return d[0];})
        .y(function(d) {return d[1];});

    selection
        .on('mousedown', function() {
            keep = true;
            xy0 = d3.mouse(this);
            path = d3.select('svg')
                .append('path')
                .attr('d', line([xy0, xy0]))
                .style({'stroke': 'black', 'stroke-width': '3px'});
        })
        .on('mouseup', function() {
            keep = false;
        })
        .on('mousemove', function(){
            if(keep) {
                Line = line([xy0, d3.mouse(this).map(function(x) {return x - 1;})]);
                console.log(Line);
                path.attr('points', Line);
            }
        });
}

但它不起作用。你知道怎么做吗?

提前致谢,

1 个答案:

答案 0 :(得分:0)

仍然不确定我理解这个问题。

  

M10 80 C 40 10,65 10,95 80 S 150 150,180 80是贝塞尔曲线参数

不,这是路径的“d”属性,它绘制了一个特定的贝塞尔曲线。我不确定你是如何将它与你的鼠标动作结合起来的。我试过,我猜它会产生一种曲线:

<!DOCTYPE html>
<html>

<head>
  <script data-require="d3@3.5.17" data-semver="3.5.17" src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.js"></script>
</head>

<body>
  <script>
    var keep = false,
      mouseStart = null,
      controlPoints = "C 40 10, 65 10, 95 80 S 150 150,";

    var svg = d3.select('body')
      .append('svg')
      .attr('width', 500)
      .attr('height', 500)
      .style('border', '1px solid black');

    var path = svg.append("path")
      .style("stroke", "steelblue")
      .style("stroke-width", "2px")
      .style("fill", "none");

    svg.on('mousedown', function() {
        keep = true;
        mouseStart = d3.mouse(this);
      })
      .on('mouseup', function() {
        keep = false;
      })
      .on('mousemove', function() {
        var mouseEnd = d3.mouse(this);
        if (keep) {
          path.attr("d", "M" + mouseStart + controlPoints + mouseEnd);
        }
      });
  </script>
</body>

</html>

如果你想从头到尾想要一个平滑的曲线,你可以尝试这样的事情:

<!DOCTYPE html>
<html>

<head>
  <script data-require="d3@3.5.17" data-semver="3.5.17" src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.17/d3.js"></script>
</head>

<body>
  <script>
    var keep = false,
      mouseStart = null;

    var svg = d3.select('body')
      .append('svg')
      .attr('width', 500)
      .attr('height', 500)
      .style('border', '1px solid black');

    var path = svg.append("path")
      .style("stroke", "steelblue")
      .style("stroke-width", "2px")
      .style("fill", "none");

    svg.on('mousedown', function() {
        keep = true;
        mouseStart = d3.mouse(this);
      })
      .on('mouseup', function() {
        keep = false;
      })
      .on('mousemove', function() {
        var mouseEnd = d3.mouse(this);
        if (keep) {
          var dx = mouseStart[0] - mouseEnd[0],
            dy = mouseStart[1] - mouseEnd[1],
            dr = Math.sqrt(dx * dx + dy * dy);
          path.attr("d", "M" +
            mouseStart[0] + "," +
            mouseStart[1] + "A" +
            dr + "," + dr + " 0 0,1 " +
            mouseEnd[0] + "," +
            mouseEnd[1]);
        }
      });
  </script>
</body>

</html>