Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

fabric.js straight line and select on click

Tags:

fabricjs

I made 3 modes for this code:

  1. select line
  2. draw line and
  3. delete line.

It looks like it is working. But I want to change 2 things. For example that every time when I select a line i just need to click it.

Can you tell me how i can improve my code ?

Thank You for your answers.

This is my code:

<!DOCTYPE html>
<html>
<head>
 <script type ="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.5.0/fabric.min.js"></script>
 <script type ="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<title>Test</title>
</head>
<body>
<button id="select">Selection mode</button>
<button id="draw">Drawing mode</button>

<button id="delete">Delete selected object(s)</button><br />
<canvas id="c" width="400" height="400" style="border:1px solid #ccc"></canvas>

<script type="text/javascript">
var line, isDown,mode;

var canvas = new fabric.Canvas('c');

$("#select").click(function(){
    mode="select";   
         canvas.selection=true;
     canvas.perPixelTargetFind = true;
     canvas.targetFindTolerance = 4;
     canvas.renderAll();
});
$("#draw").click(function(){
    
     
    mode="draw";
});
$("#delete").click(function(){
    
    
    deleteObjects();
});

// Adding objects to the canvas...

 
canvas.on('mouse:down', function(o){
  isDown = true;
  var pointer = canvas.getPointer(o.e);
  var points = [ pointer.x, pointer.y, pointer.x, pointer.y ];
   
  if(mode=="draw"){
    line = new fabric.Line(points, {
    strokeWidth: 5,
    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);
  
  if(mode=="draw"){
  line.set({ x2: pointer.x, y2: pointer.y });
  canvas.renderAll(); }
});

canvas.on('mouse:up', function(o){
  isDown = false;
});

  

// select all objects
function deleteObjects(){
    var activeObject = canvas.getActiveObject(),
    activeGroup = canvas.getActiveGroup();
    if (activeObject) {
        if (confirm('Are you sure?')) {
            canvas.remove(activeObject);
        }
    }
    else if (activeGroup) {
        if (confirm('Are you sure?')) {
            var objectsInGroup = activeGroup.getObjects();
            canvas.discardActiveGroup();
            objectsInGroup.forEach(function(object) {
            canvas.remove(object);
            });
        }
    }
}
</script>
</body>
</html>

Ps.: Sorry for bad english or mistakes.

like image 462
Palme Avatar asked Jan 26 '16 15:01

Palme


1 Answers

When adding a line to canvas it is normally selectable. But since you modified it's own properties like width and height that derives from the 2 points, its widht and height are changed.

If you change dimensions programmatically you have to call line.setCoords() explicitly otherwise the interaction points are not calculated again.

perPixelTargetFind is optional and does not need to be called every time you go on selection mode.

So the answer is:

call line.setCoords() in your mouseup event.

Check the snippet.

<!DOCTYPE html>
<html>
<head>
 <script type ="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/1.5.0/fabric.min.js"></script>
 <script type ="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<title>Test</title>
</head>
<body>
<button id="select">Selection mode</button>
<button id="draw">Drawing mode</button>

<button id="delete">Delete selected object(s)</button><br />
<canvas id="c" width="400" height="400" style="border:1px solid #ccc"></canvas>

<script type="text/javascript">
var line, isDown,mode;

var canvas = new fabric.Canvas('c');
     canvas.perPixelTargetFind = true;
     canvas.targetFindTolerance = 4;

$("#select").click(function(){
    mode="select";   
    canvas.selection=true;
    canvas.renderAll();
});
$("#draw").click(function(){
    
     
    mode="draw";
});
$("#delete").click(function(){
    
    
    deleteObjects();
});

// Adding objects to the canvas...

 
canvas.on('mouse:down', function(o){
  isDown = true;
  var pointer = canvas.getPointer(o.e);
  var points = [ pointer.x, pointer.y, pointer.x, pointer.y ];
   
  if(mode=="draw"){
    line = new fabric.Line(points, {
    strokeWidth: 5,
    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);
  
  if(mode=="draw"){
  line.set({ x2: pointer.x, y2: pointer.y });
  canvas.renderAll(); }
});

canvas.on('mouse:up', function(o){
  isDown = false;
  line.setCoords();
});

  

// select all objects
function deleteObjects(){
    var activeObject = canvas.getActiveObject(),
    activeGroup = canvas.getActiveGroup();
    if (activeObject) {
        if (confirm('Are you sure?')) {
            canvas.remove(activeObject);
        }
    }
    else if (activeGroup) {
        if (confirm('Are you sure?')) {
            var objectsInGroup = activeGroup.getObjects();
            canvas.discardActiveGroup();
            objectsInGroup.forEach(function(object) {
            canvas.remove(object);
            });
        }
    }
}
</script>
</body>
</html>
like image 92
AndreaBogazzi Avatar answered Oct 17 '22 22:10

AndreaBogazzi