电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術文章
文章詳情頁

vue實現一個矩形標記區域(rectangle marker)的方法

瀏覽:4日期:2022-11-10 16:32:06

代碼地址:vue-rectangle-marker

一、前言

一些cms系統經常會用到區域標記功能,所以寫了個用vue實現的矩形標記區域,包含拖拽、放大縮小、重置功能。

二、實現結果

1.初始

vue實現一個矩形標記區域(rectangle marker)的方法

2.標記

vue實現一個矩形標記區域(rectangle marker)的方法

三、代碼實現

<template><div class='rectangle-marker'><div class='mark-wrap'><img ref='backImg' :src='http://www.hdgsjgj.cn/bcjs/imgUrl' alt='響應式圖像' @load='onload'><div : @mousemove='mouseMove'@mousedown='mouseDown' @mouseup='mouseUp'><div ref='box' v-if='boxVisible' : class='box':style='{ width: boxW + ’px’, height: boxH + ’px’, left: boxL + ’px’, top: boxT + ’px’ }'><div @mousedown='onUpleftbtn'></div><div @mousedown='onUpRightbtn'></div><div @mousedown='onDownleftbtn'></div><div @mousedown='onDownRightbtn'></div></div></div><transition name='fade'><div v-if='showBtns && !markFlag' @mouseleave='mouseLeave'><button @click='mark'>mark</button>&nbsp;&nbsp;<button @click='reset'>reset</button></div></transition></div></div></template><script>export default {name: ’rectangleMarker’,data() {return {imgW: 0,imgH: 0,showBtns: true,markFlag: false,// 鼠標事件屬性dragging: false,startX: undefined,startY: undefined,diffX: undefined,diffY: undefined,obj: null, //當前操作對象box: null, //要處理的對象backImgRect: null,boxId: ’’,boxW: 0,boxH: 0,boxL: 0,boxT: 0,boxVisible: false}},props: {imgUrl: {type: String,required: true,default: ’’},disabled: {type: Boolean,default: false},value: {type: Array,default: function () {return []}}},methods: {onload() {let rect = this.$refs.backImg.getBoundingClientRect()this.backImgRect = {height: rect.height,width: rect.width}// console.log('initConfig -> this.backImgRect', this.backImgRect)if (this.value === ’’ || this.value === undefined || this.value === null || (Array.isArray(this.value) && this.value.length === 0)) {return}this.initData(this.value)},mouseLeave() {this.showBtns = false},mark() {this.markFlag = true},reset() {this.boxVisible = falsethis.boxId = ’’this.boxH = 0this.boxW = 0this.boxL = 0this.boxT = 0},initData(data) {if (data === ’’ || data === undefined || data === null || (Array.isArray(data) && data.length === 0)) {return}this.boxId = ’changeBox’this.boxL = data[0][0] * this.backImgRect.widththis.boxT = data[0][1] * this.backImgRect.heightthis.boxH = (data[3][1] - data[0][1]) * this.backImgRect.heightthis.boxW = (data[1][0] - data[0][0]) * this.backImgRect.widththis.boxVisible = true},mouseDown(e) {if (!this.markFlag && !this.boxVisible) {return}this.startX = e.offsetX;this.startY = e.offsetY;// 如果鼠標在 box 上被按下if (e.target.className.match(/box/)) {// 允許拖動this.dragging = true;// 設置當前 box 的 id 為 movingBoxif (this.boxId !== ’movingBox’) {this.boxId = ’movingBox’}// 計算坐標差值this.diffX = this.startXthis.diffY = this.startY} else {if (this.boxId === ’changeBox’) {return}this.boxId = ’activeBox’this.boxT = this.startYthis.boxL = this.startXthis.boxVisible = true}},mouseMove(e) {if (!this.markFlag && !this.boxVisible) {if (!this.backImgRect) {return}let toRight = this.backImgRect.width - e.offsetXlet toTop = e.offsetYif (toRight <= 100 && toTop <= 40) {this.showBtns = true}return}let toRight = this.backImgRect.width - e.offsetXlet toTop = e.offsetYif (toRight <= 100 && toTop <= 40) {this.showBtns = truereturn}// 更新 box 尺寸if (this.boxId === ’activeBox’) {this.boxW = e.offsetX - this.startXthis.boxH = e.offsetY - this.startY}// 移動,更新 box 坐標if (this.boxId === ’movingBox’ && this.dragging) {let realTop = (e.offsetY + e.target.offsetTop - this.diffY) > 0 ? (e.offsetY + e.target.offsetTop -this.diffY) : 0let realLeft = (e.offsetX + e.target.offsetLeft - this.diffX) > 0 ? (e.offsetX + e.target.offsetLeft -this.diffX) : 0let maxTop = this.backImgRect.height - this.$refs.box.offsetHeightlet maxLeft = this.backImgRect.width - this.$refs.box.offsetWidthrealTop = realTop >= maxTop ? maxTop : realToprealLeft = realLeft >= maxLeft ? maxLeft : realLeftthis.boxT = realTop;this.boxL = realLeft;}if (this.obj) {e = e || window.event;var location = {x: e.x || e.offsetX,y: e.y || e.offsetY}switch (this.obj.operateType) {case 'nw':this.move(’n’, location, this.$refs.box);this.move(’w’, location, this.$refs.box);break;case 'ne':this.move(’n’, location, this.$refs.box);this.move(’e’, location, this.$refs.box);break;case 'sw':this.move(’s’, location, this.$refs.box);this.move(’w’, location, this.$refs.box);break;case 'se':this.move(’s’, location, this.$refs.box);this.move(’e’, location, this.$refs.box);break;case 'move':this.move(’move’, location, this.box);break;}}},mouseUp() {if (!this.markFlag && !this.boxVisible) {return}// 禁止拖動this.dragging = false;if (this.boxId === ’activeBox’) {if (this.$refs.box) {this.boxId = ’changeBox’if (this.$refs.box.offsetWidth < 3 || this.$refs.box.offsetHeight < 3) {this.boxVisible = falsethis.boxId = ’’}}} else {if (this.$refs.box && this.boxId === ’movingBox’) {this.boxId = ’changeBox’if (this.$refs.box.offsetWidth < 3 || this.$refs.box.offsetHeight < 3) {this.boxVisible = falsethis.boxId = ’’}}}if (this.boxVisible) {this.getHotData()document.body.style.cursor = 'auto';this.obj = null;this.markFlag = false} else {this.markFlag = true}},getHotData() {let target = this.$refs.boxif (target) {let {offsetTop,offsetLeft} = targetlet {width: WIDTH,height: HEIGHT} = this.backImgRectlet {width,height} = target.getBoundingClientRect()// 矩形區域 角點位置(百分比)let data = [[this.toFixed6(offsetLeft, WIDTH), this.toFixed6(offsetTop, HEIGHT)],[this.toFixed6(offsetLeft + width, WIDTH), this.toFixed6(offsetTop, HEIGHT)],[this.toFixed6(offsetLeft + width, WIDTH), this.toFixed6(offsetTop + height, HEIGHT)],[this.toFixed6(offsetLeft, WIDTH), this.toFixed6(offsetTop + height, HEIGHT)]]// 矩形中點let centerPoint = [this.toFixed6(offsetLeft + 0.5 * width, WIDTH),this.toFixed6(offsetTop + 0.5 * height, HEIGHT)]let hotData = {data,centerPoint}console.log('getHotData -> hotData', hotData)console.log(JSON.stringify(hotData));}},toFixed6(v1, v2) {return (v1 / v2).toFixed(6)},move(type, location, tarobj) {switch (type) {case ’n’: {let add_length = this.clickY - location.y;this.clickY = location.y;let length = parseInt(tarobj.style.height) + add_length;tarobj.style.height = length + 'px';let realTop = this.clickY > 0 ? this.clickY : 0let maxTop = this.backImgRect.height - parseInt(tarobj.style.height)realTop = realTop >= maxTop ? maxTop : realToptarobj.style.top = realTop + 'px';break;}case ’s’: {let add_length = this.clickY - location.y;this.clickY = location.y;let length = parseInt(tarobj.style.height) - add_length;let maxHeight = this.backImgRect.height - parseInt(tarobj.style.top)let realHeight = length > maxHeight ? maxHeight : lengthtarobj.style.height = realHeight + 'px';break;}case ’w’: {var add_length = this.clickX - location.x;this.clickX = location.x;let length = parseInt(tarobj.style.width) + add_length;tarobj.style.width = length + 'px';let realLeft = this.clickX > 0 ? this.clickX : 0let maxLeft = this.backImgRect.width - parseInt(tarobj.style.width)realLeft = realLeft >= maxLeft ? maxLeft : realLefttarobj.style.left = realLeft + 'px';break;}case ’e’: {let add_length = this.clickX - location.x;this.clickX = location.x;let length = parseInt(tarobj.style.width) - add_length;let maxWidth = this.backImgRect.width - parseInt(tarobj.style.left)let realWidth = length > maxWidth ? maxWidth : lengthtarobj.style.width = realWidth + 'px';break;}}},onUpleftbtn(e) {e.stopPropagation();this.onDragDown(e, 'nw');},onUpRightbtn(e) {e.stopPropagation();this.onDragDown(e, 'ne');},onDownleftbtn(e) {e.stopPropagation();this.onDragDown(e, 'sw');},onDownRightbtn(e) {e.stopPropagation();this.onDragDown(e, 'se');},onDragDown(e, type) {e = e || window.event;this.clickX = e.x || e.offsetX;this.clickY = e.y || e.offsetY;this.obj = window;this.obj.operateType = type;this.box = this.$refs.box;return false;}},}</script><style lang='less' scoped>.rectangle-marker {width: 100%;height: 100%;display: flex;flex-direction: column;align-items: center;.mark-wrap {position: relative;.img-responsive {display: inline-block;max-width: 100%;max-height: 100%;}.draw-rect {position: absolute;top: 0;left: 0;bottom: 0;right: 0;width: 100%;height: 100%;z-index: 99;user-select: none;&.no-event {pointer-events: none;}}}.act-box {margin-top: 10px;display: flex;}.act-btns {position: absolute;right: 0;top: 0;z-index: 199;padding: 0 10px;height: 40px;width: 100px;display: flex;align-items: center;justify-content: center;}.fade-enter-active {animation: hide-and-show .5s;}.fade-leave-active {animation: hide-and-show .5s reverse;}@keyframes hide-and-show {0% {opacity: 0;}100% {opacity: 1;}}}</style><style lang='less'>.rectangle-marker {.box {position: absolute;width: 0px;height: 0px;opacity: 0.5;z-index: 149;cursor: move;border: 1px solid #f00;.upleftbtn,.uprightbtn,.downleftbtn,.downrightbtn {width: 10px;height: 10px;border: 1px solid steelblue;position: absolute;z-index: 5;background: whitesmoke;border-radius: 10px;}.upleftbtn {top: -5px;left: -5px;cursor: nw-resize;}.uprightbtn {top: -5px;right: -5px;cursor: ne-resize;}.downleftbtn {left: -5px;bottom: -5px;cursor: sw-resize;}.downrightbtn {right: -5px;bottom: -5px;cursor: se-resize;}}}</style> 背景圖傳入,圖片自適應處理。 定義drag標記為,添加開始標記、重置按鈕。 創建box區域,不同狀態(change、moving、active),對應不同id。 box可移動距離,計算邊界。 四角放大縮小的功能。 生成結果,精確到6位小數,這樣可以使得復原標記區域的時候誤差最小。

四、覺得有幫助的,麻煩給個贊哦,謝謝!

以上就是vue實現一個矩形標記區域(rectangle marker)的方法的詳細內容,更多關于vue實現矩形標記區域的資料請關注好吧啦網其它相關文章!

標簽: Vue
相關文章:
主站蜘蛛池模板: 物联网卡_物联网卡购买平台_移动物联网卡办理_移动联通电信流量卡通信模组采购平台? | 石栏杆_青石栏杆_汉白玉栏杆_花岗岩栏杆 - 【石雕之乡】点石石雕石材厂 | 中开泵,中开泵厂家,双吸中开泵-山东博二泵业有限公司 | 科昊仪器超纯水机系统-可成气相液氮罐-美菱超低温冰箱-西安昊兴生物科技有限公司 | 大行程影像测量仪-探针型影像测量仪-增强型影像测量仪|首丰百科 大通天成企业资质代办_承装修试电力设施许可证_增值电信业务经营许可证_无人机运营合格证_广播电视节目制作许可证 | 超声波电磁流量计-液位计-孔板流量计-料位计-江苏信仪自动化仪表有限公司 | 综合管廊模具_生态,阶梯护坡模具_检查井模具制造-致宏模具厂家 | 西门子伺服控制器维修-伺服驱动放大器-828D数控机床维修-上海涌迪 | 济宁工业提升门|济宁电动防火门|济宁快速堆积门-济宁市统一电动门有限公司 | 焊接减速机箱体,减速机箱体加工-淄博博山泽坤机械厂 | LHH药品稳定性试验箱-BPS系列恒温恒湿箱-意大利超低温冰箱-上海一恒科学仪器有限公司 | 密度电子天平-内校-外校电子天平-沈阳龙腾电子有限公司 | 定制异形重型钢格栅板/钢格板_定做踏步板/排水沟盖板_钢格栅板批发厂家-河北圣墨金属制品有限公司 | 防爆电机_防爆电机型号_河南省南洋防爆电机有限公司 | 山东太阳能路灯厂家-庭院灯生产厂家-济南晟启灯饰有限公司 | 航空障碍灯_高中低光强航空障碍灯_民航许可认证航空警示灯厂家-东莞市天翔航天科技有限公司 | 游泳池设备安装工程_恒温泳池设备_儿童游泳池设备厂家_游泳池水处理设备-东莞市君达泳池设备有限公司 | 亿诺千企网-企业核心产品贸易 | TPU薄膜_TPU薄膜生产厂家_TPU热熔胶膜厂家定制_鑫亘环保科技(深圳)有限公司 | 并离网逆变器_高频UPS电源定制_户用储能光伏逆变器厂家-深圳市索克新能源 | 菏泽知彼网络科技有限公司 | 企业彩铃制作_移动、联通、电信集团彩铃上传开通_彩铃定制_商务彩铃管理平台-集团彩铃网 | 排烟防火阀-消防排烟风机-正压送风口-厂家-价格-哪家好-德州鑫港旺通风设备有限公司 | 展厅设计公司,展厅公司,展厅设计,展厅施工,展厅装修,企业展厅,展馆设计公司-深圳广州展厅设计公司 | 插针变压器-家用电器变压器-工业空调变压器-CD型电抗器-余姚市中驰电器有限公司 | 嘉兴恒升声级计-湖南衡仪声级计-杭州爱华多功能声级计-上海邦沃仪器设备有限公司 | 达利园物流科技集团- | 防弹玻璃厂家_防爆炸玻璃_电磁屏蔽玻璃-四川大硅特玻科技有限公司 | 农产品溯源系统_农产品质量安全追溯系统_溯源系统 | 螺纹三通快插接头-弯通快插接头-宁波舜驰气动科技有限公司 | 冷却塔厂家_冷却塔维修_冷却塔改造_凉水塔配件填料公司- 广东康明节能空调有限公司 | ★济南领跃标识制作公司★济南标识制作,标牌制作,山东标识制作,济南标牌厂 | 真石漆,山东真石漆,真石漆厂家,真石漆价格-山东新佳涂料有限公司 | 磁棒电感生产厂家-电感器厂家-电感定制-贴片功率电感供应商-棒形电感生产厂家-苏州谷景电子有限公司 | 深圳展厅设计_企业展馆设计_展厅设计公司_数字展厅设计_深圳百艺堂 | 济南ISO9000认证咨询代理公司,ISO9001认证,CMA实验室认证,ISO/TS16949认证,服务体系认证,资产管理体系认证,SC食品生产许可证- 济南创远企业管理咨询有限公司 郑州电线电缆厂家-防火|低压|低烟无卤电缆-河南明星电缆 | 防潮防水通风密闭门源头实力厂家 - 北京酷思帝克门窗 | 喷码机,激光喷码打码机,鸡蛋打码机,手持打码机,自动喷码机,一物一码防伪溯源-恒欣瑞达有限公司 | 喷涂流水线,涂装流水线,喷漆流水线-山东天意设备科技有限公司 | 列管冷凝器,刮板蒸发器,外盘管反应釜厂家-无锡曼旺化工设备有限公司 | 免联考国际MBA_在职MBA报考条件/科目/排名-MBA信息网 |