Grouping elements on canvas using fabric.js

Next code is  drawing  lines on canvas when mouse is pressed.
I have to add some functions  to get polyline form more  lines.
As fabric.js library has option to select specific element on canvas i think i could use this option.

Once i select all lines that will be part of my polyline i would like to use double click then to group lines and call:
polylineName  = prompt("Enter polyline name : ", "");  
to complete the polyline.

I need instructions how to proceed?



<!DOCTYPE html>
<html>
<head>
<title>HTML, CSS and JavaScript demo</title>
  <style>
   #drawCanvas{
    position:absolute;
    top:0;
    left:0;
}
  </style>
</head>
<body>

<canvas id="canvas"></canvas>
<canvas id="drawCanvas"></canvas>
  <script>
   var canvas = document.getElementById("canvas"),
    ctx = canvas.getContext("2d"),
    drawCanvas = document.getElementById("drawCanvas"),
    drawCtx = drawCanvas.getContext("2d"),
    painting = false,
    lastX = 0,
    lastY = 0,
    curX = 0,
    curY = 0,
    startX = 0,
    startY = 0,
    lineThickness = 1;

canvas.width = canvas.height = 600;

drawCanvas.width = drawCanvas.height = 600;

drawCanvas.onmousedown = function(e) {
    painting = true;
    drawCtx.fillStyle = "#000";
    lastX = e.pageX - this.offsetLeft;
    lastY = e.pageY - this.offsetTop;
    startX = lastX;
    startY = lastY;
};

drawCanvas.onmouseup = function(e){
    painting = false;
    var x2 = e.pageX - this.offsetLeft,
        y2 = e.pageY - this.offsetTop;
    
    ctx.strokeStyle = "#000";
    ctx.beginPath();
    ctx.moveTo(startX, startY);
    ctx.lineTo(x2, y2);
    ctx.stroke();
    
    drawCtx.clearRect(0, 0, 600, 600);
}
    
drawCanvas.onmouseclick = function(e) {
    drawCtx.fillStyle = "#000";
    lastX = e.pageX - this.offsetLeft;
    lastY = e.pageY - this.offsetTop;
    startX = lastX;
    startY = lastY;

    if(painting){
        
    }

    else{
        painting = true;
        lastX = e.pageX - this.offsetLeft;
        lastY = e.pageY - this.offsetTop;
        startX = lastX;
        startY = lastY;
    }
};

drawCanvas.onmousemove = function(e) {
    if (painting) {
        mouseX = e.pageX - this.offsetLeft;
        mouseY = e.pageY - this.offsetTop;

        // find all points between        
        var x1 = mouseX,
            x2 = lastX,
            y1 = mouseY,
            y2 = lastY;


        var steep = (Math.abs(y2 - y1) > Math.abs(x2 - x1));
        if (steep){
            var x = x1;
            x1 = y1;
            y1 = x;

            var y = y2;
            y2 = x2;
            x2 = y;
        }
        if (x1 > x2) {
            var x = x1;
            x1 = x2;
            x2 = x;

            var y = y1;
            y1 = y2;
            y2 = y;
        }

        var dx = x2 - x1,
            dy = Math.abs(y2 - y1),
            error = 0,
            de = dy / dx,
            yStep = -1,
            y = y1;
        
        if (y1 < y2) {
            yStep = 1;
        }
       
        for (var x = x1; x < x2; x++) {
            if (steep) {
                drawCtx.fillRect(y, x, lineThickness , lineThickness );
            } else {
                drawCtx.fillRect(x, y, lineThickness , lineThickness );
            }
            
            error += de;
            if (error >= 0.5) {
                y += yStep;
                error -= 1.0;
            }
        }

        lastX = mouseX;
        lastY = mouseY;

    }
}

  </script>

</body>
</html>

Open in new window

Ivan GolubarAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Leonidas DosasCommented:
Check this example from GoJS
<!doctype html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
	<script src="https://cdnjs.cloudflare.com/ajax/libs/gojs/1.8.16/go-debug.js"></script>
	<script src="https://cdnjs.cloudflare.com/ajax/libs/gojs/1.8.16/go.js"></script>
	<script src="https://gojs.net/latest/extensions/PolygonDrawingTool.js"></script>
	<script src="https://gojs.net/latest/extensions/GeometryReshapingTool.js"></script>
</head>
<body>
	<script id="code">
  function init() {
    if (window.goSamples) goSamples();  // init for these samples -- you don't need to call this
    var $ = go.GraphObject.make;
    myDiagram =
      $(go.Diagram, "myDiagramDiv");
    myDiagram.toolManager.mouseDownTools.insertAt(3, new GeometryReshapingTool());
    myDiagram.nodeTemplateMap.add("PolygonDrawing",
      $(go.Node,
        { locationSpot: go.Spot.Center },  // to support rotation about the center
        new go.Binding("location", "loc", go.Point.parse).makeTwoWay(go.Point.stringify),
        { selectionAdorned: true, selectionObjectName: "SHAPE",
          selectionAdornmentTemplate:  // custom selection adornment: a blue rectangle
            $(go.Adornment, "Auto",
              $(go.Shape, { stroke: "dodgerblue", fill: null }),
              $(go.Placeholder, { margin: -1 }))
        },
        { resizable: true, resizeObjectName: "SHAPE" },
        { rotatable: true, rotateObjectName: "SHAPE" },
        { reshapable: true },  // GeometryReshapingTool assumes nonexistent Part.reshapeObjectName would be "SHAPE"
        $(go.Shape,
          { name: "SHAPE", fill: "lightgray", strokeWidth: 1.5 },
          new go.Binding("desiredSize", "size", go.Size.parse).makeTwoWay(go.Size.stringify),
          new go.Binding("angle").makeTwoWay(),
          new go.Binding("geometryString", "geo").makeTwoWay(),
          new go.Binding("fill"),
          new go.Binding("stroke"),
          new go.Binding("strokeWidth"))
      ));
    // create polygon drawing tool for myDiagram, defined in PolygonDrawingTool.js
    var tool = new PolygonDrawingTool();
    // provide the default JavaScript object for a new polygon in the model
    tool.archetypePartData =
      { fill: "yellow", stroke: "blue", strokeWidth: 3, category: "PolygonDrawing" };
    tool.isPolygon = true;  // for a polyline drawing tool set this property to false
    // install as first mouse-down-tool
    myDiagram.toolManager.mouseDownTools.insertAt(0, tool);
    load();  // load a simple diagram from the textarea
  }
  function mode(draw, polygon) {
    // assume PolygonDrawingTool is the first tool in the mouse-down-tools list
    var tool = myDiagram.toolManager.mouseDownTools.elt(0);
    tool.isEnabled = draw;
    tool.isPolygon = polygon;
    tool.archetypePartData.fill = (polygon ? "yellow" : null);
    tool.temporaryShape.fill = (polygon ? "yellow" : null);
  }
  // this command ends the PolygonDrawingTool
  function finish(commit) {
    var tool = myDiagram.currentTool;
    if (commit && tool instanceof PolygonDrawingTool) {
      var lastInput = myDiagram.lastInput;
      if (lastInput.event instanceof window.MouseEvent) tool.removeLastPoint();  // remove point from last mouse-down
      tool.finishShape();
    } else {
      tool.doCancel();
    }
  }
  // this command removes the last clicked point from the temporary Shape
  function undo() {
    var tool = myDiagram.currentTool;
    if (tool instanceof PolygonDrawingTool) {
      var lastInput = myDiagram.lastInput;
      if (lastInput.event instanceof window.MouseEvent) tool.removeLastPoint();  // remove point from last mouse-down
      tool.undo();
    }
  }
  function updateAllAdornments() {  // called after checkboxes change Diagram.allow...
    myDiagram.selection.each(function(p) { p.updateAdornments(); });
  }
  // save a model to and load a model from Json text, displayed below the Diagram
  function save() {
    var str = '{ "position": "' + go.Point.stringify(myDiagram.position) + '",\n  "model": ' + myDiagram.model.toJson() + ' }';
    document.getElementById("mySavedDiagram").value = str;
  }
  function load() {
    var str = document.getElementById("mySavedDiagram").value;
    try {
      var json = JSON.parse(str);
      myDiagram.initialPosition = go.Point.parse(json.position || "0 0");
      myDiagram.model = go.Model.fromJson(json.model);
      myDiagram.model.undoManager.isEnabled = true;
    } catch (ex) {
      alert(ex);
    }
  }
</script>
</head>
<body onload="init()">
<div id="sample">
  <div id="myDiagramDiv" style="border: solid 1px black; width: 100%; height: 350px"></div>
  <div id="buttons">
    <button onclick="mode(false)">Select</button>
    <button onclick="mode(true, true)">Draw Polygon</button>
    <button onclick="mode(true, false)">Draw Polyline</button>
    <button onclick="finish(true)">Finish Drawing</button>
    <button onclick="finish(false)">Cancel Drawing</button>
    <button onclick="undo()">Undo Last Point</button>
    <br/>
    <label><input type="checkbox" onclick="myDiagram.allowResize = !myDiagram.allowResize; updateAllAdornments()" checked="checked" />Allow Resizing</label>
    <label><input type="checkbox" onclick="myDiagram.allowReshape = !myDiagram.allowReshape; updateAllAdornments()" checked="checked" />Allow Reshaping</label>
    <label><input type="checkbox" onclick="myDiagram.allowRotate = !myDiagram.allowRotate; updateAllAdornments()" checked="checked" />Allow Rotating</label>
  </div>
 
  <div>
    <button onclick="save()">Save</button>
    <button onclick="load()">Load</button>
  </div>
  <textarea id="mySavedDiagram" style="width:100%;height:300px">
{ "position": "0 0",
  "model": { "class": "go.GraphLinksModel",
  "nodeDataArray": [ {"loc":"183 148", "category": "PolygonDrawing", "geo":"F M0 145 L75 2 L131 87 L195 0 L249 143z", "key":-1} ],
  "linkDataArray": [  ]
} }
  </textarea>
</div>
</body>
</html>

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Ivan GolubarAuthor Commented:
Thank you.

It has exactly what i need.
0
Ivan GolubarAuthor Commented:
Next two libraries i can see as *.rtf.
<script src="https://gojs.net/latest/extensions/PolygonDrawingTool.js"></script>
<script src="https://gojs.net/latest/extensions/GeometryReshapingTool.js"></script>


But why i can't see  the other two. Why?
      <script src="https://cdnjs.cloudflare.com/ajax/libs/gojs/1.8.16/go-debug.js"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/gojs/1.8.16/go.js"></script>
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
JavaScript

From novice to tech pro — start learning today.