本文简介

点赞 + 关注 + 珍藏 = 学会了


如果你的我的项目有画布拖拽、缩放等性能,而且你不心愿背景图追随拖拽或缩放,那肯定要往下读。

本文次要解说如何锁定背景图,锁定背景图其实只需设置1个属性即可。

本文会增加滚轮缩放画布、拖拽画布等性能来测试 “锁定背景图” 的成果。

应该能够清晰看出,不论如何拖拽和缩放画布,背景图都岿然不动。




入手编码

起步

<canvas id="canvasBox" width="600" height="600" style="border: 1px solid #ccc;"></canvas><!-- 引入 Fabric.js --><script src="https://cdn.bootcdn.net/ajax/libs/fabric.js/521/fabric.js"></script><script>  // 初始化画布  const canvas = new fabric.Canvas('canvasBox', {    backgroundVpt: false // 不受视口变换影响(也就是不论拖拽还是缩放画布,背景图都不受影响)  })</script>

backgroundVpt 设为 false 这个是要害。设置了这个,背景图就不会再挪动了,不受视口的变动影响。


增加背景图、矩形和圆形

为了不便演示,我要设置一个背景图和两个图形元素,缩放时只会批改图形元素,背景图是一动不动的。

// 省略局部代码fabric.Image.fromURL('../../images/bg.jpg', img => {  canvas.setBackgroundImage(img)  canvas.renderAll()})// 圆形circle = new fabric.Circle({  name: 'circle',  top: 60,  left: 60,  radius: 30, // 圆的半径 30  fill: 'yellowgreen'})// 矩形rect = new fabric.Rect({  name: 'rect',  top: 30, // 间隔容器顶部 60px  left: 100, // 间隔容器左侧 200px  fill: 'orange', // 填充a 橙色  width: 60, // 宽度 60px  height: 60 // 高度 60px})// 将矩形增加到画布中canvas.add(circle, rect)

设置完背景图再执行 canvas.renderAll() 才会从新渲染,不然画面看上去是没成果的。


增加滚轮缩放

应用滚轮缩放画布,须要监听 mouse:wheel

// 省略局部代码canvas.on('mouse:wheel', 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个事件:

  • 鼠标点下:mouse:down
  • 鼠标挪动:mouse:move
  • 松开鼠标:mouse:up
canvas.on('mouse:down', opt => { // 鼠标按下时触发  let evt = opt.e  canvas.isDragging = true // isDragging 是自定义的  canvas.lastPosX = evt.clientX // lastPosX 是自定义的  canvas.lastPosY = evt.clientY // lastPosY 是自定义的})canvas.on('mouse:move', opt => { // 鼠标挪动时触发  if (canvas.isDragging) {    let evt = opt.e    let vpt = canvas.viewportTransform // 聚焦视图的转换    vpt[4] += evt.clientX - canvas.lastPosX    vpt[5] += evt.clientY - canvas.lastPosY    canvas.requestRenderAll()    canvas.lastPosX = evt.clientX    canvas.lastPosY = evt.clientY  }})canvas.on('mouse:up', opt => { // 鼠标松开时触发  canvas.setViewportTransform(canvas.viewportTransform) // 设置此画布实例的视口转换    canvas.isDragging = false})



总结

本文解说的性能不难的,只有在初始化画布时讲 backgroundVpt 设为 false 即可。

我临时能想到的利用场景是反复花纹的背景,将其固定住。

《backgroundVpt 文档》



源码仓库

⭐背景不受视口变换影响



举荐浏览

《Fabric.js 上标和下标的应用偏方》

《Fabric.js 圆形笔刷》

《Fabric.js 自在绘制矩形(逐个剖析4种操作方向带来的影响)》

《Fabric.js 腾飞》
点赞 + 关注 + 珍藏 = 学会了