canvas 实现拖拽选框、放大缩小等功能

在这里插入图片描述

<template>
  <div class="edit-anchor-zone">
    <div class="edit-toolbar">
      <span class="toolbar-icon-wrap" :class="{'icon_active': isAnchorActive}">
        <el-tooltip class="item" effect="light" content="框选锚点" placement="top">
          <el-button><i class="iconfont icon-OCR-circleselect toolbar-icon" @click="drawAnchor"></i></el-button>
        </el-tooltip>
      </span>
      <span class="toolbar-icon-wrap" :class="{'icon_active': isTableActive}" v-if="!setAnchorFlag">
        <el-tooltip class="item" effect="light" content="框选列表" placement="top">
          <el-button><i class="iconfont icon-OCR-table toolbar-icon" @click="drawTable"></i></el-button>
        </el-tooltip>
      </span>
      <span class="toolbar-icon-wrap" :class="{'icon_active': isdrawActive}">
        <el-tooltip class="item" effect="light" content="拖拽画布" placement="top">
          <el-button><i class="iconfont icon-OCR-drafting toolbar-icon" @click="dragDraw"></i></el-button>
        </el-tooltip>
      </span>
      <span class="toolbar-icon-wrap" :class="{'icon_active': isZoomInActive}">
        <el-tooltip class="item" effect="light" content="放大" placement="top">
          <el-button><i class="iconfont icon-Zoomin toolbar-icon" @click="zoomIn"></i></el-button>
        </el-tooltip>
      </span>
      <span class="toolbar-icon-wrap" :class="{'icon_active': isZoomOutActive}">
        <el-tooltip class="item" effect="light" content="缩小" placement="top">
          <el-button><i class="iconfont icon-Zoomout toolbar-icon" @click="zoomOut"></i></el-button>
        </el-tooltip>
      </span>
      <span class="toolbar-icon-wrap" :class="{'icon_active': isAdaptDrawActive}">
        <el-tooltip class="item" effect="light" content="适应画布" placement="top">
          <el-button><i class="iconfont icon-OCR-autoadaptation toolbar-icon" @click="adaptDraw"></i></el-button>
        </el-tooltip>
      </span>
      <span class="toolbar-icon-wrap" :class="{'icon_active': isSetOriginActive}">
        <el-tooltip class="item" effect="light" content="原图" placement="top">
          <el-button><i class="iconfont icon-OCR-test toolbar-icon" @click="setOriginSize"></i></el-button>
        </el-tooltip>
      </span>
    </div>
    <div class="edit-body">
      <div v-if="isLoading" class="init-page-tip">
        <i class="el-icon-loading"></i>
        <p>模板加载中,请稍后</p>
      </div>
      <div class="canvas-wrapper" ref='canvasWrapper'>
        <canvas width="1000" height="700" ref="baseCanvas" class='canvas'></canvas>
      </div>
    </div>
    <el-dialog title="请选择分割列数" :visible.sync="tableVisible" width="30%">
      <div class="select-wrapper">
        <div class="select">列数: <el-input-number v-model="tableCol" :min="2" :max="10" size='small'></el-input-number>
        </div>
      </div>
    </el-dialog>
    <div style="margin-top:20px;">
      <el-button @click="mark">标记</el-button>
      <el-button @click="target">目标</el-button>
    </div>
  </div>
</template>

<script>
export default {
   
  data() {
   
    return {
   
      //toolbar
      isAnchorActive: false,
      isTableActive: false,
      isdrawActive: false,
      isZoomInActive: false,
      isZoomOutActive: false,
      isAdaptDrawActive: false,
      isSetOriginActive: false,

      // loading img
      isLoading: true,

      // refs
      wrapperTarget: null,
      baseTarget: null,
      baseInstance: null,
      selectId: null,
      currentCursor: null,
      centerLineIndex: null,
      centerLineShow: true,

      //base data
      drawWidth: 1000,
      drawHeight: 700,
      initScaleVal: 1,
      currentScaleVal: 1,
      circlsRadius: 2,
      step: 0.05000,
      minSelectArea: 15,
      imgWidth: 0,
      imgHeight: 0,
      imgBase64Code: 0,
      movePoint: {
    x: null, y: null, width: null, height: null },

      // 选框
      setAnchorFlag: true, // true 为 rectList1 , false 为 rectList2
      rectList1: [],
      rectList2: [],
      tableList: [],
      tableVisible: false,
      tableCol: 2,
      color1: '#FF7782',
      color2: '#1E82FD',
      color3: '#4b1efd',
      opacity: 0.3,
      lineWidth: 2,
    }
  },
  watch: {
   
    rectList1: function (newVal, oldVal) {
   
      console.log('rectList1: ', newVal)
    },
    rectList2: function (newVal, oldVal) {
   
      console.log('rectList2: ', newVal)
    },
    tableList: function (newVal, oldVal) {
   
      console.log('tableList: ', newVal)
    },
  },
  methods: {
   
    mark() {
   
      this.setAnchorFlag = true
      this.initDrawRect()
      this.drawAnchor()
    },
    target() {
   
      this.setAnchorFlag = false
      this.initDrawRect()
      this.drawAnchor()
    },
    initDraw(data) {
   
      this.isLoading = false;
      this.imgWidth = 1913;
      this.imgHeight = 1122;
      this.imgBase64Code = 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1576560618051&di=b89a65984c6a0e5c4c8a3de5aa8f0fcd&imgtype=0&src=http%3A%2F%2Fimage.biaobaiju.com%2Fuploads%2F20180803%2F20%2F1533300579-gnUBlQZPbt.jpg'

      this.baseTarget = this.$refs.baseCanvas
      this.wrapperTarget = this.$refs.canvasWrapper

      this.computeInitData();
      this.drawCanvas();
      this.drawAnchor();
    },
    computeInitData() {
   
      let widthRatio = (this.drawWidth / this.imgWidth).toPrecision(5),
        heightRatio = (this.drawHeight / this.imgHeight).toPrecision(5);

      this.baseInstance = this.baseTarget.getContext('2d')

      this.initScaleVal = this.currentScaleVal = widthRatio >= heightRatio ? heightRatio : widthRatio;
      if (this.initScaleVal < 0.10) {
   
        this.initScaleVal = 0.10;
        this.currentScaleVal = 0.10;
      }
      if (this.initScaleVal > 4) {
   
        this.initScaleVal = 4;
        this.currentScaleVal = 4;
      }
      if (this.initScaleVal >= 1) {
   
        this.circlsRadius = 2;
      } else {
   
        this.circlsRadius = 4;
      }
    },
    zoomIn() {
   
      this.setToolBarUnactive();
      this.isZoomInActive = true;
      this.dragDrawX = 0;
      this.dragDrawY = 0;
      if (this.currentScaleVal > 4) {
   
        return;
      };
      this.adapt(this.currentScaleVal, parseFloat(this.currentScaleVal) + this.step)
      this.currentScaleVal = parseFloat(this.currentScaleVal) + this.step;
      this.drawCanvas();
    },
    zoomOut() {
   
      this.setToolBarUnactive();
      this.isZoomOutActive = true;
      this.dragDrawX = 0;
      this.dragDrawY = 0;
      if (this.currentScaleVal <= 0.10) {
   
        return;
      }
      this.adapt(this.currentScaleVal, parseFloat(this.currentScaleVal) - this.step)
      this.currentScaleVal -= this.step;
      this.drawCanvas();
    },
    setOriginSize() {
   
      this.setToolBarUnactive();
      this.isSetOriginActive = true;
      this.adapt(this.currentScaleVal, 1)
      this.currentScaleVal = 1;
      this.drawCanvas();
    },
    adaptDraw() {
   
      this.setToolBarUnactive();
      this.isAdaptDrawActive = true;
      this.adapt(this.currentScaleVal, this.initScaleVal)
      this.currentScaleVal = this.initScaleVal;
      this.dragDrawX = 0;
      this.dragDrawY = 0;
      this.drawCanvas();
    },
    dragDraw() {
   
      this.setToolBarUnactive();
      this.isdrawActive = true;
      this.baseTarget.style.cursor = 'move'
      this.dragCanvas()
    },
    drawAnchor() {
   
      this.setToolBarUnactive();
      this.isAnchorActive 
  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
实现TK Canvas中的超大图片放大缩小功能,可以通过以下步骤实现: 1. 在Canvas中创建一个Image对象,并使用Canvas.create_image()方法将其添加到Canvas中。 2. 创建一个滚动条Scrollbar对象,并使用Canvas.config()方法将其与Canvas关联起来。 3. 创建一个Canvas.scale()方法,用于在Canvas中缩放Image对象的大小。 4. 绑定滚动条和Canvas.scale()方法,以便在滚动条滚动时调整Image对象的大小。 下面是一个示例代码,演示了如何在TK Canvas实现超大图片的放大缩小功能: ```python from tkinter import * class ImageCanvas(Frame): def __init__(self, master=None): Frame.__init__(self, master) # 创建一个Canvas和一个Scrollbar self.canvas = Canvas(self, width=800, height=600) self.scrollbar = Scrollbar(self, orient=VERTICAL, command=self.canvas.yview) self.canvas.config(yscrollcommand=self.scrollbar.set) # 将Canvas和Scrollbar添加到Frame中 self.scrollbar.pack(side=RIGHT, fill=Y) self.canvas.pack(side=LEFT, fill=BOTH, expand=TRUE) # 创建一个Image对象,并将其添加到Canvas中 self.image = PhotoImage(file='large_image.gif') self.canvas.create_image(0, 0, image=self.image, anchor=NW) # 设置Canvas的可滚动区域 self.canvas.config(scrollregion=self.canvas.bbox(ALL)) # 设置Canvas的初始缩放大小 self.scale = 1.0 # 绑定事件,实现鼠标滚轮放大缩小功能 self.canvas.bind('<MouseWheel>', self.onMouseWheel) def onMouseWheel(self, event): # 获取滚轮滚动方向 delta = event.delta # 根据滚轮滚动方向调整缩放大小 if delta > 0: self.scale *= 1.1 elif delta < 0: self.scale /= 1.1 # 调整Canvas中Image对象的大小 x = self.canvas.canvasx(event.x) y = self.canvas.canvasy(event.y) self.canvas.scale('all', x, y, self.scale, self.scale) # 更新Canvas的可滚动区域 self.canvas.config(scrollregion=self.canvas.bbox(ALL)) if __name__ == '__main__': root = Tk() app = ImageCanvas(master=root) app.pack(side=TOP, fill=BOTH, expand=TRUE) root.mainloop() ``` 在这个示例代码中,我们创建了一个ImageCanvas类,继承自Frame类,并在该类中实现了一个包含Canvas和Scrollbar的Frame,以及一个实现放大缩小功能Canvas。用户可以使用鼠标滚轮来放大缩小图片,同时可以使用滚动条来浏览整张图片。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值