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

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

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

瀏覽:5日期: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
相關文章:
主站蜘蛛池模板: 噪声治理公司-噪音治理专业隔音降噪公司 | ◆大型吹塑加工|吹塑加工|吹塑代加工|吹塑加工厂|吹塑设备|滚塑加工|滚塑代加工-莱力奇塑业有限公司 | 金属切削液-脱水防锈油-电火花机油-抗磨液压油-深圳市雨辰宏业科技发展有限公司 | 北京百度网站优化|北京网站建设公司-百谷网络科技 | 技德应用| 山东限矩型液力偶合器_液力耦合器易熔塞厂家-淄博市汇川源机械厂 | 衢州装饰公司|装潢公司|办公楼装修|排屋装修|别墅装修-衢州佳盛装饰 | 电子万能试验机_液压拉力试验机_冲击疲劳试验机_材料试验机厂家-济南众标仪器设备有限公司 | 365文案网_全网创意文案句子素材站 | T恤衫定做,企业文化衫制作订做,广告T恤POLO衫定制厂家[源头工厂]-【汉诚T恤定制网】 | 仿古瓦,仿古金属瓦,铝瓦,铜瓦,铝合金瓦-西安东申景观艺术工程有限公司 | 全自动在线分板机_铣刀式在线分板机_曲线分板机_PCB分板机-东莞市亿协自动化设备有限公司 | 济南品牌包装设计公司_济南VI标志设计公司_山东锐尚文化传播 | EDLC超级法拉电容器_LIC锂离子超级电容_超级电容模组_软包单体电容电池_轴向薄膜电力电容器_深圳佳名兴电容有限公司_JMX专注中高端品牌电容生产厂家 | 国产频谱分析仪-国产网络分析仪-上海坚融实业有限公司 | 澳门精准正版免费大全,2025新澳门全年免费,新澳天天开奖免费资料大全最新,新澳2025今晚开奖资料,新澳马今天最快最新图库-首页-东莞市傲马网络科技有限公司 | 粉末冶金-粉末冶金齿轮-粉末冶金零件厂家-东莞市正朗精密金属零件有限公司 | 南京种植牙医院【官方挂号】_南京治疗种植牙医院那个好_南京看种植牙哪里好_南京茀莱堡口腔医院 尼龙PA610树脂,尼龙PA612树脂,尼龙PA1010树脂,透明尼龙-谷骐科技【官网】 | 智能交通网_智能交通系统_ITS_交通监控_卫星导航_智能交通行业 | 翅片管换热器「型号全」_厂家-淄博鑫科环保 | 小青瓦丨古建筑瓦丨青瓦厂家-宜兴市徽派古典建筑材料有限公司 | 无锡市珂妮日用化妆品有限公司|珂妮日化官网|洗手液厂家 | 胶辊硫化罐_胶鞋硫化罐_硫化罐厂家-山东鑫泰鑫智能装备有限公司 意大利Frascold/富士豪压缩机_富士豪半封闭压缩机_富士豪活塞压缩机_富士豪螺杆压缩机 | TPM咨询,精益生产管理,5S,6S现场管理培训_华谋咨询公司 | 陕西安闸机-伸缩门-车牌识别-广告道闸——捷申达门业科技 | 碳化硅,氮化硅,冰晶石,绢云母,氟化铝,白刚玉,棕刚玉,石墨,铝粉,铁粉,金属硅粉,金属铝粉,氧化铝粉,硅微粉,蓝晶石,红柱石,莫来石,粉煤灰,三聚磷酸钠,六偏磷酸钠,硫酸镁-皓泉新材料 | 水质传感器_水质监测站_雨量监测站_水文监测站-山东水境传感科技有限公司 | 山东PE给水管厂家,山东双壁波纹管,山东钢带增强波纹管,山东PE穿线管,山东PE农田灌溉管,山东MPP电力保护套管-山东德诺塑业有限公司 | 制氮设备_PSA制氮机_激光切割制氮机_氮气机生产厂家-苏州西斯气体设备有限公司 | SDI车窗夹力测试仪-KEMKRAFT方向盘测试仪-上海爱泽工业设备有限公司 | 酒糟烘干机-豆渣烘干机-薯渣烘干机-糟渣烘干设备厂家-焦作市真节能环保设备科技有限公司 | 视觉检测设备_自动化检测设备_CCD视觉检测机_外观缺陷检测-瑞智光电 | 塑料异型材_PVC异型材_封边条生产厂家_PC灯罩_防撞扶手_医院扶手价格_东莞市怡美塑胶制品有限公司 | LNG鹤管_内浮盘价格,上装鹤管,装车撬厂家-连云港赛威特机械 | 保健品OEM贴牌代加工厂家_德州健之源| 派财经_聚焦数字经济内容服务平台 | 工程管道/塑料管材/pvc排水管/ppr给水管/pe双壁波纹管等品牌管材批发厂家-河南洁尔康建材 | 药品冷藏箱厂家_低温冰箱_洁净工作台-济南欧莱博电子商务有限公司官网 | 锻造液压机,粉末冶金,拉伸,坩埚成型液压机定制生产厂家-山东威力重工官方网站 | ptc_浴霸_大巴_干衣机_呼吸机_毛巾架_电动车加热器-上海帕克 | 对辊破碎机-液压双辊式,强力双齿辊,四辊破碎机价格_巩义市金联机械设备生产厂家 |