Fabricjs在绘图时连接线条

Fabricjs connect lines when drawing

本文关键字:连接线 绘图 Fabricjs      更新时间:2023-09-26

我需要画连接的线。例如,对于简单的线条,我需要绘制三角形、矩形等,并且我需要将线条连接到它们的端点。当可以建立联系时,突出显示圆圈会很棒。在我的代码中,我能够绘制线条(就像折线一样),但我无法将第一行与最后一行连接起来。我尝试做鼠标:over和mouse:out事件,但它们不起作用。

链接到我的代码示例:

https://jsfiddle.net/5gLwL7d3/

这是我的代码:

<canvas id="c" width="500" height="470" style="border:1px solid #ccc"></canvas>

JavaScript

var canvas = new fabric.Canvas('c', { selection: false });
fabric.Object.prototype.originX = fabric.Object.prototype.originY = 'center';
var line, isDown, isOver;
var lines = [];
var id = 1;
canvas.on('mouse:down', function(o){
    console.log("MOUSE:DOWN");
  isDown = true;
  var pointer = canvas.getPointer(o.e);
  var points = [ pointer.x, pointer.y, pointer.x, pointer.y ];
  line = new fabric.Line(points, {
    strokeWidth: 9,
    fill: 'red',
    stroke: 'red',
    originX: 'center',
    originY: 'center'
  });
  canvas.add(line);
});
canvas.on('mouse:move', function(o){
  if (!isDown) return;
  var pointer = canvas.getPointer(o.e);
  line.set({ x2: pointer.x, y2: pointer.y });
  canvas.renderAll();
});
fabric.util.addListener(window,'keyup', function(e) {
        console.log("KEYUP :: "  + e.keyCode);
        if (e.keyCode === 13) {
        isDown = false;         
    }
});
canvas.on('mouse:over', function(e) {
    //e.target.setFill('red');
    isOver = true;
    console.log("MOUSE:OVER");
    console.log(e);
});
canvas.on('mouse:out', function(e) {
    isOver = false;
    console.log("MOUSE:OUT");
});

谢谢!

我为这个问题创建了解决方案。效率应该有一些变化,但代码工作正常。

var canvas = new fabric.Canvas('c', { selection: false });
fabric.Object.prototype.originX = fabric.Object.prototype.originY = 'center';
var circle, line;
var isDown = false;
var isOver = false;
var lines = [];
var circles = [];
var id = 1;
var x2 = 0;
var y2 = 0;
var circleIndex;
var startDraw = false;

canvas.on('mouse:down', function (options) {
    isDown = true;
            var pointer = canvas.getPointer(options.e);
            if (isOver) {
                var points = [x2, y2, x2, y2];
            } else if (!isOver) {
                var points = [pointer.x, pointer.y, pointer.x, pointer.y];
            }
            if (!isOver || !startDraw) {
                line = new fabric.Line(points, {
                    strokeWidth: 3,
                    fill: 'red',
                    stroke: 'red',
                    originX: 'center',
                    originY: 'center',
                    selectable: false
                });
                circle = new fabric.Circle({
                    left: line.x1,
                    top: line.y1,
                    strokeWidth: 1,
                    opacity: 0.5,
                    radius: 10,
                    fill: 'transparent',
                    stroke: '#666',
                    perPixelTargetFind: true,
                    selectable: false
                });
                circle.position = "left";
                circle.hasControls = circle.hasBorders = false;
                circles.push(circle);
                canvas.add(circle)
                lines.push(line);
                circle.lineId = lines.length - 1;
                canvas.add(line);
            } else {
                startDraw = false;
                if (circles[circleIndex].position === 'left') {
                    var points = [lines[circles[circleIndex].lineId].x1,
                                  lines[circles[circleIndex].lineId].y1,
                                  lines[circles[circleIndex].lineId].x1,
                                  lines[circles[circleIndex].lineId].y1];
                }
                else {
                    var points = [lines[circles[circleIndex].lineId].x2,
                                  lines[circles[circleIndex].lineId].y2,
                                  lines[circles[circleIndex].lineId].x2,
                                  lines[circles[circleIndex].lineId].y2];
                }
                line = new fabric.Line(points, {
                    strokeWidth: 3,
                    fill: 'red',
                    stroke: 'red',
                    originX: 'center',
                    originY: 'center',
                    selectable: false
                });
                canvas.add(line);
                lines.push(line);
            }
});
canvas.on('mouse:move', function (options) {
    var pt = { x: options.e.clientX, y: options.e.clientY };
            for (i = 0; i < circles.length; i++) {
                if (circles[i].containsPoint(pt)) {
                    if (!circles[i].mouseOver) {
                        circles[i].mouseOver = true;
                        circles[i].set('radius', 12);
                        circles[i].set('opacity', 1.0);
                        circles[i].set('selectable', false);
                        canvas.renderAll();
                        isOver = true;
                        circleIndex = i;
                        if (circles[i].position === 'left') {
                            x2 = lines[circles[i].lineId].x1;
                            y2 = lines[circles[i].lineId].y1;
                        } else {
                            x2 = lines[circles[i].lineId].x2;
                            y2 = lines[circles[i].lineId].y2;
                        }
                    }
                } else if (circles[i].mouseOver) {
                    circles[i].mouseOver = false;
                    circles[i].set('opacity', 0.5);
                    circles[i].set('radius', 10);
                    circles[i].set('selectable', false);
                    canvas.renderAll();
                    isOver = false;
                }
            }

            if (!isDown) {
                startDraw = true;
                return;
            }
            startDraw = false;
            var pointer = canvas.getPointer(options.e);
            if (isOver) {
                line.set({ x2: x2, y2: y2 });
            } else {
                line.set({ x2: pointer.x, y2: pointer.y });
            }
            canvas.renderAll();
});
fabric.util.addListener(window, 'keyup', function (options) {
if (options.keyCode === 13) {
                isDown = false;
                if (isOver) {
                    circles[circleIndex].set('radius', 10);
                    circles[circleIndex].set('opacity', 0.5);
                    canvas.renderAll();
                    line.set({ x2: x2, y2: y2 });
                    isOver = false;
                } else {
                    canvas.add(line);
                    circle = new fabric.Circle({
                        left: lines[lines.length - 1].x2,
                        top: lines[lines.length - 1].y2,
                        strokeWidth: 1,
                        opacity: 0.5,
                        radius: 10,
                        fill: 'transparent',
                        stroke: '#666',
                        perPixelTargetFind: true,
                        selectable: false
                    });
                    circle.position = "right";
                    circle.hasControls = circle.hasBorders = false;
                    circle.lineId = lines.length - 1;
                    circles.push(circle);
                    canvas.add(circle);
                    canvas.renderAll();
                }
            }

});