|
|
@@ -0,0 +1,420 @@
|
|
|
+<template>
|
|
|
+ <div>
|
|
|
+ <el-form :inline="true">
|
|
|
+ <el-form-item label="考号类型">
|
|
|
+ <el-radio v-model="khType" :label="1" :value="1">手写</el-radio>
|
|
|
+ <el-radio v-model="khType" :label="2" :value="2">条码</el-radio>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="考号位数">
|
|
|
+ <el-input-number size="mini" v-model="khLength" :min="6" :max="20" label="描述文字"></el-input-number>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item label="识别设置">
|
|
|
+ <el-radio v-model="recTarget" :label="1" :value="1">整块区域</el-radio>
|
|
|
+ <el-radio v-model="recTarget" :label="2" :value="2">单个涂点</el-radio>
|
|
|
+ </el-form-item>
|
|
|
+ <el-form-item>
|
|
|
+ <el-button type="primary" size="mini" @click="updateStdKhInfo">保存</el-button>
|
|
|
+ </el-form-item>
|
|
|
+ </el-form>
|
|
|
+ <div style="border:1px solid #ccc;overflow: scroll;" @contextmenu.prevent="onContextmenu">
|
|
|
+ <canvas id="myCanvas" ref="myCanvas" :width="srcImgWidth" :height="srcImgHeight" @click="findRect"
|
|
|
+ @mousedown="mousedown" @mouseup="mouseup" @mousemove="mousemove">
|
|
|
+ </canvas>
|
|
|
+ <canvas id="myCopyCanvas" ref="myCopyCanvas" :width="srcImgWidth" :height="srcImgHeight"
|
|
|
+ style="display: none;">
|
|
|
+ </canvas>
|
|
|
+ <canvas id="myCropCanvas" ref="myCropCanvas" :width="rectWidth" :height="rectHeight">
|
|
|
+ </canvas>
|
|
|
+ <img :src="srcImg" width="100%" alt="" id="stdKhImg" style="display:none;">
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+ export default {
|
|
|
+ name: "canvasDrawer",
|
|
|
+ props: {
|
|
|
+ srcImg: String,
|
|
|
+ curId:String
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ flag: false,
|
|
|
+ rectWidth: 0, //矩形框的宽
|
|
|
+ rectHeight: 0, //矩形框的高
|
|
|
+ totalRect: [], //画的所有的矩形坐标长度数据存储在数组中
|
|
|
+ downX: 0, //鼠标点击图片落下时的位置(X)
|
|
|
+ downY: 0, //鼠标点击图片落下时的位置(Y)
|
|
|
+ ctx: "", //dom节点
|
|
|
+ canvas: null,
|
|
|
+ rectTag: false,
|
|
|
+ delIndex: null, //删除时选中的矩形框的index
|
|
|
+ atime: null,
|
|
|
+ dialogVisible: false, //删除的弹出框
|
|
|
+ keyCode: null,
|
|
|
+ startX: null,
|
|
|
+ startY: null,
|
|
|
+ img: null,
|
|
|
+ imgWidth: null,
|
|
|
+ imgHeight: null,
|
|
|
+ cropWidth: 0,
|
|
|
+ cropHeight: 0,
|
|
|
+ khType: 1,
|
|
|
+ khLength: 6,
|
|
|
+ recTarget: 1,
|
|
|
+ curArea:null,
|
|
|
+ stdRect:null,
|
|
|
+ srcImgWidth:null,
|
|
|
+ srcImgHeight:null,
|
|
|
+ stdKhList:[]
|
|
|
+ };
|
|
|
+ },
|
|
|
+ created() {
|
|
|
+ var image = new Image();
|
|
|
+ image.src = this.srcImg
|
|
|
+ this.srcImgWidth = image.width;
|
|
|
+ this.srcImgHeight = image.height;
|
|
|
+ this.getData();
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ var image = new Image();
|
|
|
+ image.src = this.srcImg
|
|
|
+ this.srcImgWidth = image.width;
|
|
|
+ this.srcImgHeight = image.height;
|
|
|
+ let that = this
|
|
|
+ // 绘图canvas
|
|
|
+ this.canvas = this.$refs.myCanvas;
|
|
|
+ this.canvas = document.getElementById("myCanvas")
|
|
|
+ this.ctx = this.canvas.getContext("2d");
|
|
|
+ // 复制canvas
|
|
|
+ this.copyCanvas = document.getElementById("myCopyCanvas")
|
|
|
+ this.copyCtx = this.copyCanvas.getContext("2d");
|
|
|
+ // 裁剪canvas
|
|
|
+ this.cropCanvas = document.getElementById("myCropCanvas")
|
|
|
+ this.cropCtx = this.cropCanvas.getContext("2d");
|
|
|
+
|
|
|
+ let img = document.getElementById("stdKhImg");
|
|
|
+
|
|
|
+ img.onload = function () {
|
|
|
+ that.ctx.drawImage(img, 0, 0, that.srcImgWidth, that.srcImgHeight, 0, 0, that.srcImgWidth, that
|
|
|
+ .srcImgHeight)
|
|
|
+ that.copyCtx.drawImage(img, 0, 0, 672, 264, 0, 0, 672, 264)
|
|
|
+ }
|
|
|
+ that.img = img
|
|
|
+
|
|
|
+ document.onkeydown = function (event) {
|
|
|
+ that.keyCode = event.keyCode
|
|
|
+ }
|
|
|
+
|
|
|
+ document.onkeyup = function (event) {
|
|
|
+ that.keyCode = null
|
|
|
+ that.downX = that.startX
|
|
|
+ that.downY = that.downY
|
|
|
+ that.startX = null
|
|
|
+ that.startY = null
|
|
|
+
|
|
|
+ }
|
|
|
+ },
|
|
|
+
|
|
|
+ methods: {
|
|
|
+ onContextmenu(event) {
|
|
|
+ this.$contextmenu({
|
|
|
+ items: [{
|
|
|
+ label: "复制",
|
|
|
+ onClick: () => {
|
|
|
+ this.message = "返回(B)";
|
|
|
+ console.log("返回(B)");
|
|
|
+ }
|
|
|
+ }, {
|
|
|
+ label: "删除",
|
|
|
+ onClick: () => {
|
|
|
+ this.del()
|
|
|
+ }
|
|
|
+ }, {
|
|
|
+ label: "刷新",
|
|
|
+ onClick: () => {
|
|
|
+ this.clear();
|
|
|
+ this.totalRect = [];
|
|
|
+ this.redrawAll();
|
|
|
+ }
|
|
|
+ },{
|
|
|
+ label: "正列",
|
|
|
+ onClick: () => {
|
|
|
+ this.message = "返回(B)";
|
|
|
+ console.log("返回(B)");
|
|
|
+ this.zhenlie();
|
|
|
+ }
|
|
|
+ }],
|
|
|
+ x: event.clientX,
|
|
|
+ y: event.clientY,
|
|
|
+ zIndex: 10000,
|
|
|
+ minWidth: 100
|
|
|
+ })
|
|
|
+ },
|
|
|
+ copy() {
|
|
|
+ console.log("复制操作");
|
|
|
+ },
|
|
|
+
|
|
|
+ delete() {
|
|
|
+ console.log("删除操作");
|
|
|
+ },
|
|
|
+ zhenlie(){
|
|
|
+ let stdW = this.stdRect["w"];
|
|
|
+ let stdH = this.stdRect["h"];
|
|
|
+ // 计算涂点间距
|
|
|
+ let totalWidth = this.curArea["w"];
|
|
|
+ let totalHeight = this.curArea["h"];
|
|
|
+ let startX = this.curArea["x"];
|
|
|
+ let startY = this.curArea["y"];
|
|
|
+ let stepW = (totalWidth - stdW*this.khLength)/(this.khLength-1);
|
|
|
+ let stepH = (totalHeight - stdH*10)/9;
|
|
|
+ // 计算阵列矩形列表
|
|
|
+ let rectArray = [];
|
|
|
+ let stdKhList = [];
|
|
|
+ for(var i=0;i<this.khLength;i++){
|
|
|
+ let tmpRow = [];
|
|
|
+ for(var j=0;j<10;j++){
|
|
|
+ let tmp = {
|
|
|
+ beforex:(stepW+stdW)*i+startX,
|
|
|
+ beforey:(stepH+stdH)*j+startY,
|
|
|
+ rectW:stdW,
|
|
|
+ rectH:stdH
|
|
|
+ }
|
|
|
+ rectArray.push(tmp)
|
|
|
+ tmpRow.push(tmp)
|
|
|
+ }
|
|
|
+ stdKhList.push(tmpRow)
|
|
|
+ }
|
|
|
+ this.clear();
|
|
|
+ this.totalRect = rectArray;
|
|
|
+ this.stdKhList = stdKhList;
|
|
|
+ this.redrawAll();
|
|
|
+ },
|
|
|
+ zoom2(flag = true) {
|
|
|
+ const scale = 0.8;
|
|
|
+ const beta = flag ? 1 / scale : scale;
|
|
|
+ this.ctx.scale(beta, beta);
|
|
|
+ },
|
|
|
+ // 放下鼠标
|
|
|
+ mousedown(e) {
|
|
|
+ console.log("鼠标落下");
|
|
|
+ this.atime = new Date().getTime();
|
|
|
+ this.flag = true;
|
|
|
+ this.downX = e.offsetX; // 鼠标落下时的X
|
|
|
+ this.downY = e.offsetY; // 鼠标落下时的Y
|
|
|
+ this.mousemove(e);
|
|
|
+ },
|
|
|
+ // 移动鼠标
|
|
|
+ mousemove(e) {
|
|
|
+ if (this.flag) {
|
|
|
+ //判断如果重右下往左上画,这种画法直接return
|
|
|
+ if (this.downX - e.offsetX > 0 || this.downY - e.offsetY > 0) {
|
|
|
+ console.log("重右下往左上画");
|
|
|
+ return
|
|
|
+ } else {
|
|
|
+ console.log("重左上往右下画");
|
|
|
+ this.clear(); //清空画布
|
|
|
+ this.redrawAll();
|
|
|
+ console.log(this.keyCode)
|
|
|
+ if (this.keyCode == 32) {
|
|
|
+ this.startX = this.downX + (e.offsetX - this.downX) - this.rectWidth
|
|
|
+ this.startY = this.downY + (e.offsetY - this.downY) - this.rectHeight
|
|
|
+ // console.log(startX,startY,this.rectWidth,this.rectHeight)
|
|
|
+ this.drawRect(
|
|
|
+ this.startX,
|
|
|
+ this.startY,
|
|
|
+ this.rectWidth,
|
|
|
+ this.rectHeight
|
|
|
+ )
|
|
|
+ } else {
|
|
|
+ //如果重左上往右下画,计算出鼠标移动的距离,也就是矩形框的宽和高
|
|
|
+ this.rectWidth = Math.abs(this.downX - e.offsetX)
|
|
|
+ this.rectHeight = Math.abs(this.downY - e.offsetY)
|
|
|
+ console.log("this.rectWidth", this.rectWidth);
|
|
|
+ console.log("this.rectHeight", this.rectHeight);
|
|
|
+ //判断这个宽高的长度,如果小于10,直接return,因为鼠标移动距离过于短
|
|
|
+ //防止点击页面时,会画成一个点,没有意义
|
|
|
+ if (this.rectWidth < 10 || this.rectHeight < 10) {
|
|
|
+ console.log("只是点击");
|
|
|
+ this.rectWidth = 0;
|
|
|
+ this.rectHeight = 0;
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (this.startX) {
|
|
|
+ this.downX = this.startX
|
|
|
+ }
|
|
|
+ if (this.startY) {
|
|
|
+ this.downY = this.startY
|
|
|
+ }
|
|
|
+ this.drawRect(
|
|
|
+ this.downX,
|
|
|
+ this.downY,
|
|
|
+ this.rectWidth,
|
|
|
+ this.rectHeight
|
|
|
+ )
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 抬起鼠标
|
|
|
+ mouseup(e) {
|
|
|
+ // console.log("鼠标抬起");
|
|
|
+ this.flag = false;
|
|
|
+ let a = new Date().getTime();
|
|
|
+ console.log(a - this.atime, 444444444)
|
|
|
+ if (a - this.atime > 150) {
|
|
|
+ this.rectTag = false;
|
|
|
+ } else {
|
|
|
+ this.rectTag = true;
|
|
|
+ }
|
|
|
+ if (this.rectWidth || this.rectHeight) {
|
|
|
+ //将画出的数据保存在totalRect中
|
|
|
+ this.totalRect.push({
|
|
|
+ beforex: this.downX,
|
|
|
+ beforey: this.downY,
|
|
|
+ rectW: this.rectWidth,
|
|
|
+ rectH: this.rectHeight,
|
|
|
+ });
|
|
|
+
|
|
|
+ let data = this.copyCtx.getImageData(this.downX, this.downY, this.rectWidth, this.rectHeight)
|
|
|
+ this.cropWidth = this.rectWidth;
|
|
|
+ this.cropHeight = this.rectHeight;
|
|
|
+ let c = document.getElementById("myCropCanvas");
|
|
|
+ let ctx = c.getContext("2d");
|
|
|
+ ctx.putImageData(data, 0, 0)
|
|
|
+ let val = c.toDataURL("image/jpeg");
|
|
|
+ // 单个涂点
|
|
|
+ if (this.recTarget == 2) {
|
|
|
+ this.$api.tryRecArray({
|
|
|
+ sx: this.downX,
|
|
|
+ sy: this.downY,
|
|
|
+ img: val,
|
|
|
+ khLength: 15
|
|
|
+ }).then(res => {
|
|
|
+ let oneRect = res.data.data.oneRect;
|
|
|
+ this.totalRect.pop()
|
|
|
+ this.totalRect.push({
|
|
|
+ beforex: oneRect.x,
|
|
|
+ beforey: oneRect.y,
|
|
|
+ rectW: oneRect.w,
|
|
|
+ rectH: oneRect.h
|
|
|
+ })
|
|
|
+ this.stdRect = {x:oneRect.x,y:oneRect.y,w:oneRect.w,h:oneRect.h}
|
|
|
+ this.clear(); //清空画布
|
|
|
+ this.redrawAll();
|
|
|
+
|
|
|
+ })
|
|
|
+ }else{
|
|
|
+ this.curArea = {x:this.downX,y:this.downY,w:this.rectWidth,h:this.rectHeight}
|
|
|
+ }
|
|
|
+ }
|
|
|
+ },
|
|
|
+ redrawAll() {
|
|
|
+ // console.log("先画之前画过的图,保证画多个的时候看起来像前一个不消失");
|
|
|
+ this.ctx.drawImage(this.img, 0, 0)
|
|
|
+ if (this.totalRect.length > 0) {
|
|
|
+ this.totalRect.forEach((e) => {
|
|
|
+ // console.log("eeeeeeeeeeeeeeeee",e);
|
|
|
+ this.drawRect(e.beforex, e.beforey, e.rectW, e.rectH);
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ //清除画布
|
|
|
+ clear() {
|
|
|
+ this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
|
|
|
+ },
|
|
|
+ drawRect(x, y, lineW, lineY) {
|
|
|
+ // 开始绘制;
|
|
|
+ this.ctx.beginPath();
|
|
|
+ // //设置线条颜色,必须放在绘制之前
|
|
|
+ this.ctx.strokeStyle = "#850a1e";
|
|
|
+ // console.log("44444444");
|
|
|
+ // // 线宽设置,必须放在绘制之前
|
|
|
+ this.ctx.lineWidth = 1;
|
|
|
+ // console.log("5555555555");
|
|
|
+ // strokeRect参数:(左上角x坐标,y:左上角y坐标,绘画矩形的宽度,绘画矩形的高度)
|
|
|
+ this.ctx.strokeRect(x, y, lineW, lineY);
|
|
|
+ // console.log("66666666666666");
|
|
|
+ },
|
|
|
+ //点击画布
|
|
|
+ findRect(e) {
|
|
|
+ console.log(e,88888888888888)
|
|
|
+ if (this.rectTag || true) {
|
|
|
+ console.log("this.totalRect", this.totalRect);
|
|
|
+ //当点击画布的时候,计算有没有点再矩形框内、哪个矩形框内
|
|
|
+ this.totalRect.map((item, index) => {
|
|
|
+ if (
|
|
|
+ e.offsetX - item.beforex > item.rectW ||
|
|
|
+ e.offsetX < item.beforex ||
|
|
|
+ e.offsetY - item.beforey > item.rectH ||
|
|
|
+ e.offsetY < item.beforey
|
|
|
+ ) {
|
|
|
+ return;
|
|
|
+ } else {
|
|
|
+ //找到之后,设置下标
|
|
|
+ this.delIndex = index;
|
|
|
+ //打开删除弹框
|
|
|
+ this.dialogVisible = true;
|
|
|
+ console.log("this.delIndex", this.delIndex);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
+ //点击删除按钮
|
|
|
+ del() {
|
|
|
+ this.dialogVisible = false;
|
|
|
+ //删除
|
|
|
+ this.ctx.clearRect(
|
|
|
+ this.totalRect[this.delIndex].beforex - 2,
|
|
|
+ this.totalRect[this.delIndex].beforey - 2,
|
|
|
+ this.totalRect[this.delIndex].rectW + 4,
|
|
|
+ this.totalRect[this.delIndex].rectH + 4
|
|
|
+ );
|
|
|
+ //删掉totalRect的数据,真正的项目中需要调用后台接口,删掉数据库中存储的数据
|
|
|
+ this.totalRect.splice(this.delIndex, 1);
|
|
|
+ //删掉之后,再画一次,刷新页面
|
|
|
+ this.redrawAll();
|
|
|
+ console.log(this.totalRect, "删除了没");
|
|
|
+ },
|
|
|
+ getData(){
|
|
|
+ this.totalRect = [];
|
|
|
+ this.$api.getPaperInfo({id:this.curId}).then((res) => {
|
|
|
+ this.khType = res.data.data.khType;
|
|
|
+ this.khLength = res.data.data.khLength;
|
|
|
+ let stdKhList = JSON.parse(res.data.data.stdKhList);
|
|
|
+ stdKhList.forEach((children,index)=>{
|
|
|
+ children.forEach((item,index)=>{
|
|
|
+ this.totalRect.push(item)
|
|
|
+ })
|
|
|
+ })
|
|
|
+ this.redrawAll();
|
|
|
+ });
|
|
|
+ },
|
|
|
+ updateStdKhInfo(){
|
|
|
+ let params = {
|
|
|
+ id: this.curId,
|
|
|
+ stdKhList:this.stdKhList,
|
|
|
+ khType:this.khType,
|
|
|
+ khLength:this.khLength,
|
|
|
+ khPoints:this.srcImg
|
|
|
+ }
|
|
|
+ this.$api.updatePaperInfo(params).then(res => {
|
|
|
+ this.msgSuccess("成功!");
|
|
|
+ this.open = false;
|
|
|
+ })
|
|
|
+ }
|
|
|
+ },
|
|
|
+ };
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+ #myCanvas {
|
|
|
+ background-color: #ccc;
|
|
|
+ }
|
|
|
+
|
|
|
+ .dislog {
|
|
|
+ /* width: 200px; */
|
|
|
+ /* height: 200px; */
|
|
|
+ background-color: pink;
|
|
|
+ }
|
|
|
+</style>
|