Kinetic JS绘制虚线箭头线

时间:2014-09-12 17:08:48

标签: javascript kineticjs

在KineticJS中,如何画一条用箭头划线的线?

例如:

> > > > > >

我知道要画一条虚线:

  var line = new Kinetic.Line({
            points: [fromx, fromy, tox, toy]
            stroke: 'red',
            dashArray: [10, 10]
        });

如何将破折号更改为某种形式的箭头指向一个点?使用填充背景将不起作用,因为可以在任何方向绘制线条。

1 个答案:

答案 0 :(得分:1)

绘制一个自定义的Kinetic.Shape,其中包含沿着直线路径放置的多个箭头:

  • 创建一个包含箭头图形的临时画布。

  • 创建一个Kinetic.Shape,以所需的间隔和线条以相同的角度沿着线绘制临时画布箭头。

enter image description here

以下是计算线条角度和长度的数学运算:

var dx=p1.x-p0.x;
var dy=p1.y-p0.y;
var angle=Math.atan2(dy,dx);
var length=Math.sqrt(dx*dx+dy*dy);

以下是沿着该行路径以一定间隔重复绘制箭头的代码:

var cos=Math.cos(angle);
var sin=Math.sin(angle);

// drawImage each arrow along the line at interval spaceLength
for(var n=spaceLength;n<length;n+=spaceLength){   
    var ax=p0.x+n*cos;
    var ay=p0.y+n*sin;
    ctx.save();
    ctx.translate(ax,ay-5);
    ctx.rotate(angle);
    ctx.drawImage(arrow,0,0);
    ctx.restore();
}

示例代码和演示:http://jsfiddle.net/m1erickson/1z8hynqu/

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Prototype</title>
    <script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
    <script src="http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v5.1.0.min.js"></script>
<style>
body{padding:20px;}
#container{
  border:solid 1px #ccc;
  margin-top: 10px;
  width:350px;
  height:350px;
}
</style>        
<script>
$(function(){

    var stage = new Kinetic.Stage({
        container: 'container',
        width: 350,
        height: 350
    });
    var layer = new Kinetic.Layer();
    stage.add(layer);

    // start & end points of line
    var p0={x:50,y:100};
    var p1={x:250,y:50};

    // create a temp canvas with an arrow drawing
    var arrow=makeArrow();

    // make a new arrow-line
    makeArrowLine(p0,p1,15);

    // just for demo...show the line segement in red
    var demoLine=new Kinetic.Line({
        x:0,y:0,
        points:[p0.x,p0.y,p1.x,p1.y],
        stroke:'red',
        tension:1,
    });
    layer.add(demoLine);
    layer.draw();


    function makeArrowLine(p0,p1,spaceLength){

        // a custom Shape that draws arrows along a line 
        var s=new Kinetic.Shape({
            x: 0,
            y: 0,
            stroke: 'blue',
            drawFunc: function(ctx){

              // vars needed to position/rotate arrows along line
              var p0=this.p0;
              var p1=this.p1;
              var dx=p1.x-p0.x;
              var dy=p1.y-p0.y;
              var angle=Math.atan2(dy,dx);
              var cos=Math.cos(angle);
              var sin=Math.sin(angle);
              var length=Math.sqrt(dx*dx+dy*dy);

              // drawImage each arrow along the line at interval spaceLength
              for(var n=spaceLength;n<length;n+=spaceLength){   
                  var ax=p0.x+n*cos;
                  var ay=p0.y+n*sin;
                  ctx.save();
                  ctx.translate(ax,ay-5);
                  ctx.rotate(angle);
                  ctx.drawImage(arrow,0,0);
                  ctx.restore();
              }

              // required for Kinetic.Shape's
              ctx.fillStrokeShape(this);
            }
        });
        s.p0=p0;
        s.p1=p1;
        layer.add(s);
        layer.draw();

    }


    // create a temp canvas containing a drawing of an arrow
    function makeArrow(){
        var c=document.createElement('canvas');
        var cctx=c.getContext('2d');
        c.width=8;
        c.height=10;
        cctx.beginPath();
        cctx.moveTo(0,0);
        cctx.lineTo(8,5);
        cctx.lineTo(0,10);
        cctx.stroke();
        return(c);
    }


}); // end $(function(){});

</script>       
</head>
<body>
    <div id="container"></div>
</body>
</html>