| | |
| | | ref="remarksName" |
| | | v-model="delCursor.remarksName" |
| | | size="mini" |
| | | style="margin-left: 90px;margin-top: 15px; width: 150px; position:relation;" |
| | | style=" |
| | | margin-left: 90px; |
| | | margin-top: 15px; |
| | | width: 150px; |
| | | position: relation; |
| | | " |
| | | placeholder="图形备注" |
| | | @change="changeName" |
| | | ></el-input> |
| | | </p> |
| | | <el-row style="margin-top:10px"> |
| | | <el-col :span="2" style="position:relative;margin-top:10px"> |
| | | <el-tooltip content="切换到此状态后可选中已画图形" placement="left" popper-class="atooltip"> |
| | | <el-row style="margin-top: 10px"> |
| | | <el-col :span="2" style="position: relative; margin-top: 10px"> |
| | | <el-tooltip |
| | | content="切换到此状态后可选中已画图形" |
| | | placement="left" |
| | | popper-class="atooltip" |
| | | > |
| | | <el-button |
| | | class="btn" |
| | | @click="changeType('0')" |
| | | :disabled="disableSelect" |
| | | :style="type == '0'? 'border:2px solid #0066eb':''" |
| | | :style="type == '0' ? 'border:2px solid #0066eb' : ''" |
| | | > |
| | | <i class="iconfont iconshou"></i> |
| | | </el-button> |
| | |
| | | content="直线" |
| | | placement="left" |
| | | popper-class="atooltip" |
| | | :style="type == '1'? 'border:2px solid #0066eb':''" |
| | | :style="type == '1' ? 'border:2px solid #0066eb' : ''" |
| | | > |
| | | <el-button class="btn" @click="changeType('1')" :disabled="disableLine"> |
| | | <el-button |
| | | class="btn" |
| | | @click="changeType('1')" |
| | | :disabled="disableLine" |
| | | > |
| | | <i class="iconfont iconzhixian"></i> |
| | | </el-button> |
| | | </el-tooltip> |
| | |
| | | content="矩形" |
| | | placement="left" |
| | | popper-class="atooltip" |
| | | :style="type == '2'? 'border:2px solid #0066eb':''" |
| | | :style="type == '2' ? 'border:2px solid #0066eb' : ''" |
| | | > |
| | | <el-button class="btn" @click="changeType('2')" :disabled="disableRect"> |
| | | <el-button |
| | | class="btn" |
| | | @click="changeType('2')" |
| | | :disabled="disableRect" |
| | | > |
| | | <i class="iconfont iconlegend-base"></i> |
| | | </el-button> |
| | | </el-tooltip> |
| | |
| | | content="箭头" |
| | | placement="left" |
| | | popper-class="atooltip" |
| | | :style="type == '4'? 'border:2px solid #0066eb':''" |
| | | :style="type == '4' ? 'border:2px solid #0066eb' : ''" |
| | | > |
| | | <el-button class="btn" @click="changeType('4')" :disabled="disableArrow"> |
| | | <el-button |
| | | class="btn" |
| | | @click="changeType('4')" |
| | | :disabled="disableArrow" |
| | | > |
| | | <i class="iconfont iconrighttop"></i> |
| | | </el-button> |
| | | </el-tooltip> |
| | |
| | | content="多边形:双击结束绘制" |
| | | placement="left" |
| | | popper-class="atooltip" |
| | | :style="type == '5'? 'border:2px solid #0066eb':''" |
| | | :style="type == '5' ? 'border:2px solid #0066eb' : ''" |
| | | > |
| | | <el-button @click="changeType('5')" class="btn" :disabled="disablePolygon"> |
| | | <el-button |
| | | @click="changeType('5')" |
| | | class="btn" |
| | | :disabled="disablePolygon" |
| | | > |
| | | <i class="iconfont iconduobianxing"></i> |
| | | </el-button> |
| | | </el-tooltip> |
| | | <el-tooltip content="选中图形再编辑重绘,重绘的图形保留之前的名称" placement="left" popper-class="atooltip"> |
| | | <el-tooltip |
| | | content="选中图形再编辑重绘,重绘的图形保留之前的名称" |
| | | placement="left" |
| | | popper-class="atooltip" |
| | | > |
| | | <el-button class="btn" @click="edit()" :disabled="disableSelect"> |
| | | <i class="iconfont iconxiugaitubiao1"></i> |
| | | </el-button> |
| | | </el-tooltip> |
| | | <el-tooltip content="先选中图形,再删除" placement="left" popper-class="atooltip"> |
| | | <el-tooltip |
| | | content="先选中图形,再删除" |
| | | placement="left" |
| | | popper-class="atooltip" |
| | | > |
| | | <el-button class="btn" @click="del()" :disabled="disableSelect"> |
| | | <i class="iconfont iconshanchu5"></i> |
| | | </el-button> |
| | | </el-tooltip> |
| | | <el-tooltip content="清空所有已画图形,此操作不可撤销" placement="left" popper-class="atooltip"> |
| | | <el-tooltip |
| | | content="清空所有已画图形,此操作不可撤销" |
| | | placement="left" |
| | | popper-class="atooltip" |
| | | > |
| | | <el-button class="btn" @click="clear()" :disabled="disableSelect"> |
| | | <i class="iconfont iconqingkong"></i> |
| | | </el-button> |
| | | </el-tooltip> |
| | | <el-tooltip content="撤销上一步操作" placement="left" popper-class="atooltip"> |
| | | <el-button class="btn" @click="del()" :disabled="disableSelect" style="border:0px"> |
| | | <el-tooltip |
| | | content="撤销上一步操作" |
| | | placement="left" |
| | | popper-class="atooltip" |
| | | > |
| | | <el-button |
| | | class="btn" |
| | | @click="undo()" |
| | | :disabled="disableSelect" |
| | | style="border: 0px" |
| | | > |
| | | <i class="iconfont iconfanhui1" style="font-size: 2rem"></i> |
| | | </el-button> |
| | | <!-- <span |
| | |
| | | </el-tooltip> |
| | | <!-- <el-button type="default" @click="undo()">撤销</el-button> --> |
| | | </el-col> |
| | | <el-col :span="22" style="position:relative;width:980px;padding-left:10px"> |
| | | <el-col |
| | | :span="22" |
| | | style="position: relative; width: 980px; padding-left: 10px" |
| | | > |
| | | <canvas |
| | | id="canvasDialog" |
| | | ref="canvasDialog" |
| | | width="960" |
| | | height="540" |
| | | :style=" |
| | | `position:static;background:url(${snapshot_url}) 0% 0%/960px 540px no-repeat;` |
| | | " |
| | | :style="`position:static;background:url(${snapshot_url}) 0% 0%/960px 540px no-repeat;`" |
| | | ></canvas> |
| | | <p |
| | | style="position:absolute;width:350px;left:80px;top:90px;color:white;font-size:1.5rem" |
| | | style=" |
| | | position: absolute; |
| | | width: 350px; |
| | | left: 80px; |
| | | top: 90px; |
| | | color: white; |
| | | font-size: 1.5rem; |
| | | " |
| | | :style="disabled ? `display:block;` : `display:none;`" |
| | | >批量配置方式不允许绘制区域,请选择摄像机进行区域绘制</p> |
| | | > |
| | | 批量配置方式不允许绘制区域,请选择摄像机进行区域绘制 |
| | | </p> |
| | | <!-- <span |
| | | class="iconfont icongengxin" |
| | | @click="refresh" |
| | |
| | | line: [], |
| | | rect: [], // {id:'uuid', name: '矩形1', location: [{ x: 20, y: 30 }, { x: 20, y: 60 }, { x: 100, y: 60 }, { x: 100, y: 30 }] } |
| | | arrow: [], |
| | | polygon: [] |
| | | polygon: [], |
| | | }, |
| | | // canvasData: this.canvasDataToChild, // 最终输出的画布坐标数据 |
| | | originX: null, // 当前点击点x |
| | |
| | | c: null, |
| | | ctx: null, |
| | | inputWidth: 80, |
| | | oldName: "" // 用来暂存更改之前的remarksName,方便放进撤销队列里 |
| | | oldName: "", // 用来暂存更改之前的remarksName,方便放进撤销队列里 |
| | | }; |
| | | }, |
| | | mounted() { |
| | |
| | | } |
| | | this.oldName = oldVal.remarksName; |
| | | }, |
| | | deep: true |
| | | deep: true, |
| | | }, |
| | | snapshot_url: { |
| | | handler(newVal, oldVal) { |
| | | if (newVal !== oldVal) { |
| | | // console.log(newVal, 'canvasDialog') |
| | | } |
| | | } |
| | | }, |
| | | }, |
| | | canvasDataToChild: { |
| | | handler(newVal, oldVal) { |
| | |
| | | this.step++; |
| | | this.canvasHistory.push({ |
| | | type: 0, |
| | | src: this.c.toDataURL("image/png") |
| | | src: this.c.toDataURL("image/png"), |
| | | }); |
| | | }, |
| | | deep: true |
| | | } |
| | | deep: true, |
| | | }, |
| | | // canvasDataToChild: function(newVal, oldVal) { |
| | | // this.init() |
| | | // } |
| | |
| | | methods: { |
| | | // 初始化函数 |
| | | init() { |
| | | this.c = document.querySelector("#canvasDialog"); |
| | | //this.c = document.querySelector("#canvasDialog"); |
| | | this.c = this.$refs["canvasDialog"]; |
| | | this.ctx = this.c.getContext("2d"); |
| | | this.drawCanvasInit(); |
| | | this.canvasData = JSON.parse(JSON.stringify(this.canvasDataToChild)); |
| | |
| | | this.step++; |
| | | this.canvasHistory.push({ |
| | | type: 0, |
| | | src: this.c.toDataURL("image/png") |
| | | src: this.c.toDataURL("image/png"), |
| | | }); |
| | | this.delCursor = { type: -1, index: -1, remarksName: "", id: "" } |
| | | this.delCursor = { type: -1, index: -1, remarksName: "", id: "" }; |
| | | |
| | | console.log("画布初始化"); |
| | | }, |
| | | // 取消画布清除状态函数 |
| | | cancel() { |
| | | this.changeType('0') |
| | | this.undisabled() |
| | | this.changeType("0"); |
| | | this.undisabled(); |
| | | //this.delCursor = {} |
| | | this.delCursor = { type: -1, index: -1, remarksName: "", id: "" }; |
| | | this.canvasHistory.length = 0; |
| | |
| | | this.step++; |
| | | this.canvasHistory.push({ |
| | | type: 0, |
| | | src: this.c.toDataURL("image/png") |
| | | src: this.c.toDataURL("image/png"), |
| | | }); |
| | | }, |
| | | // 主监听流程 |
| | | drawCanvasInit() { |
| | | window.addEventListener("keydown", e => { |
| | | window.addEventListener("keydown", (e) => { |
| | | let keyID = e.keyCode ? e.keyCode : e.which; |
| | | if (keyID === 82) { |
| | | // r键 |
| | | this.undo(); |
| | | } |
| | | }); |
| | | this.c.addEventListener("mousedown", e => { |
| | | this.c.addEventListener("mousedown", (e) => { |
| | | if (this.type !== "0") { |
| | | this.flag = true; |
| | | this.originX = e.offsetX; // 鼠标落下时的X |
| | |
| | | // 绘制多边形 |
| | | this.points.push({ |
| | | x: this.originX, |
| | | y: this.originY |
| | | y: this.originY, |
| | | }); |
| | | } |
| | | } else { |
| | | this.clickSelect(e); |
| | | } |
| | | }); |
| | | this.c.addEventListener("mousemove", e => { |
| | | this.c.addEventListener("mousemove", (e) => { |
| | | switch (this.type) { |
| | | case "1": |
| | | this.drawLine(e) |
| | | this.drawLine(e); |
| | | break; |
| | | case "2": |
| | | this.drawRect(e) |
| | | this.drawRect(e); |
| | | break; |
| | | case "4": |
| | | this.drawArrow(e) |
| | | this.drawArrow(e); |
| | | break; |
| | | case "5": |
| | | this.drawPolygon(e) |
| | | this.drawPolygon(e); |
| | | break; |
| | | } |
| | | }); |
| | | this.c.addEventListener("mouseup", e => { |
| | | this.c.addEventListener("mouseup", (e) => { |
| | | switch (this.type) { |
| | | case "1": |
| | | // 直线 |
| | |
| | | break; |
| | | } |
| | | }); |
| | | this.c.addEventListener("dblclick", e => { |
| | | this.c.addEventListener("dblclick", (e) => { |
| | | if (this.type === "5") { |
| | | // 绘制多边形 |
| | | this.polygonDblclick(e); |
| | |
| | | this.canvasData.polygon.length = 0; |
| | | this.canvasHistory.length = 0; |
| | | |
| | | this.indexInit() |
| | | this.freedEdit() |
| | | this.delCursor = {} |
| | | this.indexInit(); |
| | | this.freedEdit(); |
| | | this.delCursor = {}; |
| | | this.step = -1; |
| | | }, |
| | | // 修改图形名称 |
| | |
| | | switch (this.delCursor.type) { |
| | | case "1": |
| | | this.oldName = this.canvasData.line[this.delCursor.index].name; |
| | | this.canvasData.line[ |
| | | this.delCursor.index |
| | | ].name = this.delCursor.remarksName; |
| | | this.canvasData.line[this.delCursor.index].name = |
| | | this.delCursor.remarksName; |
| | | break; |
| | | case "2": |
| | | this.oldName = this.canvasData.rect[this.delCursor.index].name; |
| | | this.canvasData.rect[ |
| | | this.delCursor.index |
| | | ].name = this.delCursor.remarksName; |
| | | this.canvasData.rect[this.delCursor.index].name = |
| | | this.delCursor.remarksName; |
| | | break; |
| | | case "4": |
| | | this.oldName = this.canvasData.arrow[this.delCursor.index].name; |
| | | this.canvasData.arrow[ |
| | | this.delCursor.index |
| | | ].name = this.delCursor.remarksName; |
| | | this.canvasData.arrow[this.delCursor.index].name = |
| | | this.delCursor.remarksName; |
| | | break; |
| | | case "5": |
| | | this.oldName = this.canvasData.polygon[this.delCursor.index].name; |
| | | this.canvasData.polygon[ |
| | | this.delCursor.index |
| | | ].name = this.delCursor.remarksName; |
| | | this.canvasData.polygon[this.delCursor.index].name = |
| | | this.delCursor.remarksName; |
| | | break; |
| | | } |
| | | this.clickSelect(); |
| | |
| | | type: this.delCursor.type, |
| | | src: this.c.toDataURL("image/png"), |
| | | index: this.delCursor.index, |
| | | name: this.oldName |
| | | name: this.oldName, |
| | | }); |
| | | } else { |
| | | this.$notify({ |
| | | type: "warning", |
| | | message: "命名长度不能超过6个字!" |
| | | message: "命名长度不能超过6个字!", |
| | | }); |
| | | switch (this.delCursor.type) { |
| | | case "1": |
| | | this.delCursor.remarksName = this.canvasData.line[ |
| | | this.delCursor.index |
| | | ].name; |
| | | this.delCursor.remarksName = |
| | | this.canvasData.line[this.delCursor.index].name; |
| | | break; |
| | | case "2": |
| | | this.delCursor.remarksName = this.canvasData.rect[ |
| | | this.delCursor.index |
| | | ].name; |
| | | this.delCursor.remarksName = |
| | | this.canvasData.rect[this.delCursor.index].name; |
| | | break; |
| | | case "4": |
| | | this.delCursor.remarksName = this.canvasData.arrow[ |
| | | this.delCursor.index |
| | | ].name; |
| | | this.delCursor.remarksName = |
| | | this.canvasData.arrow[this.delCursor.index].name; |
| | | break; |
| | | case "5": |
| | | this.delCursor.remarksName = this.canvasData.polygon[ |
| | | this.delCursor.indexhhhhhhhhhhh |
| | | ].name; |
| | | this.delCursor.remarksName = |
| | | this.canvasData.polygon[this.delCursor.indexhhhhhhhhhhh].name; |
| | | break; |
| | | } |
| | | } |
| | |
| | | type: this.delCursor.type, |
| | | src: this.c.toDataURL("image/png"), |
| | | index: this.delCursor.index, |
| | | data: delEle |
| | | data: delEle, |
| | | }); |
| | | }, |
| | | // 删除元素 |
| | | del() { |
| | | debugger |
| | | let delEle = {}; |
| | | switch (this.delCursor.type) { |
| | | case "1": |
| | |
| | | break; |
| | | case "5": |
| | | delEle = this.canvasData.polygon[this.delCursor.index]; |
| | | this.canvasData.polygon.splice(this.delCursor.index+1, 1); |
| | | this.canvasData.polygon.splice(this.delCursor.index, 1); |
| | | break; |
| | | } |
| | | this.clickSelect(); |
| | |
| | | src: this.c.toDataURL("image/png"), |
| | | index: this.delCursor.index, |
| | | deleteLength: 0, // 删除的话deleteLength为0 |
| | | data: delEle |
| | | data: delEle, |
| | | }); |
| | | // console.log(this.canvasHistory, "删除之后的撤销队列"); |
| | | }, |
| | |
| | | delEle = { |
| | | id: this.canvasData.line[this.delCursor.index].id, |
| | | name: this.canvasData.line[this.delCursor.index].name, |
| | | location: this.canvasData.line[this.delCursor.index].location |
| | | } |
| | | location: this.canvasData.line[this.delCursor.index].location, |
| | | }; |
| | | // this.canvasData.line.splice(this.delCursor.index, 1); |
| | | this.canvasData.line[this.delCursor.index].location = [{ x: delEle.location[0].x, y: delEle.location[0].y }, { x: delEle.location[0].x, y: delEle.location[0].y }] |
| | | this.canvasData.line[this.delCursor.index].location = [ |
| | | { x: delEle.location[0].x, y: delEle.location[0].y }, |
| | | { x: delEle.location[0].x, y: delEle.location[0].y }, |
| | | ]; |
| | | break; |
| | | case "2": |
| | | delEle = { |
| | | id: this.canvasData.rect[this.delCursor.index].id, |
| | | name: this.canvasData.rect[this.delCursor.index].name, |
| | | location: this.canvasData.rect[this.delCursor.index].location |
| | | } |
| | | // this.canvasData.rect.splice(this.delCursor.index, 1); |
| | | this.canvasData.rect[this.delCursor.index].location = [{ x: delEle.location[0].x, y: delEle.location[0].y }, { x: delEle.location[0].x, y: delEle.location[0].y }, { x: delEle.location[0].x, y: delEle.location[0].y }, { x: delEle.location[0].x, y: delEle.location[0].y }] |
| | | location: this.canvasData.rect[this.delCursor.index].location, |
| | | }; |
| | | // this.canvasData.rect.splice(this.delCursor.index, 1); |
| | | this.canvasData.rect[this.delCursor.index].location = [ |
| | | { x: delEle.location[0].x, y: delEle.location[0].y }, |
| | | { x: delEle.location[0].x, y: delEle.location[0].y }, |
| | | { x: delEle.location[0].x, y: delEle.location[0].y }, |
| | | { x: delEle.location[0].x, y: delEle.location[0].y }, |
| | | ]; |
| | | break; |
| | | case "4": |
| | | delEle = { |
| | | id: this.canvasData.arrow[this.delCursor.index].id, |
| | | name: this.canvasData.arrow[this.delCursor.index].name, |
| | | location: this.canvasData.arrow[this.delCursor.index].location |
| | | } |
| | | // this.canvasData.arrow.splice(this.delCursor.index, 1); |
| | | this.canvasData.arrow[this.delCursor.index].location = [{ x: delEle.location[0].x, y: delEle.location[0].y }, { x: delEle.location[0].x, y: delEle.location[0].y }] |
| | | location: this.canvasData.arrow[this.delCursor.index].location, |
| | | }; |
| | | // this.canvasData.arrow.splice(this.delCursor.index, 1); |
| | | this.canvasData.arrow[this.delCursor.index].location = [ |
| | | { x: delEle.location[0].x, y: delEle.location[0].y }, |
| | | { x: delEle.location[0].x, y: delEle.location[0].y }, |
| | | ]; |
| | | break; |
| | | case "5": |
| | | delEle = { |
| | | id: this.canvasData.polygon[this.delCursor.index].id, |
| | | name: this.canvasData.polygon[this.delCursor.index].name, |
| | | location: this.canvasData.polygon[this.delCursor.index].location |
| | | } |
| | | // this.canvasData.polygon.splice(this.delCursor.index, 1); |
| | | this.canvasData.polygon[this.delCursor.index].location = [{ x: delEle.location[0].x, y: delEle.location[0].y }, { x: delEle.location[0].x, y: delEle.location[0].y }, { x: delEle.location[0].x, y: delEle.location[0].y }] |
| | | location: this.canvasData.polygon[this.delCursor.index].location, |
| | | }; |
| | | // this.canvasData.polygon.splice(this.delCursor.index, 1); |
| | | this.canvasData.polygon[this.delCursor.index].location = [ |
| | | { x: delEle.location[0].x, y: delEle.location[0].y }, |
| | | { x: delEle.location[0].x, y: delEle.location[0].y }, |
| | | { x: delEle.location[0].x, y: delEle.location[0].y }, |
| | | ]; |
| | | break; |
| | | } |
| | | this.clickSelect(); |
| | |
| | | type: this.delCursor.type, |
| | | src: this.c.toDataURL("image/png"), |
| | | index: this.delCursor.index, |
| | | deleteLength: 1, // 编辑的话deleteLength为1 |
| | | data: delEle |
| | | deleteLength: 1, // 编辑的话deleteLength为1 |
| | | data: delEle, |
| | | }); |
| | | this.editObj = { |
| | | id: this.delCursor.id, |
| | | type: this.delCursor.type, |
| | | index: this.delCursor.index, |
| | | remarksName: this.delCursor.remarksName |
| | | } |
| | | this.disabledOthers(this.delCursor.type) |
| | | remarksName: this.delCursor.remarksName, |
| | | }; |
| | | this.disabledOthers(this.delCursor.type); |
| | | // 切换当前状态 |
| | | this.changeType(this.delCursor.type) |
| | | this.changeType(this.delCursor.type); |
| | | this.$notify({ |
| | | type: "warning", |
| | | message: "已擦除旧的区域,请直接绘制区域" |
| | | }) |
| | | message: "已擦除旧的区域,请直接绘制区域", |
| | | }); |
| | | }, |
| | | // 点击选中变色 将当前页面所有路径重绘判断当前鼠标的坐标在哪个图形内 如果不传坐标参数就是回显的方法 |
| | | clickSelect(e) { |
| | |
| | | v.location[1].x, |
| | | v.location[1].y, |
| | | 20, |
| | | _this.twoPointDistance({ x: v.location[0].x, y: v.location[0].y }, { x: v.location[1].x, y: v.location[1].y }) * 0.1, |
| | | _this.twoPointDistance( |
| | | { x: v.location[0].x, y: v.location[0].y }, |
| | | { x: v.location[1].x, y: v.location[1].y } |
| | | ) * 0.1, |
| | | 2, |
| | | "yellow" |
| | | ); // 绘制方法 |
| | |
| | | v.location[1].x, |
| | | v.location[1].y, |
| | | 20, |
| | | _this.twoPointDistance({ x: v.location[0].x, y: v.location[0].y }, { x: v.location[1].x, y: v.location[1].y }) * 0.1, |
| | | _this.twoPointDistance( |
| | | { x: v.location[0].x, y: v.location[0].y }, |
| | | { x: v.location[1].x, y: v.location[1].y } |
| | | ) * 0.1, |
| | | 2, |
| | | "red" |
| | | ); // 绘制方法 |
| | |
| | | } |
| | | _this.ctx.closePath(); |
| | | _this.ctx.stroke(); |
| | | _this.showRemarks( |
| | | v.location[0].x, |
| | | v.location[0].y, |
| | | v.name, |
| | | false |
| | | ); |
| | | _this.showRemarks(v.location[0].x, v.location[0].y, v.name, false); |
| | | _this.c.style.cursor = "pointer"; |
| | | if (e && _this.minDistance(e.offsetX, e.offsetY, v.location, 10)) { |
| | | // 如果传入了事件坐标,就用isPointInStroke判断一下 |
| | |
| | | } |
| | | _this.ctx.closePath(); |
| | | _this.ctx.stroke(); |
| | | _this.showRemarks( |
| | | v.location[0].x, |
| | | v.location[0].y, |
| | | v.name, |
| | | true |
| | | ); |
| | | _this.showRemarks(v.location[0].x, v.location[0].y, v.name, true); |
| | | _this.c.style.cursor = "pointer"; |
| | | } |
| | | } |
| | |
| | | }, |
| | | // 撤销 |
| | | undo() { |
| | | console.log(this.canvasHistory); |
| | | console.log(this.step); |
| | | if (this.type === "5" && this.flag) { |
| | | // 正在画多边形,暂存数组里有坐标数据,可一步一步撤销 |
| | | if (this.points.length > 0) { |
| | |
| | | } |
| | | } else { |
| | | // 多边形已经完成或者是在画别的图形 |
| | | if (this.step >= 0) { |
| | | if (this.step > 0) { |
| | | if (this.canvasHistory[this.step].data !== undefined) { |
| | | // 编辑删除步骤的撤销 之前删除的数据原路塞回去 |
| | | switch (this.canvasHistory[this.step].type) { |
| | |
| | | // 修改图形备注的撤销 |
| | | switch (this.canvasHistory[this.step].type) { |
| | | case "1": |
| | | this.canvasData.line[ |
| | | this.canvasHistory[this.step].index |
| | | ].name = this.canvasHistory[this.step].name; |
| | | this.canvasData.line[this.canvasHistory[this.step].index].name = |
| | | this.canvasHistory[this.step].name; |
| | | break; |
| | | case "2": |
| | | this.canvasData.rect[ |
| | | this.canvasHistory[this.step].index |
| | | ].name = this.canvasHistory[this.step].name; |
| | | this.canvasData.rect[this.canvasHistory[this.step].index].name = |
| | | this.canvasHistory[this.step].name; |
| | | break; |
| | | case "4": |
| | | this.canvasData.arrow[ |
| | |
| | | this.step--; |
| | | } else { |
| | | // 正常的撤销 |
| | | console.log("正常的撤销"); |
| | | this.ctx.clearRect(0, 0, this.c.width, this.c.height); |
| | | let canvasPic = new Image(); |
| | | if (this.step > 0) { |
| | |
| | | canvasPic.addEventListener("load", function () { |
| | | ctx.drawImage(canvasPic, 0, 0); |
| | | }); |
| | | console.log("清除"); |
| | | |
| | | // 撤销最终数据 |
| | | switch (this.canvasHistory[this.step].type) { |
| | | case "1": |
| | | case 1: |
| | | console.log("清除线"); |
| | | this.canvasData.line.pop(); |
| | | break; |
| | | case 2: |
| | |
| | | } else { |
| | | this.$notify({ |
| | | type: "warning", |
| | | message: "不能再继续撤销了" |
| | | message: "不能再继续撤销了", |
| | | }); |
| | | } |
| | | } |
| | | // console.log("撤销!",this.canvasData); |
| | | }, |
| | | disabledOthers(type) { |
| | | console.log("当前type:", type) |
| | | console.log("当前type:", type); |
| | | switch (type) { |
| | | case "1": |
| | | this.disableLine = false |
| | | this.disableRect = true |
| | | this.disableArrow = true |
| | | this.disablePolygon = true |
| | | this.disableSelect = true |
| | | break |
| | | this.disableLine = false; |
| | | this.disableRect = true; |
| | | this.disableArrow = true; |
| | | this.disablePolygon = true; |
| | | this.disableSelect = true; |
| | | break; |
| | | case "2": |
| | | this.disableLine = true |
| | | this.disableRect = false |
| | | this.disableArrow = true |
| | | this.disablePolygon = true |
| | | this.disableSelect = true |
| | | break |
| | | this.disableLine = true; |
| | | this.disableRect = false; |
| | | this.disableArrow = true; |
| | | this.disablePolygon = true; |
| | | this.disableSelect = true; |
| | | break; |
| | | case "4": |
| | | this.disableLine = true |
| | | this.disableRect = true |
| | | this.disableArrow = false |
| | | this.disablePolygon = true |
| | | this.disableSelect = true |
| | | break |
| | | this.disableLine = true; |
| | | this.disableRect = true; |
| | | this.disableArrow = false; |
| | | this.disablePolygon = true; |
| | | this.disableSelect = true; |
| | | break; |
| | | case "5": |
| | | this.disableLine = true |
| | | this.disableRect = true |
| | | this.disableArrow = true |
| | | this.disablePolygon = false |
| | | this.disableSelect = true |
| | | break |
| | | this.disableLine = true; |
| | | this.disableRect = true; |
| | | this.disableArrow = true; |
| | | this.disablePolygon = false; |
| | | this.disableSelect = true; |
| | | break; |
| | | } |
| | | console.log("禁用直线:", this.disableLine) |
| | | console.log("禁用矩形:", this.disableRect) |
| | | console.log("禁用箭头:", this.disableArrow) |
| | | console.log("禁用多边形:", this.disablePolygon) |
| | | console.log("禁用直线:", this.disableLine); |
| | | console.log("禁用矩形:", this.disableRect); |
| | | console.log("禁用箭头:", this.disableArrow); |
| | | console.log("禁用多边形:", this.disablePolygon); |
| | | }, |
| | | undisabled() { |
| | | this.disableLine = false |
| | | this.disableRect = false |
| | | this.disableArrow = false |
| | | this.disablePolygon = false |
| | | this.disableSelect = false |
| | | this.disableLine = false; |
| | | this.disableRect = false; |
| | | this.disableArrow = false; |
| | | this.disablePolygon = false; |
| | | this.disableSelect = false; |
| | | }, |
| | | // 刷新底图 |
| | | refresh() { |
| | |
| | | width = typeof width !== "undefined" ? width : 1; |
| | | // color = typeof color !== 'undefined' ? color : 'yellow' |
| | | // 计算各角度和对应的P2,P3坐标 |
| | | debugger |
| | | |
| | | let angle = (Math.atan2(fromY - toY, fromX - toX) * 180) / Math.PI; |
| | | let angle1 = ((angle + theta) * Math.PI) / 180; |
| | | let angle2 = ((angle - theta) * Math.PI) / 180; |
| | |
| | | let bbox = c.getBoundingClientRect(); |
| | | return { |
| | | x: (x - bbox.left) * (c.width / bbox.width), |
| | | y: (y - bbox.top) * (c.height / bbox.height) |
| | | y: (y - bbox.top) * (c.height / bbox.height), |
| | | /* |
| | | * 此处不用下面两行是为了防止使用CSS和JS改变了canvas的高宽之后是表面积拉大而实际 |
| | | * 显示像素不变而造成的坐标获取不准的情况 |
| | |
| | | }, |
| | | // 切换画线类型 |
| | | changeType(num) { |
| | | if (num === '0') { |
| | | if (num === "0") { |
| | | this.c.style.cursor = "pointer"; |
| | | } else { |
| | | this.c.style.cursor = "crosshair" |
| | | this.c.style.cursor = "crosshair"; |
| | | } |
| | | this.type = num; |
| | | }, |
| | |
| | | e.offsetX, |
| | | e.offsetY, |
| | | 20, |
| | | this.twoPointDistance({ x: this.originX, y: this.originY }, { x: e.offsetX, y: e.offsetY }) * 0.1, |
| | | this.twoPointDistance( |
| | | { x: this.originX, y: this.originY }, |
| | | { x: e.offsetX, y: e.offsetY } |
| | | ) * 0.1, |
| | | 2, |
| | | "yellow" |
| | | ); // 绘制方法 |
| | | } |
| | | }, |
| | | twoPointDistance(p1, p2) { |
| | | let dep = Math.sqrt(Math.pow((p1.x - p2.x), 2) + Math.pow((p1.y - p2.y), 2)); |
| | | let dep = Math.sqrt(Math.pow(p1.x - p2.x, 2) + Math.pow(p1.y - p2.y, 2)); |
| | | return dep; |
| | | }, |
| | | // 画多边形移动函数 |
| | |
| | | this.loadImage(); |
| | | this.pointsUndo = this.points.concat({ |
| | | x: e.offsetX, |
| | | y: e.offsetY |
| | | y: e.offsetY, |
| | | }); |
| | | this.drawPolygonUtil( |
| | | this.points.concat({ |
| | | // concat返回连接后的数组,原数组不变,相当于把移动的坐标作为一个虚假的坐标追加在后面,绝! |
| | | x: e.offsetX, |
| | | y: e.offsetY |
| | | y: e.offsetY, |
| | | }) |
| | | ); |
| | | } |
| | |
| | | return; |
| | | } |
| | | this.flag = false; |
| | | let Id |
| | | let fileName |
| | | let Id; |
| | | let fileName; |
| | | let coordinate = []; |
| | | coordinate.push({ |
| | | x: this.originX, |
| | | y: this.originY |
| | | y: this.originY, |
| | | }); |
| | | coordinate.push({ |
| | | x: e.offsetX, |
| | | y: e.offsetY |
| | | y: e.offsetY, |
| | | }); |
| | | // console.log("line的editObj:",this.editObj) |
| | | if (this.editObj.id == undefined) { |
| | | Id = this.getUuid() |
| | | Id = this.getUuid(); |
| | | fileName = this.remarks(this.originX, this.originY, "1"); |
| | | this.canvasData.line.push({ |
| | | id: Id, |
| | | name: fileName, |
| | | location: coordinate |
| | | location: coordinate, |
| | | }); |
| | | } else { |
| | | Id = this.editObj.id |
| | | fileName = this.editObj.remarksName |
| | | Id = this.editObj.id; |
| | | fileName = this.editObj.remarksName; |
| | | this.canvasData.line.splice(this.delCursor.index, 1, { |
| | | id: Id, |
| | | name: fileName, |
| | | location: coordinate |
| | | location: coordinate, |
| | | }); |
| | | } |
| | | this.clickSelect() |
| | | this.undisabled() |
| | | this.c.style.cursor = "crosshair" |
| | | this.clickSelect(); |
| | | this.undisabled(); |
| | | this.c.style.cursor = "crosshair"; |
| | | // 将当前刚画完的图形加入删改游标,可以将刚画完的图形名称显示在左上角 |
| | | this.delCursor = { |
| | | id: this.getUuid(), |
| | | remarksName: fileName, |
| | | type: "1", |
| | | index: this.lineIndex - 1 |
| | | index: this.lineIndex - 1, |
| | | }; |
| | | this.url = this.c.toDataURL(); // 每次 mouseup 都保存一次画布状态 |
| | | this.step++; |
| | | this.canvasHistory.length = this.step; // 截断数组 |
| | | this.canvasHistory.push({ type: 1, src: this.c.toDataURL("image/png") }); // 将快照保存到历史记录中以供撤销之用 |
| | | // this.changeType('0') |
| | | this.freedEdit() |
| | | this.freedEdit(); |
| | | }, |
| | | // 画矩形抬起 |
| | | rectMouseUp(e) { |
| | |
| | | // 逆时针算出矩形四角坐标 |
| | | coordinate.push({ |
| | | x: this.originX, |
| | | y: this.originY |
| | | y: this.originY, |
| | | }); |
| | | coordinate.push({ |
| | | x: this.originX, |
| | | y: e.offsetY |
| | | y: e.offsetY, |
| | | }); |
| | | coordinate.push({ |
| | | x: e.offsetX, |
| | | y: e.offsetY |
| | | y: e.offsetY, |
| | | }); |
| | | coordinate.push({ |
| | | x: e.offsetX, |
| | | y: this.originY |
| | | y: this.originY, |
| | | }); |
| | | let Id |
| | | let fileName |
| | | let Id; |
| | | let fileName; |
| | | // console.log("rect的editObj:",this.editObj) |
| | | if (this.editObj.id == undefined) { |
| | | Id = this.getUuid() |
| | | Id = this.getUuid(); |
| | | fileName = this.remarks(this.originX, this.originY, "2"); |
| | | this.canvasData.rect.push({ |
| | | id: Id, |
| | | name: fileName, |
| | | location: coordinate |
| | | location: coordinate, |
| | | }); |
| | | } else { |
| | | Id = this.editObj.id |
| | | fileName = this.editObj.remarksName |
| | | Id = this.editObj.id; |
| | | fileName = this.editObj.remarksName; |
| | | |
| | | this.canvasData.rect.splice(this.delCursor.index, 1, { |
| | | id: Id, |
| | | name: fileName, |
| | | location: coordinate |
| | | location: coordinate, |
| | | }); |
| | | } |
| | | this.clickSelect() |
| | | this.undisabled() |
| | | this.c.style.cursor = "crosshair" |
| | | this.clickSelect(); |
| | | this.undisabled(); |
| | | this.c.style.cursor = "crosshair"; |
| | | this.delCursor = { |
| | | id: Id, |
| | | remarksName: fileName, |
| | | type: "2", |
| | | index: this.rectIndex - 1 |
| | | index: this.rectIndex - 1, |
| | | }; |
| | | // console.log("刚画完的矩形标志:",this.delCursor) |
| | | this.url = this.c.toDataURL(); // 每次 mouseup 都保存一次画布状态 |
| | |
| | | this.canvasHistory.length = this.step; // 截断数组 |
| | | this.canvasHistory.push({ type: 2, src: this.c.toDataURL("image/png") }); // 将快照保存到历史记录中以供撤销之用 |
| | | |
| | | this.freedEdit() |
| | | this.freedEdit(); |
| | | }, |
| | | // 画箭头时抬起 |
| | | arrowMouseUp(e) { |
| | |
| | | return; |
| | | } |
| | | this.flag = false; |
| | | let Id |
| | | let fileName |
| | | let Id; |
| | | let fileName; |
| | | let coordinate = []; |
| | | coordinate.push({ |
| | | x: this.originX, |
| | | y: this.originY |
| | | y: this.originY, |
| | | }); |
| | | coordinate.push({ |
| | | x: e.offsetX, |
| | | y: e.offsetY |
| | | y: e.offsetY, |
| | | }); |
| | | // console.log("arrow的editObj:",this.editObj) |
| | | if (this.editObj.id == undefined) { |
| | | Id = this.getUuid() |
| | | Id = this.getUuid(); |
| | | fileName = this.remarks(this.originX, this.originY, "4"); |
| | | this.canvasData.arrow.push({ |
| | | id: Id, |
| | | name: fileName, |
| | | location: coordinate |
| | | location: coordinate, |
| | | }); |
| | | } else { |
| | | Id = this.editObj.id |
| | | fileName = this.editObj.remarksName |
| | | Id = this.editObj.id; |
| | | fileName = this.editObj.remarksName; |
| | | this.canvasData.arrow.splice(this.delCursor.index, 1, { |
| | | id: Id, |
| | | name: fileName, |
| | | location: coordinate |
| | | location: coordinate, |
| | | }); |
| | | } |
| | | this.clickSelect() |
| | | this.undisabled() |
| | | this.c.style.cursor = "crosshair" |
| | | this.clickSelect(); |
| | | this.undisabled(); |
| | | this.c.style.cursor = "crosshair"; |
| | | // 将当前刚画完的图形加入删改游标,可以将刚画完的图形名称显示在左上角 |
| | | this.delCursor = { |
| | | id: this.getUuid(), |
| | | remarksName: fileName, |
| | | type: "4", |
| | | index: this.arrowIndex - 1 |
| | | index: this.arrowIndex - 1, |
| | | }; |
| | | this.url = this.c.toDataURL(); // 每次 mouseup 都保存一次画布状态 |
| | | this.step++; |
| | | this.canvasHistory.length = this.step; // 截断数组 |
| | | this.canvasHistory.push({ type: 4, src: this.c.toDataURL("image/png") }); // 将快照保存到历史记录中以供撤销之用 |
| | | // this.changeType('0') |
| | | this.freedEdit() |
| | | this.freedEdit(); |
| | | }, |
| | | // 画多边形结束时双击 |
| | | polygonDblclick(e) { |
| | | this.flag = false; |
| | | this.points.pop(); // 双击之后多一个点的重复坐标,需要删除 |
| | | let Id |
| | | let fileName |
| | | let Id; |
| | | let fileName; |
| | | let coordinate = []; |
| | | this.points.map((item, index) => { |
| | | coordinate.push(item); |
| | | }); |
| | | // console.log("polygon的editObj:",this.editObj) |
| | | if (this.editObj.id == undefined) { |
| | | Id = this.getUuid() |
| | | Id = this.getUuid(); |
| | | fileName = this.remarks(this.points[0].x, this.points[0].y, "5"); |
| | | this.canvasData.polygon.push({ |
| | | id: Id, |
| | | name: fileName, |
| | | location: coordinate |
| | | location: coordinate, |
| | | }); |
| | | } else { |
| | | Id = this.editObj.id |
| | | fileName = this.editObj.remarksName |
| | | Id = this.editObj.id; |
| | | fileName = this.editObj.remarksName; |
| | | this.canvasData.polygon.splice(this.delCursor.index, 1, { |
| | | id: Id, |
| | | name: fileName, |
| | | location: coordinate |
| | | location: coordinate, |
| | | }); |
| | | } |
| | | this.clickSelect() |
| | | this.undisabled() |
| | | this.clickSelect(); |
| | | this.undisabled(); |
| | | this.c.style.cursor = "crosshair"; |
| | | this.points.length = 0; |
| | | // 将当前刚画完的图形加入删改游标,可以将刚画完的图形名称显示在左上角 |
| | |
| | | id: this.getUuid(), |
| | | remarksName: fileName, |
| | | type: "5", |
| | | index: this.polygonIndex - 1 |
| | | index: this.polygonIndex - 1, |
| | | }; |
| | | this.url = this.c.toDataURL(); |
| | | this.step++; |
| | |
| | | this.canvasHistory.push({ type: 5, src: this.c.toDataURL("image/png") }); // 将快照保存到历史记录中以供撤销之用 |
| | | // this.changeType('0') |
| | | // console.log("总数据:",this.canvasData) |
| | | this.freedEdit() |
| | | this.freedEdit(); |
| | | }, |
| | | // 释放编辑状态 |
| | | freedEdit() { |
| | | this.editObj = {} |
| | | this.editObj = {}; |
| | | }, |
| | | // 回显历史数据时计算一下回显的每种元素的数量以便生成图形注解时获得正确的开头 |
| | | indexInit() { |
| | |
| | | this.arrowIndex = this.canvasData.arrow.length; |
| | | //排除this.canvasData.polygon全部区域(全部区域的id就是摄像机的id) |
| | | |
| | | let filterPolygonArr = this.canvasData.polygon.filter(item=>item.id != this.TreeDataPool.selectedNode.id) |
| | | let filterPolygonArr = this.canvasData.polygon.filter( |
| | | (item) => item.id != this.TreeDataPool.selectedNode.id |
| | | ); |
| | | this.polygonIndex = filterPolygonArr.length; |
| | | }, |
| | | // 生成uuid |
| | |
| | | }, |
| | | // 判断一个点是否离一个图形的最小距离为n像素以内 |
| | | minDistance(x, y, locations, n) { |
| | | let flag = false |
| | | let flag = false; |
| | | for (let i = 0; i < locations.length; i++) { |
| | | if (i == locations.length - 1) { |
| | | if (this.point2Line(x, y, locations[i].x, locations[i].y, locations[0].x, locations[0].y) < n) { |
| | | flag = true |
| | | if ( |
| | | this.point2Line( |
| | | x, |
| | | y, |
| | | locations[i].x, |
| | | locations[i].y, |
| | | locations[0].x, |
| | | locations[0].y |
| | | ) < n |
| | | ) { |
| | | flag = true; |
| | | } |
| | | } else { |
| | | if (this.point2Line(x, y, locations[i].x, locations[i].y, locations[i + 1].x, locations[i + 1].y) < n) { |
| | | flag = true |
| | | if ( |
| | | this.point2Line( |
| | | x, |
| | | y, |
| | | locations[i].x, |
| | | locations[i].y, |
| | | locations[i + 1].x, |
| | | locations[i + 1].y |
| | | ) < n |
| | | ) { |
| | | flag = true; |
| | | } |
| | | } |
| | | } |
| | | return flag |
| | | return flag; |
| | | }, |
| | | point2Line(x, y, x1, y1, x2, y2) { |
| | | let cross = (x2 - x1) * (x - x1) + (y2 - y1) * (y - y1); // |AB| * |AC|*cos(x) |
| | |
| | | return Math.sqrt((x - x2) * (x - x2) + (y - y2) * (y - y2) + 0.0); |
| | | |
| | | let r = cross / d2; |
| | | let px = x1 + (x2 - x1) * r; // C在 AB上的垂足点(px,py) |
| | | let px = x1 + (x2 - x1) * r; // C在 AB上的垂足点(px,py) |
| | | let py = y1 + (y2 - y1) * r; |
| | | return Math.sqrt((x - px) * (x - px) + (y - py) * (y - py) + 0.0); //两点间距离公式 |
| | | } |
| | | }, |
| | | }, |
| | | props: { |
| | | isGB28181: { |
| | | default: false, |
| | | type: Boolean |
| | | type: Boolean, |
| | | }, |
| | | // isShowDrawArrow: { |
| | | // default: false, |
| | |
| | | // }, |
| | | disabled: { |
| | | default: false, |
| | | type: Boolean |
| | | type: Boolean, |
| | | }, |
| | | canvasDataToChild: { |
| | | default: () => { |
| | |
| | | line: [], |
| | | rect: [], |
| | | arrow: [], |
| | | polygon: [] |
| | | polygon: [], |
| | | }; |
| | | }, |
| | | type: Object |
| | | type: Object, |
| | | }, |
| | | snapshot_url: { |
| | | type: String, |
| | | default: "" |
| | | } |
| | | } |
| | | default: "", |
| | | }, |
| | | }, |
| | | }; |
| | | </script> |
| | | <style lang="scss" scoped> |