一、问题场景
我在使用Fabric.js创建了canvas容器后,在其中添加Image对象,并在原型链中修改其图形对象的控制图标和事件,发现control事件无法触发,转而进入到selection相关事件中
代码片段如下:
// // 添加右下角图标 缩放
fabric.Object.prototype.controls.br = new fabric.Control({
x: 0.5,
y: 0.5,
cursorStyle: 'default',
mouseUpHandler: getXY,
actionName: 'zoom',
// @ts-ignore
actionHandler: fabric.controlsUtils.scalingEqually,
render: renderIcon(barZoom),
// @ts-ignore
cornerSize: 24
})
//....
//创建图片对象
const image = new Image()
image.setAttribute('crossOrigin', 'anonymous')
image.src = item.imgSrc
image.onload = () => {
//设置缩放倍数
const imgZoom = 100 / image.width
const rect = new fabric.Image(image, {
left: 0,
top: this.pageList[0].height! / 2,
borderColor: '#19BCAA',
borderScaleFactor: 2,
// 控制角大小
cornerSize: 30,
hasBorders: true,
padding: -2,
// 指示对象控件(边框/控件)是否在叠加图像上方呈现
// @ts-ignore
controlsAboveOverlay: true,
borderOpacityWhenMoving: 1,
// 转角在画布Itext中是否透明
transparentCorners: false,
//允许控制事件
hasControls: true,
centeredScaling: true,
allowTouchScrolling: true,
lockScalingFlip: true, // 禁止翻转
lockMovementX: true, //禁止横向拖动
scaleX: imgZoom,
scaleY: imgZoom
})
// 设置周边control不展示的点位。 ml:左,mb:下,mr:右,mt:上,mtr:旋转,tl:左上角,bl:左下角,tr:右上角,br:右下角
rect.setControlsVisibility({
bl: false,
ml: false,
mb: false,
mr: false,
mt: false,
// br: false,
// tl: false,
mtr: false,
tr: false
})
//canvas对象在前文代码已经完成创建
Canvas.add(rect)
Canvas.centerObject(rect)
//此时设置object为活跃状态,被选中,从而允许control
Canvas.setActiveObject(rect)
Canvas.selectable = true
Canvas.renderAll()
// 选择
rect.on('mousedown', e => {
e.e.preventDefault()
e.e.stopPropagation()
//....
})
// 取消选择
this.canvasList[0].qfzCanvas.on('selection:cleared', () => {
})
二、问题解决
最后到处搜类似问题,找到一个帖子给了我启发:
在vue3项目使用fabric.js 图片缩放失效?-腾讯云开发者社区-腾讯云
发现可能与fabric.js处理vue响应式数据(转化为Proxy对象)存在漏洞有关。
🌟解决方法:
- 和上面帖子说的一样,在往canvas对象里面add图形对象的时候,用markRaw将图形对象标记为原始对象,将避免其变为proxy
Canvas.add(markRaw(rect))
- 直接将Canvas对象定义在全局或者setup中,而不是定义在vue的data属性里面。因为data会对数据自动绑定监听捏~而setup不会