平移对象后如何解决将不再在fabric.js中选择?

时间:2018-03-16 05:46:41

标签: fabricjs

以下是问题的再现:jsfiddle。代码主要取自官方教程。



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);
&#13;
<script src="//cdnjs.cloudflare.com/ajax/libs/fabric.js/2.2.1/fabric.min.js"></script>
<canvas id="c" width="1000" height="1000"></canvas>
&#13;
&#13;
&#13;

ctrl 进行平移。尝试一个大盘(但仍然在视图内的对象)并选择对象。并尝试几次,你将面临我提到的问题,即对象不再可选。但是,如果你按下你可能会选择它,这很奇怪并且感觉很麻烦。

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

您需要object.setCoords()来设置mouse:up回调中角落的所有坐标。

<强> 样本

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>