这几个月做了标注工具的项目,之前没有对canvas任何使用,网上对fabricjs的框架呼声很高,所以本文大致总结下项目中遇到的问题。技术栈 vue3 + vite
1.如何让canvas自适应
<div id="canvas-box">
<canvas :id="'canvas' + randomNumber" style="display: block; width: 100%; height: 100%"></canvas>
</div>
让cavas-box为flex布局,每次页面加载时,先获得div的宽高,在将canvas的宽高
canvasBox = document.getElementById('canvas-box')
canvasSize.canvasWidth = canvasBox.clientWidth || canvasBox.offsetWidth
canvasSize.canvasHeight = canvasBox.clientHeight || canvasBox.offsetHeight
document.getElementById('canvas' + randomNumber.value).width = canvasSize.canvasWidth
document.getElementById('canvas' + randomNumber.value).height =canvasSize.canvasHeight
这里我给canvas加了随机数 是因为,在生产环境将fabric封装成组件 进行切换时候 页面刷新初次没有问题,但是多次下fabric会出现少绘制一层canvas,我在官网提了issuse,但是一直没时间解决,加了随机数就好,可能是vue认为这两个dom一样吧。而在开发环境一切正常,如果你也是封装组件动态打开的话,可以留意一下这个问题。
2.如何画布放大
//监听鼠标滚轮事件
const canvasMouseWheel = (opt) => {
const delta = opt.e.deltaY // 滚轮,向上滚一下是 -100,向下滚一下是 100
let zoom = canvas.getZoom() // 获取画布当前缩放值
zoom *= 0.999 ** delta
if (zoom > 20) zoom = 20
if (zoom < 0.01) zoom = 0.01
canvas.zoomToPoint(
{
x: opt.e.offsetX,
y: opt.e.offsetY
},
zoom
)
opt.e.preventDefault()
opt.e.stopPropagation()
}
3.如何画布拖拽
//监听鼠标按下事件
const canvasMouseDown = (e) => {
//这里spaceKeyState.value指的是空格键
if (spaceKeyState.value) {
canvas.discardActiveObject().renderAll()
canvas.isDragging = true
canvas.lastPosX = e.e.clientX
canvas.lastPosY = e.e.clientY
canvas.selection = false // 移动时不出现框选样式
}
}
4.如何往画布画矩形 可以利用fabric.rect,这种方法最省事,不用考虑坐标偏移,放大放小问题(之前用path坑的好惨) 很简单
const rect = new fabric.Rect({
top: 距离画布顶,
left: 距离画布左面,
width: 矩形宽
height: 矩形高
fill: 颜色,
})
// 将矩形添加到画布上
canvas.add(rect)
//canvas.getPointer(e) 获取鼠标按下和松开的坐标 知道矩形大小
5.限制矩形在图像内画 这个也很简单 在绘制结束的时候判断图像的四个点是否在图像内,取canva背景图的最大值,让背景图的left和top等于绘制矩形的,让绘制矩形的宽高<let+自身的高
未完待续。。。