起因:根據項目需求本人寫了一個繪制矩形的組件。
功能:在圖片中繪制矩形,根據圖片大小進行自適應展示,獲取圖片矩形坐標。
思路:首先定義一個固定大小的DIV,DIV標簽中有監測鼠標變化的四個事件mousedown,mousemove,mouseup,mouseleave。
第二在DIV標簽內有img,canvas兩個標簽,一個負責圖片展示,一個負責繪制矩形。
其中img與DIV標簽的大小相當,canvas是根據DIV標簽position定位的以保證鼠標事件在圖片上繪制矩形不會有偏差。
以下就是組件的全部代碼和實現效果展示
<template>
<div id="customPositionDiv">
<div style="width: 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="width: 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
customRwidth: '', //原圖與展示圖片的寬度比
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; width:' + 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>


