2

我受到 KonvaJS 教程Modify Curves with Anchor Points的启发,制作了我自己的示例,即创建多个自定义箭头。

  1. 单击 selectionBox 创建一个锚点。

  2. 在创建第三个锚点时创建弯曲箭头。

  3. 在第四次单击重置所有变量以绘制新的弯曲箭头。

    var width = window.innerWidth;
    var height = window.innerHeight;

    // globals
    var selectionBoxLayer, curveLayer, lineLayer, anchorLayer, quad, bezier;

    function updateDottedLines() {
        var q = quad;
        var quadLine = lineLayer.get('#quadLine')[0];

        quadLine.setPoints([q.start.attrs.x, q.start.attrs.y, q.control.attrs.x, q.control.attrs.y, q.end.attrs.x, q.end.attrs.y]);
        lineLayer.draw();
    }
    function buildAnchor(x, y) {
        var anchor = new Konva.Circle({
            x: x,
            y: y,
            radius: 20,
            stroke: '#666',
            fill: '#ddd',
            strokeWidth: 2,
            draggable: true
        });

        // add hover styling
        anchor.on('mouseover', function() {
            document.body.style.cursor = 'pointer';
            this.setStrokeWidth(4);
            anchorLayer.draw();
        });
        anchor.on('mouseout', function() {
            document.body.style.cursor = 'default';
            this.setStrokeWidth(2);
            anchorLayer.draw();

        });

        anchor.on('dragend', function() {
            drawCurves();
            updateDottedLines();
        });

        anchorLayer.add(anchor);
        anchorLayer.draw();
        return anchor;
    }
        function drawCurves() {
        var context = curveLayer.getContext();
        var arrowLine = new Konva.Shape({
            sceneFunc: function(context){
              debugger;
                      // draw quad
        context.beginPath();
        context.moveTo(quad.start.attrs.x, quad.start.attrs.y);
        context.quadraticCurveTo(quad.control.attrs.x, quad.control.attrs.y, quad.end.attrs.x, quad.end.attrs.y);
                //Draw Arrow Head
                var headlen = 10;   // length of head in pixels
                var angle = Math.atan2(quad.end.attrs.y - quad.control.attrs.y, quad.end.attrs.x - quad.control.attrs.x);
                context.lineTo(quad.end.attrs.x-headlen*Math.cos(angle-Math.PI/6), quad.end.attrs.y-headlen*Math.sin(angle-Math.PI/6));
                context.moveTo(quad.end.attrs.x, quad.end.attrs.y);
                context.lineTo(quad.end.attrs.x- headlen*Math.cos(angle+Math.PI/6), quad.end.attrs.y-headlen*Math.sin(angle+Math.PI/6));
                context.fillStrokeShape(this);
            },
            stroke: 'black',
            strokeWidth: 4
        });
        curveLayer.add(arrowLine);
        curveLayer.draw();
    }

    var stage = new Konva.Stage({
        container: 'container',
        width: width,
        height: height
    });
    selectionBoxLayer = new Konva.Layer();
    anchorLayer = new Konva.Layer();
    lineLayer = new Konva.Layer();

    // curveLayer just contains a canvas which is drawn
    // onto with the existing canvas API
    curveLayer = new Konva.Layer();

    var quadLine = new Konva.Line({
        dash: [10, 10, 0, 10],
        strokeWidth: 3,
        stroke: 'black',
        lineCap: 'round',
        id: 'quadLine',
        opacity: 0.3,
        points: [0, 0]
    });


    // add dotted line connectors
    lineLayer.add(quadLine);

    quad = {};

    // keep curves insync with the lines
    anchorLayer.on('beforeDraw', function() {
      if(quad.start && quad.control && quad.end){
        drawCurves();
        updateDottedLines();
      }
    });

   var selectionBoxBackground = new Konva.Rect({
        x: 0,
        y: 0,
        height:stage.height(),
        width: stage.width(),
        fill: 'transparent',
        draggable: false,
        name: 'selectionBoxBackground'
    });
    selectionBoxLayer.add(selectionBoxBackground);
    var clickCounter = 0;
    selectionBoxBackground.on("click", function(){
        clickCounter +=1;
      var mousePos = {};
        switch(clickCounter){
            case 1:
            mousePos = stage.getPointerPosition();
            quad.start = buildAnchor(mousePos.x, mousePos.y);
            break;
            case 2:
            mousePos = stage.getPointerPosition();
            quad.control = buildAnchor(mousePos.x, mousePos.y);
            break;
            case 3:
            mousePos = stage.getPointerPosition();
            quad.end = buildAnchor(mousePos.x, mousePos.y);
            drawCurves();
            updateDottedLines();
            break;
            default:
            clickCounter = 0;
            quad = {};
            anchorLayer.destroyChildren();
            anchorLayer.draw();
        }      
    });

    
    stage.add(curveLayer);
    stage.add(lineLayer);
    stage.add(selectionBoxLayer);
    stage.add(anchorLayer);
 body {
      margin: 0;
      padding: 0;
      overflow: hidden;
      background-color: #F0F0F0;
    }
<script src="https://cdn.rawgit.com/konvajs/konva/0.11.1/konva.min.js"></script>

<body>
  <div id="container"></div>


</body>

PS 请注意,当我在浏览器控制台中写入时curveLayer.children,它会带来所有创建的弯曲箭头。

提示:我认为在创建new Shape()时所有创建的形状的值都会更改为新的。

我不知道我错过了什么。

4

0 回答 0