起因:根据项目需求本人写了一个绘制矩形的组件。
功能:在图片中绘制矩形,根据图片大小进行自适应展示,获取图片矩形坐标。
思路:首先定义一个固定大小的DIV,DIV标签中有监测鼠标变化的四个事件mousedown,mousemove,mouseup,mouseleave。
第二在DIV标签内有img,canvas两个标签,一个负责图片展示,一个负责绘制矩形。
其中img与DIV标签的大小相当,canvas是根据DIV标签position定位的以保证鼠标事件在图片上绘制矩形不会有偏差。
以下就是组件的全部代码和实现效果展示
<template> <div id="customPositionDiv"> <div style=" 1460px; height:740px; background-color: #c0c0c0; margin:0 auto ; display:-webkit-box; -webkit-box-align:center; -webkit-box-pack:center; "> <div @mousedown="mousedown" @mousemove="mousemove" @mouseup="mouseup" @Mouseleave="Mouseleave" :style="imgstyle"> <img :src="imgSrc" :style="imgstyle"> <canvas ref="table" :width="canvasWidth" :height="canvasHeight" :style="canvasstyle"></canvas> </div> </div> <div style=" 1450px;z-index: inherit;text-align: right ;margin:10px 0 0 0"> <span slot="footer" class="dialog-footer"> <el-button @click="customClose">取 消</el-button> <el-button type="primary" @click="customQuery">确 定</el-button> </span> </div> </div> </template> <style lang="scss"> </style> <script> import vue from 'vue'; export default { name: 'canvasDraw', props: ['imgSrc'], data() { return { // customPositionShow:false, //自定义位置 // showclose:false, startX: '', //画画开始的X坐标 startY: '', //画画开始的Y坐标 endX: '', //画画结束的X坐标 endY: '', //画画结束的Y坐标 isMouseDownInCanvas: '', //鼠标是否按下 customcxt: '', // cxt customR '', //原图与展示图片的宽度比 customRheight: '', //原图与展示图片的高度比 imgstyle: '', //根据图片大小自适应样式 canvasstyle: '', //根据图片大小canvas自适应样式 居中显示 canvasWidth: '', //根据图片大小自适应canvas宽 canvasHeight: '', //根据图片大小自适应canvas高 DivWidth: 1460, //最大宽度 DivHeight: 740, //最大高度 }; }, watch: { 'imgSrc': function () { this.show(); }, }, mounted() { this.show(); }, methods: { //取消时返回组件调用处所需的数据 customClose() { this.customcxt.clearRect(0, 0, this.DivWidth, this.DivHeight); this.$emit('custom', { 'type': 1, 'data': '' }); }, //确定时返回组件调用处所需的数据 customQuery() { this.customcxt.clearRect(0, 0, this.DivWidth, this.DivHeight); //根据绘制进行图片裁剪 //获取矩形框Left,Width' let cLeft = 0; let cWidth = 0; if (this.startX > this.endX) { cLeft = this.endX; cWidth = this.startX - this.endX; } else { cLeft = this.startX; cWidth = this.endX - this.startX; } //获取矩形框Top,Height let cTop = 0; let cHeight = 0; if (this.startY > this.endY) { cTop = this.endY; cHeight = this.startY - this.endY; } else { cTop = this.startY; cHeight = this.endY - this.startY; } var oMark = []; oMark['offsetLeft'] = parseInt(cLeft / this.customRwidth); oMark['offsetTop'] = parseInt(cTop / this.customRheight); oMark['offsetWidth'] = parseInt(cWidth / this.customRwidth); oMark['offsetHeight'] = parseInt(cHeight / this.customRheight); this.$emit('custom', { 'type': 2, 'data': oMark }); }, // dialog展示自定义矩形框画板, // 计算img与canvas标签自适应图片的大小 show() { vue.nextTick(_ => { let customCanvas = this.$refs.table;// canvas显示层 this.customcxt = customCanvas.getContext("2d"); let img = new Image(); img.src = this.imgSrc; let that = this; img.onload = function () { let canvasleft = 0; let canvastop = 0; let WrH = img.width / img.height; //图片宽高比 let RWrH = that.DivWidth / that.DivHeight; //放置图片DIV的宽高比 let aa = 0; // 根据宽高比大小判断确定自适应的宽和高 if (RWrH > WrH) { aa = that.DivHeight / img.height; that.canvasHeight = that.DivHeight; that.canvasWidth = img.width * aa; canvasleft = (that.DivWidth - that.canvasWidth) / 2 } else { aa = that.DivWidth / img.width; that.canvasHeight = img.height * aa; that.canvasWidth = that.DivWidth; canvastop = (that.DivHeight - that.canvasHeight) / 2 } that.imgstyle = ' position: relative; ' + that.canvasWidth + ' px; height:' + that.canvasHeight + 'px'; //img浮动定位居中显示 that.customRwidth = that.canvasWidth / img.width; //原图与展示图片的宽高比 that.customRheight = that.canvasHeight / img.height; that.canvasstyle = 'position: absolute;left: ' + canvasleft + '; top: ' + canvastop + ';' //canvas浮动定位 }; }) }, //鼠标按下时执行 mousedown(e) { this.isMouseDownInCanvas = true; // 鼠标按下时开始位置与结束位置相同 // 防止鼠标在画完矩形后 点击图画形成第二个图形 this.endX = e.offsetX; this.endY = e.offsetY; this.startX = e.offsetX; this.startY = e.offsetY; this.mousemove(e) }, //鼠标移动式时执行 mousemove(e) { if (this.isMouseDownInCanvas) { // 当鼠标有按下操作时执行 this.endX = e.offsetX; this.endY = e.offsetY; let wwidth = this.endX - this.startX; let wheigth = this.endY - this.startY; // 清除指定区域的所有像素 this.customcxt.clearRect(0, 0, this.DivWidth, this.DivHeight); this.customcxt.strokeStyle = " #00ff00"; //矩形框颜色 this.customcxt.lineWidth = "2"; //矩形框宽度 this.customcxt.strokeRect(this.startX, this.startY, wwidth, wheigth); //绘制矩形 } }, //鼠标松开时执行 mouseup(e) { this.isMouseDownInCanvas = false; }, Mouseleave(e) { this.isMouseDownInCanvas = false }, }, } </script>