Fabric -- 画布的缩放及拖拽

前提准备:vue2环境,下载好fabric( npm i fabric --save )

  • 初始化一个画布。
  // 3. 设置画布参数
  const canvas = this.canvas = new fabric.Canvas('c', {
    width: '800', // 画布宽度
    height: '600', // 画布高度
    backgroundColor: '#eee' // 画布背景色
  })
  • 准备一个圆角矩形和插入一张图片用作参照物
// 圆角矩形
  const rect = new fabric.Rect({
    top: 300, // 距离容器顶部 300px
    left: 300, // 距离容器左侧 300px
    fill: 'orange', // 填充 橙色
    width: 100, // 宽度 100px
    height: 100, // 高度 100px
    originX:'left', // 原点
    originY:'center', //原点
    lockScalingFlip: true, //锁定翻转,及可不可以拉到边的负值
    rx: 20, // x轴的半径
    ry: 20 // y轴的半径
  })

  // 将矩形添加到画布中
  canvas.add(rect) 


// 添加图片 import 或者 require 都行,但 '../../..' 引路径好像不行,在线的没试过
// import logo from '@/assets/logo.png' // 引入图片      
fabric.Image.fromURL(logo, oImg => {
    oImg.scale(0.5) // 缩放
    oImg.set({
      left:50,
      top:50
    })
    canvas.add(oImg) // 将图片加入到画布
    })

一、 缩放

1、 以原点为中心(左上角),缩放画布
      // 监听鼠标滚轮事件
      canvas.on('mouse:wheel', opt => {
        let delta = opt.e.deltaY // 滚轮向上滚一下是 -100,向下滚一下是 100
        let zoom = canvas.getZoom() // 获取画布当前缩放值

        // 控制缩放范围在 0.01~20 的区间内
        zoom *= 0.999 ** delta
        if (zoom > 20) zoom = 20
        if (zoom < 0.01) zoom = 0.01

        // 设置画布缩放比例
        canvas.setZoom(zoom)
      })
2、以鼠标指针为中心,缩放画布
  // 监听鼠标滚轮事件
  canvas.on('mouse:wheel', opt => {
    let delta = opt.e.deltaY // 滚轮向上滚一下是 -100,向下滚一下是 100
    let zoom = canvas.getZoom() // 获取画布当前缩放值

    // 控制缩放范围在 0.01~20 的区间内
    zoom *= 0.999 ** delta
    if (zoom > 20) zoom = 20
    if (zoom < 0.01) zoom = 0.01

    canvas.zoomToPoint(
      {
        x: opt.e.offsetX, // 鼠标x轴坐标
        y: opt.e.offsetY  // 鼠标y轴坐标
      },
      zoom // 最后要缩放的值
    )
  })
  • 区别点: setZoom 和 zoomToPoint
3、 点击按钮控制缩放
// html     
<button @click="setZoom(0.1)">放大</button>
<button @click="setZoom(-0.1)">缩小</button>



// js
// 点击控制缩放
setZoom(val) {
    let zoom = this.canvas.getZoom() + parseFloat(val);
    zoom = Math.max(0.2, zoom); 
    zoom = Math.min(5, zoom); 
    let backPoint = this.canvas.getCenterPoint();
    console.log(backPoint);
    this.canvas.zoomToPoint(backPoint, zoom);
},

二、 拖拽

主要步骤:

  • 监听画布对象的鼠标按下事件,维护一标志符,记录此刻位置
  • 监听画布对象的鼠标移动事件,判断标志符,视图位置发生改变,更新位置
  • 监听画布对象的鼠标按起事件,释放一标志符
1、方法一
      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 => { // 鼠标移动时触发
        console.log('查看e',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.requestRenderAll() // 重新渲染
        }
      })

      canvas.on('mouse:up', opt => { // 鼠标松开时触发
        canvas.setViewportTransform(canvas.viewportTransform) // 设置此画布实例的视口转换  
        canvas.isDragging = false // 关闭移动状态
      })
  • 画布中默认可以通过拖拽来选中元素,在画布拖拽时会产生拖拽框。这里可以禁用画布的选中,可通过点击元素选中
 canvas.selection = false
2、方法二
    canvas.on({
      "mouse:down": (e) => {
        this.panning = true;
        canvas.selection = false;
      },
      "mouse:up": (e) => {
        this.panning = false;
        canvas.selection = true;
      },
      "mouse:move": (e) => {
        if (this.panning && e && e.e) {
          let delta = new fabric.Point(e.e.movementX, e.e.movementY);// e.e.movementX 移动时画布的横向相对偏移量
          canvas.relativePan(delta);
        }
    })

代码及参考

https://juejin.cn/post/7105046849362329608
https://juejin.cn/post/7143062674954256391
https://blog.csdn.net/qq_38860536/article/details/104719854

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值