错误的边框coords与fabric.js绘制多边形

时间:2015-02-27 16:09:28

标签: polygon fabricjs

我尝试用鼠标绘制多边形,我在jsfiddle上找到了这个例子:http://jsfiddle.net/Kienz/ujefxh7w/

问题在于,当我们完成绘制并尝试对对象进行切割时,边框位于形状之外。

我们可以解决这个问题吗?或者它是一个fabric.js错误?

正如我们在官方的fabricjs.com/页面上看到的那样,在首页的例子中,免费的手绘图也超出了边框。

  // initialize fabric canvas and assign to global windows object for debug
    var canvas = window._canvas = new fabric.Canvas('c');

   // Do some initializing stuff
fabric.Object.prototype.set({
    transparentCorners: false,
    cornerColor: 'rgba(102,153,255,0.5)',
    cornerSize: 12,
    padding: 7
});

// ADD YOUR CODE HERE
var mode = "add",
    currentShape;

canvas.observe("mouse:move", function (event) {
    var pos = canvas.getPointer(event.e);
    if (mode === "edit" && currentShape) {
        var points = currentShape.get("points");
        points[points.length - 1].x = pos.x - currentShape.get("left");
        points[points.length - 1].y = pos.y - currentShape.get("top");
        currentShape.set({
            points: points
        });
        canvas.renderAll();
    }
});

canvas.observe("mouse:down", function (event) {
    var pos = canvas.getPointer(event.e);
if (mode === "add") {
    var polygon = new fabric.Polygon([{
        x: pos.x,
        y: pos.y
    }, {
        x: pos.x + 0.5,
        y: pos.y + 0.5
    }], {
        fill: 'blue',
        opacity: 0.5,
        selectable: false
    });
    currentShape = polygon;
    canvas.add(currentShape);
    mode = "edit";
} else if (mode === "edit" && currentShape && currentShape.type === "polygon") {
    var points = currentShape.get("points");
    points.push({
        x: pos.x - currentShape.get("left"),
        y: pos.y - currentShape.get("top")
    });
    currentShape.set({
        points: points
    });
    canvas.renderAll();
}
});

fabric.util.addListener(window, 'keyup', function (e) {
    if (e.keyCode === 27) {
        if (mode === 'edit' || mode === 'add') {
            mode = 'normal';
            currentShape.set({
                selectable: true
            });
            currentShape._calcDimensions(false);
            currentShape.setCoords();
        } else {
            mode = 'add';
        }
        currentShape = null;
    }
     canvas.renderAll();
})

1 个答案:

答案 0 :(得分:2)

问题

_calcDimensions()计算多边形的宽度,高度,minX和minY,因此您可以使用此小提琴http://jsfiddle.net/ujefxh7w/90/查看多边形的中心点(使用宽度和高度计算)将在调用后更改_calcDimensions()(在此之前,中心点的值等于左上角,因为宽度和高度为零)。

但是我们通过减去左上角位置将所有点插入到多边形中,但在调用_calcDimensions()之后,这些点将从“新”(正确)中心点开始渲染,正如您从中看到的那样小提琴。

此外,我们必须处理_calcDimensions()引入的minX和minY偏移。如果我们不这样做,你可以设法绘制一些带有边界区域的形状。 (例如用这些坐标绘制一个三角形[(100,100),(150,50),(200,200)],第二个点将超出界限。

解决方案

我们必须

  1. 将minX和minY偏移量添加到我们形状的左上角位置,并从新点的值中减去它们
  2. 使用实际中心点和多边形的左上角位置重新计算点的坐标
  3. http://jsfiddle.net/ujefxh7w/115/

    fabric.util.addListener(window, 'keyup', function (e) {
        if (e.keyCode === 27) {
            if (mode === 'edit' || mode === 'add') {
                mode = 'normal';
    
                // remove last useless point
                var points = currentShape.get("points");
                points.pop(); 
                currentShape.set({points: points});
    
                // call helpers
                currentShape._calcDimensions();
                currentShape.setCoords();
    
                // adjust shape position by using minX and minY offsets
                var minx = currentShape.get("minX");
                var miny = currentShape.get("minY");
                currentShape.set({
                    left: currentShape.get("left") + minx,
                    top: currentShape.get("top") + miny
                });
    
                // adjust points coordinates by 
                // 1- subtracting the center point coords 
                // 2- adding the left-top coords  
                // 3- subtracting minX and minY offsets
                var pCenter = currentShape.getCenterPoint();
                var l = currentShape.get("left");
                var t = currentShape.get("top");
                var adjPoints = currentShape.get("points").map(function(p) {
                    return {
                        x: p.x - pCenter.x + l - minx,
                        y: p.y - pCenter.y + t - miny
                    };
                });
                currentShape.set({
                    points: adjPoints,
                    selectable: true
                });
    
                canvas.setActiveObject(currentShape);
    
                canvas.renderAll();
            } else {
                mode = 'add';
            }
            currentShape = null;
        }
    });