【问题标题】:How to solve after panning object will no longer be selectable in fabric.js?在fabric.js中无法选择平移对象后如何解决?
【发布时间】:2018-03-16 19:47:33
【问题描述】:

下面是问题的重现: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);
<script src="//cdnjs.cloudflare.com/ajax/libs/fabric.js/2.2.1/fabric.min.js"></script>
<canvas id="c" width="1000" height="1000"></canvas>

ctrl 进行平移。尝试大平移(但对象仍在视图中)并选择对象。再试几次,你就会遇到我提到的问题,即对象不再可选择。但是,如果你按一下你可能会选择它,这很奇怪,感觉有问题。

我该如何解决这个问题?

【问题讨论】:

    标签: fabricjs


    【解决方案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>

    【讨论】:

    • 并在您的setBackgroundImage() 中在回调中执行渲染调用。检查答案 sn-p。
    • 谢谢。还有一个问题。当我按下 ctrl 时,我试图阻止红色框被选中。我尝试添加 o.selectable = false 和 o.evented=false。但是,它不起作用。你知道我该怎么做吗?
    • @user136266 您所能做的就是使用canvas.discardActiveObject(); 丢弃该活动对象@检查更新的答案。
    • 矩形仍在被选中。您尝试通过单击矩形进行拖动。你会看到它在移动,虽然有点移动
    • @user136266 设置canvas._currentTransform = null 这样就不会再移动了,检查更新答案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-13
    • 1970-01-01
    • 2013-11-25
    • 1970-01-01
    • 2021-08-09
    • 2013-12-18
    • 2013-06-24
    相关资源
    最近更新 更多