canvas库fabric.js实现背景图坐标定位、移动、点击坐标执行某方法、鼠标滚动放大缩小(例子)

前言

实现功能:

1,背景图上动态显示坐标点,点击坐标点显示弹出框

2,canvas可移动

3,鼠标滚动时以鼠标原点为中心缩放canvas

4,背景自动铺满,

 

 

 

 

 

 

 

 


 

 

代码

npm install fabric

  

  具体代码(只是例子,写的简单粗暴请见谅)

<template>
  <div class="area" ref="areaDiv" @mousewheel.prevent>
    <div class="manager_detail" style="position: absolute">
      <canvas id="canvas" width="1680" height="837" ref="canvas"></canvas>
    </div>
    <div>
      <a-modal :visible="visible" title="didid" :width="650" class="dialog111"
       footer="" @cancel="cancelDialog">
        dididi
      </a-modal>
    </div>
  </div>
</template>

<script>
import { mapGetters } from 'vuex'
import Echart from '@/components/chart/echart'
import {fabric} from 'fabric'
//注意不能在main.js中用vue.use(fabric),会导致使用fabric的组件中全局this变为kssl也就是this指向了fabric,而不是vuecomponent;哪里用到在哪里import引入
export default {
  name: 'VideoWatch',
  components: {
    Echart,
  },
  data() {
    return {
      prevDaySales: {},
      monthSales: {},
      yearSales: {},
      visible:false,
    }
  },
  computed: {
    ...mapGetters(['userInfo']),
  },
  mounted() {
    let that=this;
    this.$nextTick(()=>{
      this.initCanvas(that);
    })
    

  },
  methods: {
    initCanvas(that) {
      // 1. 实例化canvas 画布
      var canvas = new fabric.Canvas('canvas', {
        perPixelTargetFind: true, //这一句说明选中的时候以图形的实际大小来选择而不是以边框来选择
        hasBorders: false,
      })
      // 2. 设置背景图片做为底图
      fabric.Image.fromURL(require('./../../../assets/geo.jpg'), function (img) { 
        //保证背景图1:1铺满容器  
        canvas.setBackgroundImage(img, canvas.renderAll.bind(canvas), {
          scaleX: canvas.width / img.width,
          scaleY: canvas.height / img.height,
        })
      })
      //获取坐标点位置

      fabric.Image.fromURL(require('./../../../assets/point.png'), function (oImg) {
        oImg.scale(1).set({
          left: 500,
          top: 350,
          name: 'point',
          hasBorders: false, //不显示选中时的边
          hasControls: false, //不显示选中时的9个方块
          lockMovementX: true,
          lockMovementY: true,
        })
        canvas.add(oImg)
      })
      fabric.Image.fromURL(require('./../../../assets/point.png'), function (oImg) {
        oImg.scale(1).set({
          left: 760,
          top: 350,
          name: 'point2',
          hasBorders: false, //不显示选中时的边
          hasControls: false, //不显示选中时的9个方块
          lockMovementX: true,
          lockMovementY: true,
        })
        canvas.add(oImg)
      })
      //鼠标按下事件
      canvas.on('mouse:down', function (e) {      
        this.panning = true
      })
      //鼠标抬起事件
      canvas.on('mouse:up', function (e) {
        this.panning = false
        canvas.selectable = false
        if(e.target&&e.target.name){      
          that.showDialog(e.target.name)
        }
        
        // alert(e.target.name)
      })
      // 移动画布事件
      canvas.on('mouse:move', function (e) {
        if (this.panning && e && e.e) {
          var delta = new fabric.Point(e.e.movementX, e.e.movementY)
          canvas.relativePan(delta)
        }
      })
      // 鼠标滚动画布放大缩小
      canvas.on('mouse:wheel', function (e) {
        var zoom = (e.e.deltaY > 0 ? -0.1 : 0.1) + canvas.getZoom()
        zoom = Math.max(0.8, zoom)
        //最小为原来的1/10
        zoom = Math.min(3, zoom)
        //最大是原来的3倍
        var zoomPoint = new fabric.Point(e.e.pageX, e.e.pageY)
        canvas.zoomToPoint(zoomPoint, zoom)
      })
    },
    showDialog(title){
      this.visible=true;
    },
    cancelDialog(){
      this.visible=false;
    },
    

  },
}
</script>

<style lang="less" scoped>
.area {
  height: 100%;
  width: 100%;
}
.data_area {
  display: flex;
  justify-content: space-between;
  height: 100%;
}

.title-div {
  display: flex;
  align-items: center;
  height: 35px;
  // background-image: url('~@/assets/left_bt.png');
  -moz-background-size: 100% 100%;
  background-size: 100% 100%;
  img {
    width: 41px;
  }
}
</style>

  

  

  

posted @ 2022-07-07 11:26  大笛子  阅读(3320)  评论(1编辑  收藏  举报