在HTML5画布上用锚点修改路径

时间:2018-11-10 13:09:03

标签: javascript canvas konvajs

我的问题是如何制作一个UI,使用户可以通过拖动路径上的上的锚点来修改复杂的路径。注意 on -例如,此example in the Konvajs documentation中Bezier曲线的控制点本身不在路径上,而我更喜欢 on 上的复杂路径上的锚点。

我将尝试修改在this question中创建的曲线。

这是一个绘制示例路径的代码段。谁能帮我吗?稍微向下滚动代码段窗口,然后单击矩形以查看路径动画。

    var stage = new Konva.Stage({
        container: 'container',
        width: 500,
        height: 500
    });

    var layer = new Konva.Layer();

    var rect = new Konva.Rect({
        x: stage.getWidth() / 2,
        y: stage.getHeight() / 2,
        stroke: '#555',
        strokeWidth: 3,
        fill: '#ddd',
        width: 50,
        height: 50,
        shadowColor: 'black',
        shadowBlur: 10,
        shadowOffset: [10, 10],
        shadowOpacity: 0.2,
        cornerRadius: 10
    });

    var path = new Konva.Path({
        x: stage.getWidth() / 2,
        y: stage.getHeight() / 2,
        data: 'M30 10 C-20 -50 -20 -70 50 -80 C150 -100 50 -150 -100 -80',
        stroke: '#00D2FF',
        strokeWidth: 5
    });

    var pathLen = path.getLength() + 10;
    path.dashOffset(pathLen);
    path.dash([pathLen]);

    var anim = new Konva.Animation(function (frame) {
        var dashLen = pathLen - frame.time / 5;
        if (dashLen < 0) {
            var tween = new Konva.Tween({
                node: path,
                duration: 1,
                strokeWidth: 10,
                easing: Konva.Easings.ElasticEaseOut
            });
            tween.play();
            anim.stop();
        } else {
            path.dashOffset(dashLen);
        }
    }, layer);

    rect.on('mousedown', function() {
        anim.start();
    })


    layer.add(path);
    layer.add(rect);

    stage.add(layer);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/konva/2.5.1/konva.js"></script>
<div id='container' style="display: inline-block; width: 500px, height: 500px; background-color: silver; overflow: hidden; position: relative;"></div>
<div id='img'></div>

还有,有人可以建议为什么在动画运行之前绘制部分曲线吗?

1 个答案:

答案 0 :(得分:0)

我的解决方案没有控制点:

  var stage = new Konva.Stage({
    container: "container",
    width: 500,
    height: 500,
    draggable: true
  });

  var layer = new Konva.Layer();
  var curveLayer = new Konva.Layer();
  var k = 0;

  var rect = new Konva.Rect({
    x: stage.getWidth() / 2,
    y: stage.getHeight() / 2,
    stroke: "#555",
    strokeWidth: 3,
    fill: "#ddd",
    width: 50,
    height: 50,
    shadowColor: "black",
    shadowBlur: 10,
    shadowOffset: [10, 10],
    shadowOpacity: 0.2,
    cornerRadius: 10
  });

  var path = buildPath("M25 25 L-75 -200 C-75 -200 -120 -300 -200 -200");

  var pathLen = path.getLength() + 1000;
  path.dashOffset(pathLen);
  path.dash([pathLen]);

  var anim = new Konva.Animation(function(frame) {
    var dashLen = pathLen - frame.time * 10;
    if (dashLen < 0) {
      var tween = new Konva.Tween({
        node: path,
        duration: 1,
        strokeWidth: 10,
        easing: Konva.Easings.ElasticEaseOut
      });
      var circle = buildAnchorPoint(-75, -200);
      var circle1 = buildAnchorPoint(-200, -200);
      //var circle2 = buildAnchorPoint(-120, -242.5);
      layer.draw();
      circle.on("dragmove", function() {
        var point = stage.getPointerPosition();
        var pointx = point.x - stage.x();
        var pointy = point.y - stage.y();
        console.log(
          "X: " +
            (pointx - stage.getWidth() / 2) +
            " Y: " +
            (pointy - stage.getHeight() / 2)
        );
        path.data(
          "M25 25 L" +
            (pointx - stage.getWidth() / 2) +
            " " +
            (pointy - stage.getHeight() / 2) +
            " C" +
            (pointx - stage.getWidth() / 2) +
            " " +
            (pointy - stage.getHeight() / 2) +
            "-120 -300" +
            (circle1.getX() - stage.getWidth() / 2) +
            " " +
            (circle1.getY() - stage.getHeight() / 2)
        );
        curveLayer.draw();
        layer.draw();
      });
      circle1.on("dragmove", function() {
        var point = stage.getPointerPosition();
        var pointx = point.x - stage.x();
        var pointy = point.y - stage.y();
        console.log(
          "X: " +
            (point.x - stage.getWidth() / 2) +
            " Y: " +
            (point.y - stage.getHeight() / 2)
        );
        path.data(
          "M25 25 L" +
            (circle.getX() - stage.getWidth() / 2) +
            " " +
            (circle.getY() - stage.getHeight() / 2) +
            "C" +
            (circle.getX() - stage.getWidth() / 2) +
            " " +
            (circle.getY() - stage.getHeight() / 2) +
            " -120 -300 " +
            (pointx - stage.getWidth() / 2) +
            " " +
            (pointy - stage.getHeight() / 2)
        );
        curveLayer.draw();
        layer.draw();
      });
      tween.play();
      anim.stop();
    } else {
      path.dashOffset(dashLen);
    }
  }, curveLayer);

  rect.on("mousedown", function() {
    if (k == 0) {
      anim.start();
      k++;
    }
  });

  layer.add(rect);

  stage.add(curveLayer);
  stage.add(layer);

  function buildPath(data) {
    var path = new Konva.Path({
      x: stage.getWidth() / 2,
      y: stage.getHeight() / 2,
      data: data,
      stroke: "#00D2FF",
      strokeWidth: 5,
      lineJoin: "round",
      lineCap: "round"
    });
    curveLayer.add(path);
    return path;
  }

  function buildAnchorPoint(x, y) {
    var circle = new Konva.Circle({
      x: stage.getWidth() / 2 + x,
      y: stage.getHeight() / 2 + y,
      stroke: "#c1fbff",
      strokeWidth: 1,
      fill: "#00D2FF",
      radius: 5,
      cornerRadius: 10,
      draggable: true
    });
    layer.add(circle);
    return circle;
  }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/konva/2.5.1/konva.js"></script>
<div id='container' style="display: inline-block; width: 500px, height: 500px; background-color: silver; overflow: hidden; position: relative;"></div>
<div id='img'></div>

有人可以帮助控制点锚吗?

此外,我想稍微清理一下代码,因为我将有许多锚定路径,这就是为什么我需要使处理程序不喜欢我的代码的原因,请帮忙!