user10024395
user10024395

Reputation: 1

How to solve after panning object will no longer be selectable in fabric.js?

Below is the reproduction of the problem: jsfiddle. Code is mostly taken from official tutorial.

var canvas = new fabric.Canvas('c');
canvas.setBackgroundImage('//www.datashinobi.com/data/person/Charlotte%20Casiraghi/0622cdb484c35923528b1537fd1970785b00241f367ff466fc36c414a50ca973.jpg')
canvas.uniScaleTransform = true

canvas.on('mouse:down', function (opt) {
  var evt = opt.e;
  if (evt.ctrlKey == true) {
    canvas.selection = false;
    canvas.forEachObject(function(o) {
      o.selectable = false;
    });
  	this.isDragging = true;
  	this.selection = false;
  	this.lastPosX = evt.clientX;
  	this.lastPosY = evt.clientY;
	}
});

canvas.on('mouse:move', function (opt) {
	if (this.isDragging) {
  	var e = opt.e;
    this.viewportTransform[4] += e.clientX - this.lastPosX;
    this.viewportTransform[5] += e.clientY - this.lastPosY;
    this.requestRenderAll();
    this.lastPosX = e.clientX;
    this.lastPosY = e.clientY;
  }
});

canvas.on('mouse:up', function (opt) {
	this.isDragging = false;
  this.selection = true;
  canvas.selection = true;
  canvas.forEachObject(function(o) {
    o.selectable = true;
  });
});

canvas.on('mouse:wheel', function (opt) {
	var delta = opt.e.deltaY;
  var pointer = canvas.getPointer(opt.e);
  var zoom = canvas.getZoom();
  zoom = zoom - delta * 0.01;
  if (zoom > 9) {
  	zoom = 9;
  }
  if (zoom < 1) {
  	zoom = 1;
  }
  canvas.zoomToPoint({x: opt.e.offsetX, y: opt.e.offsetY}, zoom);
  opt.e.preventDefault();
  opt.e.stopPropagation();
});

var rect = new fabric.Rect({
	left: 100,
  top: 100,
  fill: 'red',
  width: 100,
  height: 100,
  opacity: 0.4,
  hasRotatingPoint: false,
  hasBorders: false,

})


canvas.add(rect);
<script src="//cdnjs.cloudflare.com/ajax/libs/fabric.js/2.2.1/fabric.min.js"></script>
<canvas id="c" width="1000" height="1000"></canvas>

Press ctrl to pan. Try a large pan(but object still within view) and select the object. And try a few times and you will face the problem I mention, which is that the object is no longer selectable. However, if you press around you may be able to select it, which is weird and feels buggy.

How can I solve this problem?

Upvotes: 1

Views: 1475

Answers (1)

Durga
Durga

Reputation: 15614

All you need is object.setCoords() to set all the coordinate of corners inside mouse:up callback.

DEMO

var canvas = new fabric.Canvas('c');
canvas.setBackgroundImage('//www.datashinobi.com/data/person/Charlotte%20Casiraghi/0622cdb484c35923528b1537fd1970785b00241f367ff466fc36c414a50ca973.jpg', canvas.renderAll.bind(canvas))
canvas.uniScaleTransform = true

canvas.on('mouse:down', function(opt) {
  var evt = opt.e;
  if (evt.ctrlKey == true) {
    canvas.selection = false;
    canvas.discardActiveObject();
    canvas._currentTransform = null;  canvas.forEachObject(function(o) {
      o.selectable = false;
    });
    this.isDragging = true;
    this.selection = false;
    this.lastPosX = evt.clientX;
    this.lastPosY = evt.clientY;
  }
});

canvas.on('mouse:move', function(opt) {
  if (this.isDragging) {
    var e = opt.e;
    this.viewportTransform[4] += e.clientX - this.lastPosX;
    this.viewportTransform[5] += e.clientY - this.lastPosY;
    this.requestRenderAll();
    this.lastPosX = e.clientX;
    this.lastPosY = e.clientY;
  }
});

canvas.on('mouse:up', function(opt) {
  this.isDragging = false;
  this.selection = true;
  canvas.selection = true;
  canvas.forEachObject(function(o) {
    o.selectable = true;
    o.setCoords();
  });
});

canvas.on('mouse:wheel', function(opt) {
  var delta = opt.e.deltaY;
  var pointer = canvas.getPointer(opt.e);
  var zoom = canvas.getZoom();
  zoom = zoom - delta * 0.01;
  if (zoom > 9) {
    zoom = 9;
  }
  if (zoom < 1) {
    zoom = 1;
  }
  canvas.zoomToPoint({
    x: opt.e.offsetX,
    y: opt.e.offsetY
  }, zoom);
  opt.e.preventDefault();
  opt.e.stopPropagation();
});

var rect = new fabric.Rect({
  left: 100,
  top: 100,
  fill: 'red',
  width: 100,
  height: 100,
  opacity: 0.4,
  hasRotatingPoint: false,
  hasBorders: false,

})
canvas.add(rect);
<script src="//cdnjs.cloudflare.com/ajax/libs/fabric.js/2.2.1/fabric.min.js"></script>
<canvas id="c" width="1000" height="1000"></canvas>

Upvotes: 3

Related Questions