在两条线的交叉处画桥

时间:2016-05-14 07:24:33

标签: fabricjs

我刚开始使用fabric.js 我可以在画布上得到两条线的交点。

enter image description here

现在我需要知道如何在两条线上绘制桥梁。

enter image description here

感谢。

1 个答案:

答案 0 :(得分:2)

这是我能得到的输出:

appcmd

我使用了以下代码(我从enter image description here的原始代码中更改了一些内容):

// Multiple_connected_lines_and_curves.js
// this fabric.js demo was based upon the Quadratic Curve demo and the Stickman demo
var canvas = new fabric.Canvas('mycanvas');


// ------- points & circles -------

function distance(p1, p2) {
    //Accepts two objects p1 & p2. Returns the distance between p1 & p2
    return Math.sqrt(((p2.left - p1.left) * (p2.left - p1.left)) + ((p2.top - p1.top) * (p2.top - p1.top)));
} // distance()

function addCircle(name, x, y) {

    var c = new fabric.Circle({
        name: name,
        left: x,
        top: y,
        hasBorders: false,
        hasControls: false,
        lockUniScaling: true,
        selectable: true,
        coords: x + ', ' + y,
        reference: true
    });
    return c;
} // addCircle()


function addPoint(name, x, y, style) {

    var p = addCircle(name, x, y, style);;
    p.point = new fabric.Point(x, y);
    p.text = new fabric.Text(name, {
        left: x,
        top: y - 10,
        name: name + '_text',
        fontSize: 14,
        hasBorders: false,
        hasControls: false,
        lockUniScaling: true,
        selectable: false,
        reference: true
    });
    canvas.add(p.text);
    canvas.add(p);
    canvas.bringToFront(p);
    return p;
} // addPoint()


// ------- paths -------

function addLine(p0, p1) {
    var new_line = new fabric.Object();
    new_line = new fabric.Line([p0.left, p0.top, p1.left, p1.top], {
        fill: "black",
        stroke: "black",
        strokeLinejoin: "miter",
        strokeMiterlimit: 1,
        strokeWidth: 1,
        selectable: false,
        hasBorders: false,
        hasControls: false,
        reference: false,
        name: "Line_" + p0.name + p1.name
    });
    if (p0.hasOwnProperty('outPath') === false) {
        p0.outPath = [];
    }
    p0.outPath.push(new_line);
    if (p1.hasOwnProperty('inPath') === false) {
        p1.inPath = [];
    }
    p1.inPath.push(new_line);
    canvas.add(new_line);
    canvas.sendBackwards(new_line);
    canvas.bringToFront(p0);
    canvas.bringToFront(p1);
    return new_line;
} //addLine()

function addCurve(p0, c0, c1, p1) {
    // path are stored as an array of two arrays
    // [['M', p0.left, p0.top], ['C', c0.left, c0.top, c1.left, c1.top, p1.left, p1.top]]
    // [0][0], [0][1], [0][2], [1][0], [1][1], [1][2], [1][3], [1][4], [1][5], [1][6]
    // [0][0] = 'M',   [1][0] = 'C'
    var path_str = 'M ' + p0.left + ' ' + p0.top + ' C ' + c0.left + ' ' + c0.top + ' ' + c1.left + ' ' + c1.top + ' ' + p1.left + ' ' + p1.top;
    var new_path = new fabric.Path(path_str, {
        fill: "",
        stroke: "black",
        strokeLinejoin: "miter",
        strokeMiterlimit: 1,
        strokeWidth: 1,
        hasBorders: false,
        hasControls: false,
        selectable: false,
        reference: false,
        name: 'Curve_' + p0.name + p1.name
    });
    //new_path is an outPath for p0 & c0
    if (p0.hasOwnProperty('outPath') === false) {
        // create p0.outPath array if it doesn't exist
        p0.outPath = [];
    }
    p0.outPath.push(new_path);
    if (c0.hasOwnProperty('outPath') === false) {
        // create c0.outPath array if it doesn't exist
        c0.outPath = [];
    }
    c0.outPath.push(new_path);

    //new_path is an inPath for c1 & p1
    if (c1.hasOwnProperty('inPath') === false) {
        // create c1.inPath array if not exist
        c1.inPath = [];
    }
    c1.inPath.push(new_path);

    if (p1.hasOwnProperty('inPath') === false) {
        // create p1.inPath array if not exist
        p1.inPath = [];
    }
    p1.inPath.push(new_path);

    //draw new_path on canvas
    canvas.add(new_path);
    canvas.bringToFront(p0);
    canvas.bringToFront(p1);
    canvas.bringToFront(c0);
    canvas.bringToFront(c1);
    return new_path;
} //addCurve()


// ------- main -------

// constants
var IN = 90; // 90px per inch
// resize canvas
canvas.setWidth(5 * IN);
canvas.setHeight(5 * IN);
// corner points
var a1 = addPoint('', 1 * IN, 2 * IN);
var a2 = addPoint('', 2 * IN, 1 * IN);
var a3 = addPoint('', 3 * IN, 2 * IN);
var a4 = addPoint('', 2 * IN, 3 * IN);

var a1c11 = addPoint('', 1.9 * IN, 2 * IN);
var a1c12 = addPoint('', 2.1 * IN, 2 * IN);

// control points
a1.c1 = addPoint('', 5 * IN, 1 * IN, 'control');
a1.c2 = addPoint('', 1 * IN, 2 * IN, 'control');
a2.c1 = addPoint('', 2 * IN, 3 * IN, 'control');
a2.c2 = addPoint('', 3 * IN, 2 * IN, 'control');

a1c11.c1 = addPoint('', 2 * IN, 1.85 * IN, 'control');
a1c11.c2 = addPoint('', 2 * IN, 1.85 * IN, 'control');

// draw curves & lines
addCurve(a1c11, a1c11.c1, a1c11.c2, a1c12);
addLine(a4, a2); // vertical line
addLine(a1, a1c11);
addLine(a3, a1c12);


// ------- all objects have been drawn; define observers -------

canvas.observe('object:modified', function (e) {
    //update curves, lines & text when circles are moved
    // lines are accessed using .x1, .y1, .x2, .y2 attributes
    // curves are accessed through its 2 arrays:
    // [0][0] = 'M', [0][1] = po.x, [0][2] = po.y
    // [1][0]='C', [1][1]=c0.x, [1][2]=c0.y, [1][3]=c1.x, [1][4]=c1.y, [1][5]=p1.x, [1][6]=p1.y

    var p = e.target;
    console.log('Moving ' + p.name);

    if (p.hasOwnProperty("text") === true) {
        //move text label to new circle location
        p.text.set({
            'left': p.left,
            'top': p.top - 10
        });
    }

    if (p.hasOwnProperty("inPath") === true) {
        //inpaths - paths end at circle
        for (var i = 0; i < p.inPath.length; i++) {
            ppath = p.inPath[i];
            if (p.ptype === 'control') {
                ppath.path[1][3] = p.left; // p is 2nd control circle in curve, update c1.x
                ppath.path[1][4] = p.top; // p is 2nd control circle in curve, update c1.y
            } else if (ppath.type === 'path') {
                ppath.path[1][5] = p.left; // p is end circle in curve, update p1.x
                ppath.path[1][6] = p.top; // p is end circle in curve update p1.y
            } else if (ppath.type === 'line') {
                ppath.set({
                    'x2': p.left,
                    'y2': p.top
                }); //p is begin circle in line, update left & top
            }
        }
    }
    if (p.hasOwnProperty("outPath") === true) {
        //outpaths - paths begin at circle
        for (var i = 0; i < p.outPath.length; i++) {
            ppath = p.outPath[i];
            if (p.ptype === 'control') {
                ppath.path[1][1] = p.left; //p is 1st control circle in curve, update c0.x
                ppath.path[1][2] = p.top; //p is 1st control circle in curve, update c0.y
            } else if (ppath.type === 'path') {
                ppath.path[0][1] = p.left; // p is begin circle in curve, update p0.x
                ppath.path[0][2] = p.top; // p is begin circle in curve, update p0.y
            } else if (ppath.type === 'line') {
                ppath.set({
                    'x1': p.left,
                    'y1': p.top
                }); //p is end circle in line, update left & top
            }
        }
    }
    console.log(p.name + ' moved!');
    canvas.renderAll();
    canvas.bringToFront(p);
}); //canvas.observe()

我没有更改HTML部分,它仅供参考:

<h2>Multiple connected lines and curves</h2>
    <canvas id="mycanvas" width="300" height="300" style="border:2px selectable=false solid #ccc"></canvas>

您可以通过更改上述代码中的以下变量来更改曲线:

...
var a1c11 = addPoint('', 1.9 * IN, 2 * IN);
var a1c12 = addPoint('', 2.1 * IN, 2 * IN);
...
a1c11.c1 = addPoint('', 2 * IN, 1.85 * IN, 'control');
a1c11.c2 = addPoint('', 2 * IN, 1.85 * IN, 'control');
...

另外,为了只看到水平线与#34;桥接&#34; (您提到过),只需删除以下内容:

addLine(a4, a2); // vertical line

http://jsfiddle.net/Q9t6e/

希望这有帮助