使用fabric 根据坐标绘图

需求:根据接口返回的坐标数据,根据坐标数据在影像上绘图,初始页面,不满足条件的内容,都要被绘制红框,点击表格对应的数据后,绘制蓝框
初始页面多个坐标绘制
点击数据获取坐标,绘制篮框,红框同时存在

//完整cavans
<template>
  <div class="can">
    <canvas
      id="canvas3"
      style="
        border: 1px solid #dcdfe6;
        box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.12),
          0 0 6px 0 rgba(0, 0, 0, 0.04);
          width: 500px;
          height: 500px;
      "
    >
      <p>您的系统不支持此程序,请更换浏览器!</p>
    </canvas>
  </div>
</template>

<script>
import { fabric as Fabric } from 'fabric'
import $ from 'jquery'

export default {
  props: {
    baseUrl: { //父组件传过来的影像url
      type: String
    },
    redBorder: {  //父组件传过来的数组
      type: Array
    },
    positionType:{
      type:String,
      default:'initPosition'
    }

  },
  data () {
    return {
      card: {},
      panning: false,
      // 待旋转的图片
      selectedObj: {},
      index:null,
      localPosition: []
    }
  },
  created () {
    window.addEventListener('resize', this.resizeWindowEvent)

  },
  mounted() {
    // this.initCanvas()
  },
  destoryed () {
    window.removeEventListener('resize', this.resizeWindowEvent)
  },
  methods: {
    resizeWindowEvent(e) {
      if (!!this.card) {
        this.card.setWidth($('.image').innerWidth())   //外层容器
        this.card.setHeight($('.can').height() - 15)
      }
    },
    // drawArr  args是传过来的坐标数据
    //坐标数组 [[251, 309, 310, 252, 330, 328, 360, 362],[812, 952, 953, 814, 333, 324, 349, 358]]  坐标是根据影像坐顶点为原点
    drawArrDefault(args) {
      let tempArr = []
      for(let i in args) {
        var react = react + i
          react = new Fabric.Rect({
          top: args[i][4]* 0.5,
          left: args[i][0] * 0.5,
          width: args[i][1] - args[i][0],
          height: args[i][7] - args[i][4],
          fill: 'transparent',
          scaleX: 0.5,
          scaleY: 0.5,
          stroke: 'red',
          strokeWidth: 2,
          angle: 0,
          // perPixelTargetFind: false,
        })
        tempArr.push(react)
      }
      for(let item of tempArr) {
        this.card.add(item)
      }
    },
	//初始化
    initCanvas (data) {
      this.card = new Fabric.Canvas('canvas3', {
        preserveObjectStacking: true,
        centeredScaling: true // 全局所有元素都生效  鼠标中心点实现缩放
      })
      const canvas = this.card
      
      canvas.setWidth($('.image').innerWidth())
      canvas.setHeight($('.can').height() - 15)
      Fabric.Image.fromURL(this.baseUrl, (img) => {
        img.set({
          hasControls: false, // 是否开启图层的控件
          // borderColor: 'orange', // 图层控件边框的颜色
          scaleX: 0.5,
          scaleY: 0.5,
          //防止鼠标拖动影像,绘图发生位移
          lockMovementX: true, // 禁止水平移动
          lockMovementY: true, // 禁止垂直移动
          hasRotatingPoint: false, // 无旋转点
       
        })
        // 添加对象后, 如下图
        canvas.add(img)
        // 在画布图片后,插入新的所有默认标记
        this.drawArrDefault(data)
        canvas.renderAll()
      })
      
      $('#canvas3').parent().siblings().css('display', 'none')
      const relationship = { x: 0, y: 0, zoom: 1 }
      // 鼠标按下事件
      canvas.on('mouse:down', function (e) {
        this.panning = true
        canvas.selection = false
      })
      // 鼠标抬起事件
      canvas.on('mouse:up', function (e) {
        this.panning = false
        canvas.selection = true
      })
      // 移动画布事件
      canvas.on('mouse:move', function (e) {
        if (this.panning && e && e.e) {
          const delta = new Fabric.Point(e.e.movementX, e.e.movementY)
          canvas.relativePan(delta)
          // 累计每一次移动时候的偏移量
          relationship.x += e.e.movementX / relationship.zoom
          relationship.y += e.e.movementY / relationship.zoom
        }
      })
      // 鼠标滚动画布放大缩小
      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

        // 以左上角为原点
        // this.canvas.setZoom(zoom)

        // 以鼠标所在位置为原点缩放
        canvas.zoomToPoint(
          { // 关键点
            x: opt.e.offsetX,
            y: opt.e.offsetY
          },
          zoom
        )
        opt.e.preventDefault()
        opt.e.stopPropagation()
      })

    },
    
    drawRedBorder (newValue) {
      this.card._objects.splice(1)
      let arr = []
      if (newValue !== null) {
        this.drawArrDefault(this.localPosition)
        const rect = new Fabric.Rect({
          top: newValue[4]* 0.5,
          left: newValue[0] * 0.5,
          width: newValue[1] - newValue[0],
          height: newValue[7] - newValue[4],
          fill: 'transparent', // 背景
          scaleX: 0.5,
          scaleY: 0.5,
          stroke: 'blue',
          strokeWidth: 2,
          angle: 0,
          perPixelTargetFind: false,
          //防止鼠标拖动影像,绘图发生位移
          lockMovementX: true, // 禁止水平移动
          lockMovementY: true, // 禁止垂直移动
          hasRotatingPoint: false, // 无旋转点
          hasControls:false,
          selectable: false // 不可选中
        })
        this.card.add(rect) // 选中
      }
      this.card.renderAll()
    },
    // currAngle影像旋转
    currAngle () {
      this.selectedObj = this.card._objects[0]
      // 顺时针90°旋转
      const currAngle = this.selectedObj.angle // 当前图层的角度
      const angle = currAngle === 360 ? 90 : currAngle + 90
      this.selectedObj.rotate(angle)
      // 所有图层的操作之后,都需要调用这个方法
      this.card.renderAll()
    }
  },
  watch: {
    baseUrl (newValue, oldValue) {
      // console.log(newValue, oldValue)
      if(this.positionType == 'clickTable'){
        if (newValue !== oldValue) {
          this.initCanvas()
        }
      }
    },
    redBorder: {
      handler (newValue, oldValue) {
        this.localPosition = sessionStorage.getItem('position') ? JSON.parse(sessionStorage.getItem('position')) : newValue 
        if(this.positionType == 'initPosition') { // 获取所有初始位置
         this.initCanvas(this.localPosition)
        } else {
          if(this.positionType == 'clickTable') { // 点击费用清单中 小项表格
            this.drawRedBorder(newValue)
          }
        }
      },
      deep: true
    },
  }
}
</script>

<style>
.can {
  width: 100vw;
  height: -moz-calc(90vh - 30px);
  height: -webkit-calc(90vh - 30px);
  height: calc(90vh - 30px);
}
</style>

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值