感谢作者写出这么好的文章:https://www.cnblogs.com/wff9342/p/10563068.html

<template><div ref="tagcanvasbox" class="tagcanvasbox"><canvas ref="tagcanvas" width='844' height='475'@mousedown ="mouseDown($event)" @mouseup ="mouseUp($event)"@mousemove ="mouseMove($event)"@contextmenu.prevent ="contextMenu($event)"@mouseout ="mouseOut($event)"></canvas></div>
</template>
<script>
export default {name:'tagcanvas',//props:{imgCanvas:{type:Object,default:{imgcanvasW:844,imgcanvasH:475}},},data(){return{ctx:'',tagObj:{newrecsObj:{},recs:[{h: 36,w: 58,x: 404,y: 161},{h: 67,w: 58,x: 239,y: 49}],x:0,y:0,url:'',radious:5,recSize:5,drag:false,resize:false,draw:false,showLitRecs:true,index:-1,side:0,startX:0,startY:0,isRightClick:false}}},mounted(){this.ctx = this.$refs.tagcanvas.getContext('2d');},methods:{mouseOut(e){let dom = this.$refs.tagcanvas;let x =e.clientX;let y =e.clientY;let domx1 = dom.offsetLeft;let domy1 = dom.offsetTop;let domx2 = dom.offsetLeft + dom.offsetWidth;let domy2 = dom.offsetTop + dom.offsetHeight;if( x < domx1 || x > domx2 || y < domy1 || y > domy2){this.clearCanvas(this.$refs.tagcanvas, this.ctx);this.drawOldRecs(this.tagObj.recs, this.ctx);}},mouseDown(e){// let ctx = this.$refs.tagcanvas.getContext('2d');console.log('down',e);this.tagObj.x = e.offsetX;this.tagObj.y = e.offsetY;this.tagObj.index = this.getEventIndex(this.tagObj.recs, this.tagObj.x, this.tagObj.y, this.tagObj.radious); //得到落点所在框的序数console.log(this.tagObj.index,this.tagObj.recs);if (e.button == 2) {if (this.tagObj.index >= 0) {this.tagObj.isRightClick = true;}return;}if (this.tagObj.index >= 0) { //移动或者放缩this.tagObj.startX = this.tagObj.recs[this.tagObj.index].x;this.tagObj.startY = this.tagObj.recs[this.tagObj.index].y;this.tagObj.side = this.getEventArea(this.tagObj.recs[this.tagObj.index], this.tagObj.x, this.tagObj.y, this.tagObj.radious); //得到落点在一个框中的区域// console.log(this.tagObj.side,this.tagObj.index);if (this.tagObj.side < 9) { //准备缩放this.tagObj.resize = true;} else { //准备拖动this.tagObj.drag = true;}this.drawLitRecs(this.ctx, this.prepareLitRecs(this.tagObj.recs[this.tagObj.index]), this.tagObj.recSize); //画移动小框} else {this.tagObj.draw = true;}this.changeResizeCursor(this.$refs.tagcanvas, this.tagObj.side); //判断小框类型},mouseUp(e){if (this.tagObj.isRightClick == true) {this.tagObj.index = this.getEventIndex(this.tagObj.recs, this.tagObj.x, this.tagObj.y, this.tagObj.radious);this.tagObj.recs.splice(this.tagObj.index, 1);this.clearCanvas(this.$refs.tagcanvas, this.ctx);for (var i = 0; i < this.tagObj.recs.length; i++) {this.ctx.strokeRect(this.tagObj.recs[i].x, this.tagObj.recs[i].y, this.tagObj.recs[i].w, this.tagObj.recs[i].h);}this.tagObj.isRightClick = false;return;}this.tagObj.resize = false;this.tagObj.drag = false;if (this.tagObj.draw) {this.addToRecs(this.$refs.tagcanvas, e); //添加框this.tagObj.draw = false;}},mouseMove(e){var index;var side;this.clearCanvas(this.$refs.tagcanvas, this.ctx);this.drawRuler(this.$refs.tagcanvas, this.ctx, e);this.drawOldRecs(this.tagObj.recs, this.ctx); //必须放在moveRec之下index = this.getEventIndex(this.tagObj.recs, e.offsetX, e.offsetY, this.tagObj.radious);if (index > -1) {side = this.getEventArea(this.tagObj.recs[index], e.offsetX, e.offsetY, this.tagObj.radious); //得到落点在一个框中的区域// console.log(index,JSON.stringify(this.tagObj.recs),this.tagObj.radious,side);} else {side = 0;}this.changeResizeCursor(this.$refs.tagcanvas, side);// console.log(this.tagObj.showLitRecs && index >= 0 && side > 0);if (this.tagObj.showLitRecs && index >= 0 && side > 0) {this.drawLitRecs(this.ctx, this.prepareLitRecs(this.tagObj.recs[index]), this.tagObj.recSize);}if (this.tagObj.draw) {this.drawRec(this.$refs.tagcanvas, this.ctx, e);}if (this.tagObj.drag) {// console.log('139',this.$refs.tagcanvas, this.tagObj.recs[this.tagObj.index], e);this.moveRec(this.$refs.tagcanvas, this.tagObj.recs[this.tagObj.index], e);}if (this.tagObj.resize) {this.reSizeRec(this.tagObj.side, this.tagObj.recs[this.tagObj.index], e.offsetX, e.offsetY, this.tagObj.recSize);}},contextMenu(e){return false;},getEventIndex(recs, x, y, radious) { //得到落点所在框的序数,-1代表没有落在任何框内if (recs.length == 0) {return -1;}for (var i = 0; i < recs.length; i++) {if (x > (recs[i].x - radious) && x < (recs[i].x + recs[i].w + radious) &&y > (recs[i].y - radious) && y < (recs[i].y + recs[i].h + radious)) {return i;}if (i == recs.length - 1) {return -1;}}},clearCanvas(canvas, ctx) {ctx.clearRect(0, 0, canvas.width, canvas.height);},getEventArea(data, x, y, radious) { //得到落点在一个框中的区域if (x > (data.x - radious) && x < (data.x + radious)) {if (y > (data.y - radious) && y < (data.y + radious)) {return 1;} else if (y > (data.y + radious) && y < (data.y + data.h - radious)) {return 2;} else if(y > (data.y + data.h - radious)&& y < (data.y + data.h + radious)){return 3;}} else if (x > (data.x + data.w - radious) && x < (data.x + data.w + radious)) {if (y > (data.y - radious) && y < (data.y + radious)) {return 4;} else if (y > (data.y + radious) && y < (data.y + data.h - radious)) {return 5;} else if (y > (data.y + data.h - radious) && y < (data.y + data.h + radious)){return 6;}} else {if (y > (data.y - radious) && y < (data.y + radious) && x > (data.x + radious) && x < (data.x + data.w- radious)) {return 7;} else if (y > (data.y + data.h - radious) && y < (data.y + data.h + radious) && x > (data.x + radious) && x < (data.x + data.w - radious)) {return 8;} else {return 9;}}},drawLitRecs(ctx, data, size) { //画移动时的小框,data为矩形框9个点的坐标for (var i = 0; i < data.length; i++) {ctx.strokeRect(data[i][0] - size / 2, data[i][1] - size / 2, size, size);}},changeResizeCursor(canvas, index) {switch (index) {case 0:canvas.style.cursor = "crosshair";break;case 1:canvas.style.cursor = "se-resize";break;case 2:canvas.style.cursor = "e-resize";break;case 3:canvas.style.cursor = "ne-resize";break;case 4:canvas.style.cursor = "sw-resize";break;case 5:canvas.style.cursor = "w-resize";break;case 6:canvas.style.cursor = "nw-resize";break;case 7:canvas.style.cursor = "s-resize";break;case 8:canvas.style.cursor = "n-resize";break;case 9:canvas.style.cursor = "move";break;default:canvas.style.cursor = "default";}},addToRecs(canvas, e) {var rec = {};rec.x = (this.tagObj.x > e.offsetX) ? e.offsetX : this.tagObj.x;rec.y = (this.tagObj.y > e.offsetY) ? e.offsetY : this.tagObj.y;rec.w = Math.abs(e.offsetX - this.tagObj.x);rec.h = Math.abs(e.offsetY - this.tagObj.y);//rec.type = currentSelectedType;this.tagObj.newrecsObj = rec;this.tagObj.recs.push(this.tagObj.newrecsObj);this.tagObj.url = this.$refs.tagcanvas.toDataURL();},drawRuler(canvas, ctx, e) { //鼠标画图辅助线ctx.beginPath();ctx.strokeStyle = 'red';ctx.lineWidth = 1;//ctx.strokeStyle="#FF0000";ctx.moveTo(e.offsetX, 0);ctx.lineTo(e.offsetX, canvas.height);ctx.moveTo(0, e.offsetY);ctx.lineTo(canvas.width, e.offsetY);ctx.stroke();},prepareLitRecs(data) { //把一个框的左上角坐标和宽高输入,得到8个坐标,左3,右3中2var li = [];li[0] = [data.x, data.y];li[1] = [data.x, data.y + data.h / 2];li[2] = [data.x, data.y + data.h];li[3] = [data.x + data.w, data.y];li[4] = [data.x + data.w, data.y + data.h / 2];li[5] = [data.x + data.w, data.y + data.h];li[6] = [data.x + data.w / 2, data.y];li[7] = [data.x + data.w / 2, data.y + data.h];return li;},drawOldRecs(recs, ctx) { //鼠标画图后// let tagctx = this.$refs.tagcanvas.getContext('2d');//btn_clear();if (recs.length == 0) {return 0;}// console.log(recs);for (var i = 0; i < recs.length; i++) {//for (var j = 0; j < tags.length; j++) {//if (recs[i].type == tags[j].en_name) {//var id = document.getElementById('type_' + tags[j].en_name);//id.style.background = tags[j].color;this.ctx.beginPath();ctx.lineWidth = 3;//ctx.strokeStyle =tags[j].color;ctx.strokeStyle = "rgb(121, 245, 57)";ctx.strokeRect(recs[i].x, recs[i].y, recs[i].w, recs[i].h);//break;//}//}}},drawRec(canvas, ctx, e) { //画图ctx.strokeRect(this.tagObj.x, this.tagObj.y, e.offsetX - this.tagObj.x, e.offsetY - this.tagObj.y);},moveRec(canvas, rec, e) {// console.log(canvas, rec,JSON.stringify(rec), e);rec.x = this.tagObj.startX + e.offsetX - this.tagObj.x;rec.y = this.tagObj.startY + e.offsetY - this.tagObj.y;},reSizeRec(index, rec, ex, ey, recSize) {var temX = rec.x;var temY = rec.y;if (index < 4 && temX + rec.w - ex > recSize) {rec.x = ex;}if ((index == 1 || index == 4 || index == 7) && temY + rec.h - ey > recSize) {rec.y = ey;}if (index < 4) {if (temX + rec.w - ex > recSize) {rec.w = temX + rec.w - ex;}} else if (index < 7) {if (ex - temX > recSize) {rec.w = ex - temX;}}if (index == 1 || index == 4 || index == 7) {if (temY + rec.h - ey > recSize) {rec.h = temY + rec.h - ey;}} else if (index == 3 || index == 6 || index == 8) {if (ey - temY > recSize) {rec.h = ey - temY;}}}}
}
</script>
<style scoped>
.tagcanvasbox{width: 100%;height: 100%;position: relative;}
canvas{position: absolute;top: 0;left: 0;
}
</style>

文章是我根据作者的源码改写成vue的格式,仅供参考

vue canvas画框调大小相关推荐

  1. vue+canvas实现手写签字画板

    vue+canvas实现手写签字画板 效果 预览 体验地址 用途 涂鸦画板 签名板 实现 使用canvas,通过监听鼠标动作来进行绘图. 关键代码如下: drawing(event){if(!this ...

  2. VUE+Canvas 实现桌面弹球消砖块小游戏

    大家都玩过弹球消砖块游戏,左右键控制最底端的一个小木板平移,接住掉落的小球,将球弹起后消除画面上方的一堆砖块. 那么用VUE+Canvas如何来实现呢?实现思路很简单,首先来拆分一下要画在画布上的内容 ...

  3. 移动端html5手写板,Vue+canvas实现移动端手写板步骤详解

    这次给大家带来Vue+canvas实现移动端手写板步骤详解,Vue+canvas实现移动端手写板的注意事项有哪些,下面就是实战案例,一起来看一下. 清除 保存 Canvas画板 var draw; v ...

  4. html+js+canvas实现画板涂画功能和vue+canvas实现画板涂画功能

    1,html+js+canvas实现画板涂画功能 效果如下: <!DOCTYPE HTML> <html> <head><meta charset=" ...

  5. VUE+Canvas实现简单的五子棋游戏

    之前的canvas小游戏系列欢迎大家戳: <VUE实现一个Flappy Bird~~~> <VUE+Canvas实现上吊火柴人猜单词游戏> <VUE+Canvas 实现桌 ...

  6. CSDN去掉图片水印和调大小

    目录 1.去水印 2.居中,调大小 1.去水印 进入文章编辑模式,比如我上传了这样一张图,强制带了水印 图片上传后,可以看到图片下面都有一段代码 删掉红框里的内容就可以去掉水印了,最后的 " ...

  7. VUE+Canvas实现财神爷接元宝小游戏

    之前的canvas小游戏系列欢迎大家戳: <VUE实现一个Flappy Bird~~~> <VUE+Canvas实现上吊火柴人猜单词游戏> <VUE+Canvas 实现桌 ...

  8. VUE前后分离调起微信支付

    @ VUE调起微信支付 VUE前后分离调起微信支付 支付很简单,但每次都是在网上直接扒下来使用,老年人记忆,于是就自己记录一下,方便以后快速的粘贴复制; 第一步 :VUE 需要安装 微信支付模块 // ...

  9. vue pdf组件调节大小_创建可移动和可调整大小的Vue组件

    vue pdf组件调节大小 Vue可移动 (Vue Moveable) A Vue Component that create Moveable, Draggable, Resizable, Scal ...

最新文章

  1. mysql主主复制、主从复制、半同步的实现
  2. 【转载】linux2.6内核initrd机制解析
  3. sql2005还原出现“受限制用户”解决方法
  4. 台湾国立大学郭彦甫Matlab教程笔记(14)polynomial differentiation多项式微分
  5. 作为一个程序员,进步完全取决于自己
  6. 装配组件_基于Haption力反馈系统的交互式装配仿真
  7. 企业实战_04_MyCat常用配置文件详解
  8. 相关系数法程序设计 opencv C++ CSU
  9. householder变换解线性方程组matlab实现
  10. 杭电 2838 牛叉的树状数组
  11. 毕马威《2021年中国证券业调查报告》:金融科技和数字化将成为发展核心
  12. 27、fd_set与FD_SETSIZE详解
  13. Advances in Cryptology EUROCRYPT 2008
  14. java 输出流转换成输入流_在JAVA中如何将输出流转为输入流的类的实现
  15. 台达cp2000的面板怎么调节_台达CP2000系列变频器参数设置
  16. Adobe源码泄漏?3行代码搞定,Flash动画无缝导入Android iOS cocos2dx(二)
  17. 【网页设计】基于HTML+CSS+JavaScript学生网上报到系统响应式网站
  18. qcom android GPS 启动流程
  19. 用wifi模块开发项目
  20. Redis之哨兵模式

热门文章

  1. 网易云信im即时通讯,php网易云信im即时通讯,tp,demo,即时通讯
  2. 读《从一到无穷大》之后感
  3. 遍身罗绮者 不是养蚕人
  4. php获取客户端真实ip
  5. 区块链溯源是什么?一文带您读懂!
  6. 群晖+picgo搭建私有图床
  7. 米的换算单位和公式_Excel 怎样进行单位换算,excle怎么把米换算公里
  8. 微信小程序,图像识别源码
  9. 我的java开发总结
  10. 02-PDI(Kettle)导入与导出