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?
 
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
 
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
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.