Fabric.js中平移画布后对象无法选中的问题解决方案
问题原因与解决方案
这个问题我之前也碰到过,根源在于你手动修改viewportTransform数组的方式没有让Fabric.js内部的坐标映射完全同步,导致点击检测时的坐标转换出错了。
问题分析
当你按住Ctrl拖动画布时,直接修改viewportTransform[4]和[5](这两个对应画布的X、Y轴偏移量),虽然能直观看到画布平移,但Fabric.js内部的一些关键状态没有被正确更新。当你后续尝试点击选中对象时,Fabric.js计算鼠标点击位置与对象实际位置的对应关系会出现偏差,所以才会出现点不到对象、偶尔点周边才能选中的异常情况。
修正后的代码
我们改用Fabric.js官方提供的relativePan方法来实现画布平移,它会自动同步所有内部状态,保证坐标转换的一致性:
JavaScript代码
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; // 改用relativePan方法实现平移 var deltaX = e.clientX - this.lastPosX; var deltaY = e.clientY - this.lastPosY; canvas.relativePan(new fabric.Point(deltaX, deltaY)); 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);
HTML代码
<script src="//cdnjs.cloudflare.com/ajax/libs/fabric.js/2.2.1/fabric.min.js"></script> <canvas id="c" width="1000" height="1000"></canvas>
说明
relativePan是Fabric.js专门用于画布平移的API,它不仅会更新viewportTransform,还会同步处理内部的坐标转换逻辑,确保鼠标点击、对象选择等交互操作的坐标计算始终准确。替换后,你再按住Ctrl大幅平移画布,之后选中对象就完全正常了。
内容的提问来源于stack exchange,提问作者user10024395
相关产品推荐
相关产品推荐

