Draw a polygon freely using the fabric.js

2

I'm using this code to try to draw a polygon freely: link

canvas.on('mouse:move', function (options) {
        if (lines[0] !== null && drawingObject.type == "roof") {
            setStartingPoint(options);
            lines[lineCounter - 1].set({
                x2: x,
                y2: y
            });
            canvas.renderAll();
        }
    });

My problem is that when I use this code on my page it does not draw correctly. When I start drawing the polygon the lines do not appear in the place where I asked them to draw but always from the top left field. when I click to get the polygon it is drawn in the correct place.

    
asked by anonymous 24.04.2014 / 00:13

1 answer

1

Script operation

The script is an editor that lets you draw and work with geometric shapes. To do this, it is necessary to click on the label "PressTo Draw! And to stop", then click on some points inside the drawing rectangle and again on the label above. Clicked points will be enclosed in a polygon filled with purple.

I added the explanation because it may not be intuitive at first.

The problem

As I understand it, the problem occurs when drawing a second shape, because it seems to interfere with the first one drawn. The same would occur with subsequent forms.

The cause

The cause is the infamous global variables ( roofPoints , lines and lineCounter ).

Because they are not redefined after drawing one of the shapes, the following form will include the points of the previous shape. (I did not analyze all the impacts that occurred).

The solution

I took the liberty of doing a fiddle fork and apply a few simple adjustments.

The main adjustment was to restart the variables mentioned at the beginning of the drawing of a shape. See the excerpt:

$("#btnRoof").click(function () {
    if (drawingObject.type == "roof") {
        drawingObject.type = "";
        canvas.remove(lines[lineCounter - 1]);
        var roof = makeRoof(roofPoints);
        canvas.add(roof);
        canvas.renderAll();
    } else {
        drawingObject.type = "roof"; // roof type
        roofPoints = [];
        lines = [];
        lineCounter = 0;            
    }
});

Conclusion

Avoid working with global variables to avoid falling into this type of problem. Always use the minimum scope for the variables.

For example, look at the variable roof on the modified fiddle. It is declared locally, as there was no need for it to be global.

I know that at some point it is important to share the variables between the various events, but try to do this by encapsulating the variables into an object that can be easily restarted.

Anyway, my intention is not to criticize, because surely it is possible to adjust the script without difficulties. But if the idea is to include more features and make it more complex, tunneling will make a huge difference to not get to the point where any maintenance will stop it from working.

    
24.04.2014 / 14:19