Reputation: 1
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
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