在画布上的弯头连接器末端绘制箭头

时间:2014-02-17 06:31:58

标签: javascript canvas

我已经实现了在画布上绘制的弯头连接器工具,弯头连接器工作正常,但我想在弯头连接器的末端显示箭头。我已经在行尾添加了箭头,但有些我不能为箭头结束获得正确的角度,并且当我的肘部连接器移动时,我的箭头结束保持旋转。可以请任何人帮忙。下面是我的代码。

    var startPosX1, startPosY1, startPosX2 = "", startPosY2 = "", midPosX1, midPosY1;
function tool_elbowArrowConnect() {
    var tool = this;
    this.started = false;
    //cPush();
    this.mousedown = function (ev) {
        tool.started = true;
        tool.x0 = startPosX1 = ev.offsetX;
        tool.y0 = startPosY1 = ev.offsetY;
        cPush();
    };

    this.mousemove = function (ev) {
        if (!tool.started) {
            return;
        }

        context.clearRect(0, 0, canvas.width, canvas.height);
        context.strokeStyle = strokeColor;
        var curPosX, curPosY;
        curPosX = ev.offsetX;
        curPosY = ev.offsetY;
        //elbow connector logic
        if (curPosX > startPosX1) {
            midPosX1 = ((curPosX - startPosX1) / 2) + startPosX1;
        }
        else if (startPosX > curPosX) {
            midPosX1 = ((startPosX1 - curPosX) / 2) + curPosX;
        }

        if (curPosY > startPosY1) {
            midPosY1 = ((curPosY - startPosY1) / 2) + startPosY1;
        }
        else if (startPosY1 > curPosY) {
            midPosY1 = ((startPosY1 - curPosY) / 2) + curPosY;
        }

        //Line 1
        context.beginPath();
        context.moveTo(startPosX1, startPosY1);
        context.lineTo(midPosX1, startPosY1);
        context.strokeStyle = strokeColor;
        context.stroke();
        context.closePath();

        //Line2
        context.beginPath();
        context.moveTo(midPosX1, startPosY1);
        context.lineTo(midPosX1, curPosY);
        context.strokeStyle = strokeColor;
        context.stroke();
        context.closePath();

        //Line3
        context.beginPath();
        context.moveTo(midPosX1, curPosY);
        context.lineTo(curPosX, curPosY);
        context.strokeStyle = strokeColor;
        context.stroke();

        if (midPosX1 != undefined && startPosX2 == "" && startPosY2 == "") {
            startPosX2 = midPosX1;
            startPosY2 = curPosY;
        }

        //  context.closePath();

        if (startPosX2 != ev.offsetX && startPosY2 != ev.offsetY) {
            var radianAngle = Math.atan((ev.offsetY - startPosY2) / (ev.offsetX - startPosX2));
            radianAngle += ((ev.offsetX > startPosX2) ? 90 : -90) * Math.PI / 180;
            drawArrowhead(ev.offsetX, ev.offsetY, radianAngle, context);
        }

    };

    this.mouseup = function (ev) {
        if (tool.started) {
            tool.mousemove(ev);
            tool.started = false;
            img_update();
        }
    };

}

function drawArrowhead(x, y, radians, ctx) {
    // context.clearRect(x - 5, y - 5, 10, 10);
    ctx.save();
    ctx.strokeStyle = strokeColor;
    ctx.lineWidth = 2;
    ctx.beginPath();
    ctx.translate(x, y);
    ctx.rotate(radians);
    ctx.moveTo(0, 0);
    ctx.lineTo(6, 10);
    ctx.lineTo(-6, 10);
    ctx.closePath();
    ctx.restore();
    ctx.fillStyle = strokeColor;
    ctx.fill();
}

1 个答案:

答案 0 :(得分:2)

由于你的箭头需要在一行的末尾以适当的角度绘制,这里是你的代码的重构,它为箭头函数提供了它所需行的定义:

演示:http://jsfiddle.net/m1erickson/MyGDX/

// given a line x1,y1 to x2,y2, draw an arrowhead at x2,y2 at proper angle

var PI2=Math.PI*2;

function drawArrowhead(x1,y1,x2,y2){
    var dx=x2-x1;
    var dy=y2-y1;
    var radians=(Math.atan2(dy,dx)+PI2)%PI2;
    ctx.save();
    ctx.lineWidth = 2;
    ctx.beginPath();
    ctx.translate(x2, y2);
    ctx.rotate(radians);
    ctx.moveTo(0,0);
    ctx.lineTo(-10,6);
    ctx.lineTo(-10,-6);
    ctx.closePath();
    ctx.fillStyle = strokeColor;
    ctx.fill();
    ctx.restore();
}