救星来了前端标注工具 实现图片 图像标注 多边形 矩形 画笔 缩放 线段 等功能 的插件 AILabel.js

您所在的位置:网站首页 图片上箭头标注 救星来了前端标注工具 实现图片 图像标注 多边形 矩形 画笔 缩放 线段 等功能 的插件 AILabel.js

救星来了前端标注工具 实现图片 图像标注 多边形 矩形 画笔 缩放 线段 等功能 的插件 AILabel.js

2024-06-05 22:21| 来源: 网络整理| 查看: 265

备注:久等了(https://gitee.com/liangliang39/imagelabel.git) 一、网址以及demo(请以最新demo实例为准,因版本写法可能有出入)

官方文档:http://ailabel.com.cn/public/ailabel/api/index.html#1 demo地址1: http://ailabel.com.cn/public/ailabel/demo/label/index.html demo地址2: http://ailabel.com.cn/public/ailabel/demo/index.html

二、我的实例代码(vue环境下)

请添加图片描述

三、如有不懂的添加官方qq群向大佬请教(378301400) 新建样本集 样本集 3 标注 样本量 {{item.title}} {{item.percentage}} {{item.number}} 样本集:绝缘子缺陷 训练集 Insulator / Images / 50000 张 标注完成度 75% 标注 训练集 Insulator / Images / 50000 张 标注完成度 75% 标注 训练集 Insulator / Images / 50000 张 标注完成度 75% 标注 添加样本 重新配置 删除此样本 训练集 标注进度:1,029 / 5,000 当前样本: img_2389.png 样本信息:img_2389.png Width:1200px Height:678px 标签:1 清除标注 完成 +放大 -缩小 涂抹 擦除 注记 清除图层 添加图层 刷新图层 添加图形 {{curtext}} import { mapGetters, mapState } from "vuex"; import getListMixin from '@/mixins/getlist'; // 列表元素 import { debounce } from "@/utils/index"; // 引入防抖函数 import Breadcrumb from '@/components/Breadcrumb'; //路由导航 import AILabel from 'ailabel'; let that; let drawingStyle; // 绘制样式 let gMap; // 标注容器 let Mode = ''; // 默认绘制类型 let gImageLayer; // 图片绘制 let gFirstFeatureLayer; // 实例化 let gFirstMaskLayer; // 涂抹层 let gFirstTextLayer; // 文本层 let targetMarker; // 更新视图 let targetText; // 更新标签 let gFirstMarker; // 标注 export default { name: "Dashboard", mixins:[getListMixin], data() { return { searchval: "", // 搜索输入值 currindex:0, // 默认选中项 list: [{ title: '样本集1', percentage: '80%', number: 1518, color: 1, }, { title: '样本集2', percentage: '80%', number: 1517, color: 2, }, { title: '样本集3', percentage: '80%', number: 1516, color: 3, },{ title: '样本集4', percentage: '80%', number: 1515, color: 3, },{ title: '样本集5', percentage: '60%', number: 1514, color: 3, },{ title: '样本集6', percentage: '60%', number: 1514, color: 3, },{ title: '样本集7', percentage: '60%', number: 1513, color: 3, },{ title: '样本集8', percentage: '60%', number: 1519, color: 3, },{ title: '样本集9', percentage: '60%', number: 1514, color: 3, },{ title: '样本集10', percentage: '60%', number: 1519, color: 3, },{ title: '样本集11', percentage: '60%', number: 1519, color: 3, },{ title: '样本集12', percentage: '60%', number: 1519, color: 3, },{ title: '样本集13', percentage: '60%', number: 1514, color: 3, },{ title: '样本集14', percentage: '60%', number: 1519, color: 3, },{ title: '样本集15', percentage: '60%', number: 1515, color: 3, }], // 数据列表 options: [{ value: '黄金糕', label: '黄金糕', color: 'red' }, { value: '双皮奶', label: '双皮奶', color: 'white' }, { value: '蚵仔煎', label: '蚵仔煎', color: 'green' }, { value: '龙须面', label: '龙须面', color: 'pink' }, { value: '北京烤鸭', label: '北京烤鸭', color: 'blue' }], value: '黄金糕', // 当前选择框值 imglist:[ { url: require('../../assets/images/ai_bj1.png'), name:"ai_bj1" }, { url: require('../../assets/images/ai_bj2.png'), name:"ai_bj2" }, { url: require('../../assets/images/ai_bj3.png'),name:"ai_bj3" }, { url: require('../../assets/images/ai_img1.png'),name:"ai_bj3" }, { url: require('../../assets/images/ai_bj1.png'), name:"ai_bj1" }, { url: require('../../assets/images/ai_bj2.png'), name:"ai_bj2" }, { url: require('../../assets/images/ai_bj3.png'),name:"ai_bj3" }, ], // 素材列表 curimg:'', // 当前大图 url或base64 timer: null, // 延时定时器 animate: false, // 轮播是否开启动画 duration: 1000, // 轮播动画延时 type:1, // 轮播方向 centerindex:2, // 轮播中间值 flagswitch:true, // 标注开关 rleData:[], // 最终图像标记 curMode:1, // 当前图形类型 curtext:'', }; }, created() { // this.timer = setInterval(this.scroll, this.duration); this.curimg = this.imglist[this.centerindex].url; that = this; console.log(this.imglist.length); console.log(this.rleData.length); this.rleData.length = this.imglist.length; console.log(this.rleData.length); console.log(this.rleData); this.rleData = this.addmoredatax; console.log(this.addmoredatax); console.log(this.name); }, methods: { setMode(mode) { // console.log(mode); gMap.setMode(mode); // 后续对应模式处理 switch (gMap.mode) { case 'PAN': { break; } case 'MARKER': { // 忽略 break; } case 'POINT': { drawingStyle = {fillStyle: '#9370DB'}; gMap.setDrawingStyle(drawingStyle); break; } case 'CIRCLE': { drawingStyle = {fillStyle: '#9370DB', strokeStyle: '#0000FF', lineWidth: 2}; gMap.setDrawingStyle(drawingStyle); break; } case 'LINE': { drawingStyle = {strokeStyle: '#FF00FF', lineJoin: 'round', lineCap: 'round', lineWidth: 10}; gMap.setDrawingStyle(drawingStyle); break; } case 'POLYLINE': { drawingStyle = {strokeStyle: '#FF1493', lineJoin: 'round', lineCap: 'round', lineWidth: 10} gMap.setDrawingStyle(drawingStyle); break; } case 'RECT': { drawingStyle = {strokeStyle: '#0f0', lineWidth: 1} gMap.setDrawingStyle(drawingStyle); this.curMode = 1; break; } case 'POLYGON': { drawingStyle = {strokeStyle: '#00f', fillStyle: '#0f0', globalAlpha: .3, lineWidth: 1, fill: true, stroke: true} gMap.setDrawingStyle(drawingStyle); this.curMode = 2; break; } case 'DRAWMASK': { drawingStyle = {strokeStyle: 'rgba(255, 0, 0, .5)', fillStyle: '#00f', lineWidth: 20} gMap.setDrawingStyle(drawingStyle); break; } case 'CLEARMASK': { drawingStyle = {fillStyle: '#00f', lineWidth: 20} gMap.setDrawingStyle(drawingStyle); break; } default: break; } }, // 去标注 gomark(item){ this.flagswitch = true; }, // 监听输入框搜索 changeinput(){ if(!this.searchval){ this.$nextTick(()=>{ this.list = [{ title: '样本集1', percentage: '80%', number: 1518, color: 1, }, { title: '样本集2', percentage: '80%', number: 1517, color: 2, }, { title: '样本集3', percentage: '80%', number: 1516, color: 3, },{ title: '样本集4', percentage: '80%', number: 1515, color: 3, },{ title: '样本集5', percentage: '60%', number: 1514, color: 3, },{ title: '样本集6', percentage: '60%', number: 1514, color: 3, },{ title: '样本集7', percentage: '60%', number: 1513, color: 3, },{ title: '样本集8', percentage: '60%', number: 1519, color: 3, },{ title: '样本集9', percentage: '60%', number: 1514, color: 3, },{ title: '样本集10', percentage: '60%', number: 1519, color: 3, },{ title: '样本集11', percentage: '60%', number: 1519, color: 3, },{ title: '样本集12', percentage: '60%', number: 1519, color: 3, },{ title: '样本集13', percentage: '60%', number: 1514, color: 3, },{ title: '样本集14', percentage: '60%', number: 1519, color: 3, },{ title: '样本集15', percentage: '60%', number: 1515, color: 3, },{ title: '样本集16', percentage: '90%', number: 1519, color: 3, },{ title: '样本集17', percentage: '90%', number: 1515, color: 3, },{ title: '样本集18', percentage: '90%', number: 1519, color: 3, },{ title: '样本集19', percentage: '90%', number: 1515, color: 3, },{ title: '样本集20', percentage: '90%', number: 1519, color: 3, }] // 数据列表 }) } let arr = this.list.filter((item,index)=>{ return item.percentage == this.searchval; }); if(arr.length > 0){ this.list = arr; } }, // 手动触发轮播 handchange: debounce((item,index)=>{ // that.curimg = item.url; // 大于2 和小于2的 方向处理 if(index > that.centerindex){ that.clickscroll(2); }else if(index // 方向赋值 that.type = type; // type 1 向上 2 向下 that.animate = true; // 因为在消息向上滚动的时候需要添加css3过渡动画,所以这里需要设置true // 清除标记 that.clearbtn(); that.timer = setTimeout(() => { if(type == 2){ that.imglist.push(that.imglist.shift()); //删除数组的第一个元素并添加到数组的最后一项 that.rleData.push(that.rleData.shift()); //删除数组的第一个元素并添加到数组的最后一项 }else{ that.imglist.unshift(that.imglist.pop()); //删除数组的第一个元素并添加到数组的最后一项 that.rleData.unshift(that.rleData.pop()); //删除数组的第一个元素并添加到数组的最后一项 } that.curimg = that.imglist[that.centerindex].url; that.animate = false; //滑动完成后取消过渡动画,实现无缝滚动 // 重新渲染标记 that.clearbtn(); // 清除标记 that.btnclearimg(); // 清除图层 that.btnadd(); // 添加新图层 that.addmoredata(); // 添加图形 }, that.duration / 2);//滑动item项必须要在每次轮播开始前,所以时间必须比duration短 },300,false), // 搜索列表点击事件 handClick(item,idx){ // 赋值当前项 this.currindex = idx; // 展示样本集 this.flagswitch = false; }, // 初始化画布 获取基本属性 onImageLoad(e){ console.log(e); }, // 画完标记触发 onAnnoAdded(item){ }, // 清除标记 clearbtn(flag){ // 删除全部marker gMap.markerLayer.removeAllMarkers(); // 删除全部text gFirstTextLayer.removeAllTexts(); // 删除全部feature gFirstFeatureLayer.removeAllFeatures(); // 删除全部涂抹 gFirstMaskLayer.removeAllActions(); }, // 刷新图层 refresh(){ gMap.refresh(); }, // 保存标记位置 savebtn(){ const rleData = gFirstFeatureLayer.getAllFeatures(); console.log('--rleData--', rleData); this.rleData[this.currindex] = rleData; this.$message({ message: '保存成功', type: 'success' }) }, // 标记组件初始化完成 onReady(){ }, // 读取默认数据 readydata(){ }, // 删除图层 btnclearimg(){ // gMap.removeAllLayers(); gMap.removeLayerById('first-layer-image'); }, // 添加图层 btnadd(){ gImageLayer = new AILabel.Layer.Image('first-layer-image', // id { src: this.curimg, width: 790, height: 520, position: { // 图片左上角坐标 x: 0, y: 0 } }, // imageInfo {name: '第一个图片图层'}, // props {zIndex: 5} // style ) gMap.addLayer(gImageLayer); }, // 缩小 zoomIn(){ gMap.zoomIn(); }, // 放大 zoomOut(){ gMap.zoomOut(); }, // 初始化容器 showmarkimg(){ // 创建容器 gMap = new AILabel.Map('map', { center: {x: 395, y: 260}, zoom: 800, mode: 'RECT', // 绘制线段 refreshDelayWhenZooming: false, // 缩放时是否允许刷新延时,性能更优 zoomWhenDrawing: false, panWhenDrawing: false }) // 添加图片层 gImageLayer = new AILabel.Layer.Image('first-layer-image', // id { src: this.curimg, width: 790, height: 520, position: { // 图片左上角坐标 x: 0, y: 0 } }, // imageInfo {name: '第一个图片图层'}, // props {zIndex: 5} // style ) gMap.addLayer(gImageLayer); // 实例化 gFirstFeatureLayer = new AILabel.Layer.Feature( 'first-layer-feature', // id {name: '第一个矢量图层'}, // props {zIndex: 10} // style ); gMap.addLayer(gFirstFeatureLayer); // 涂抹层 gFirstMaskLayer = new AILabel.Layer.Mask( 'first-layer-mask', // id {name: '第一个涂抹图层'}, // props {zIndex: 11, opacity: .5} // style ); gMap.addLayer(gFirstMaskLayer); // 添加文本层 gFirstTextLayer = new AILabel.Layer.Text( 'first-layer-text', // id {name: '第一个文本图层'}, // props {zIndex: 12, opacity: 1} // style ); gMap.addLayer(gFirstTextLayer); // 添加图形 this.addmoredata(); }, // 添加图形 addmoredata(){ console.log(this.rleData); let rectFeature; // 添加矩形 let gFirstFeaturePolygon; // 添加多边形 let gFirstText; // 添加文字 this.rleData && this.rleData[this.currindex] && this.rleData[this.currindex].forEach(ele => { console.log(ele); if(ele.type == "RECT"){ rectFeature = new AILabel.Feature.Rect( ele.id, // id ele.shape, // shape ele.props, // props ele.style // style ); gFirstFeatureLayer.addFeature(rectFeature); // 判断是否有 text if(ele.props && ele.props.text){ gFirstText = new AILabel.Text( ele.props.textId, // id {text: ele.props.text, position: {x: ele.shape.x, y: ele.shape.y}, offset: {x: 0, y: 0}}, // shape, 左上角 {name: '第一个文本对象',textId: ele.props.textId, deleteMarkerId: ele.props.deleteMarkerId}, // props {fillStyle: '#F4A460', strokeStyle: '#D2691E', background: true, globalAlpha: 1, fontColor: '#0f0'} // style ); gFirstTextLayer.addText(gFirstText); } }else if(ele.type == 'POLYGON'){ gFirstFeaturePolygon = new AILabel.Feature.Polygon( ele.id, // id ele.shape, // shape ele.props, // props ele.style // style ); gFirstFeatureLayer.addFeature(gFirstFeaturePolygon); if(ele.props && ele.props.text){ gFirstText = new AILabel.Text( ele.props.textId, // id, // id {text: ele.props.text, position: ele.shape.points[0], offset: {x: 0, y: 0}}, // shape, 左上角 {name: '第一个文本对象',textId: ele.props.textId, deleteMarkerId: ele.props.deleteMarkerId }, // props {fillStyle: '#F4A460', strokeStyle: '#D2691E', background: true, globalAlpha: 1, fontColor: '#0f0'} // style ); gFirstTextLayer.addText(gFirstText); } } }); } }, components: { Breadcrumb, }, computed: { ...mapGetters(["name","addmoredatax"]), }, mounted() { this.showmarkimg(); // 绘制结束 gMap.events.on('drawDone', (type, data, data1) => { // console.log('type, data', type, data); // 唯一ID const relatedTextId = `label-text-id-${+new Date()}`; const relatedDeleteMarkerId = `label-marker-id-${+new Date()}`; console.log(type); // 添加标注 if (type === 'MARKER') { console.log("sssssss"); const marker = new AILabel.Marker( relatedDeleteMarkerId, // id { src: require('../../assets/images/marker.png'), position: data, offset: { x: -16, y: 32 } }, // markerInfo {name: '第一个marker注记'} // props ); marker.events.on('click', marker => { console.log('marker click'); gMap.markerLayer.removeMarkerById(marker.id); }); gMap.markerLayer.addMarker(marker); } // 添加点 else if (type === 'POINT') { const pointFeature = new AILabel.Feature.Point( relatedDeleteMarkerId, // id {...data, sr: 3}, // shape {name: '第一个矢量图层',textId: relatedTextId, deleteMarkerId: relatedDeleteMarkerId }, // props drawingStyle // style ); gFirstFeatureLayer.addFeature(pointFeature); } // 添加圆 else if (type === 'CIRCLE') { // data 代表r半径shape;data1代表sr半径shape const circleFeature = new AILabel.Feature.Circle( relatedDeleteMarkerId, // id data, // data1代表屏幕坐标 shape {name: '第一个矢量图层',textId: relatedTextId, deleteMarkerId: relatedDeleteMarkerId}, // props {fillStyle: '#F4A460', strokeStyle: '#D2691E', lineWidth: 2} // style ); gFirstFeatureLayer.addFeature(circleFeature); } // 添加线段 else if (type === 'LINE') { const scale = gMap.getScale(); const width = drawingStyle.lineWidth / scale; const lineFeature = new AILabel.Feature.Line( relatedDeleteMarkerId, // id {...data, width}, // shape {name: '第一个矢量图层',textId: relatedTextId, deleteMarkerId: relatedDeleteMarkerId}, // props drawingStyle // style ); gFirstFeatureLayer.addFeature(lineFeature); } // 添加多线段 else if (type === 'POLYLINE') { const scale = gMap.getScale(); const width = drawingStyle.lineWidth / scale; const polylineFeature = new AILabel.Feature.Polyline( relatedDeleteMarkerId, // id {points: data, width}, // shape {name: '第一个矢量图层',textId: relatedTextId, deleteMarkerId: relatedDeleteMarkerId}, // props drawingStyle // style ); gFirstFeatureLayer.addFeature(polylineFeature); } // 添加矩形 else if (type === 'RECT') { const rectFeature = new AILabel.Feature.Rect( relatedDeleteMarkerId, // id data, // shape {name: '矢量图形',textId: relatedTextId, deleteMarkerId: relatedDeleteMarkerId, text: this.value}, // props drawingStyle // style ); gFirstFeatureLayer.addFeature(rectFeature); // 添加feature标签名 const {x: ltx, y: lty} = data; const gFirstText = new AILabel.Text( relatedTextId, // id {text: this.value, position: {x: ltx, y: lty}, offset: {x: 0, y: 0}}, // shape, 左上角 {name: '第一个文本对象',textId: relatedTextId, deleteMarkerId: relatedDeleteMarkerId}, // props {fillStyle: '#F4A460', strokeStyle: '#D2691E', background: true, globalAlpha: 1, fontColor: '#0f0'} // style ); gFirstTextLayer.addText(gFirstText); } // 添加多边形 else if (type === 'POLYGON') { const polygonFeature = new AILabel.Feature.Polygon( relatedDeleteMarkerId, // id {points: data}, // shape {name: '矢量图形2',textId: relatedTextId, deleteMarkerId: relatedDeleteMarkerId, text: this.value }, // props drawingStyle // style ); gFirstFeatureLayer.addFeature(polygonFeature); // 添加feature标签名 const {x: ltx, y: lty} = data[0]; const gFirstText = new AILabel.Text( relatedTextId, // id {text: this.value, position: {x: ltx, y: lty}, offset: {x: 0, y: 0}}, // shape, 左上角 {name: '第一个文本对象',textId: relatedTextId, deleteMarkerId: relatedDeleteMarkerId}, // props {fillStyle: '#F4A460', strokeStyle: '#D2691E', background: true, globalAlpha: 1, fontColor: '#0f0'} // style ); gFirstTextLayer.addText(gFirstText); } // 添加涂抹 else if (type === 'DRAWMASK') { const scale = gMap.getScale(); const width = drawingStyle.lineWidth / scale; const drawMaskAction = new AILabel.Mask.Draw( relatedDeleteMarkerId, // id '铅笔', {points: data, width}, // shape {name: '港币', price: '1元',textId: relatedTextId, deleteMarkerId: relatedDeleteMarkerId}, // props drawingStyle // style ); gFirstMaskLayer.addAction(drawMaskAction); } // 添加擦除 else if (type === 'CLEARMASK') { const scale = gMap.getScale(); const width = drawingStyle.lineWidth / scale; const clearMaskAction = new AILabel.Mask.Clear( relatedDeleteMarkerId, // id {points: data, width} // shape ); gFirstMaskLayer.addAction(clearMaskAction); } }); // click单击事件 gMap.events.on('click', point => { // console.log('--click--', point); }); gMap.events.on('boundsChanged', data => { console.log('--map boundsChanged--',data); }); gMap.events.on('featureSelected', feature => { // 高亮选中feature gMap.setActiveFeature(feature); const markerId = feature.props.deleteMarkerId; const textId = feature.props.textId; // 禁止重复编辑 const mappedMarker = gMap.markerLayer.getMarkerById(markerId); if (mappedMarker) { return; } console.log("双击编辑"); let features; if(feature.type == "POLYGON"){ // console.log(feature.shape.points); features = feature.shape.points[1]; }else if (feature.type == "RECT"){ features = feature.getPoints()[1]; } // 添加delete-icon gFirstMarker = new AILabel.Marker( markerId, // id { src: require('../../assets/images/delete.png'), position: features, // 矩形右上角 offset: { x: -20, y: -4 } }, // markerInfo {name: '第一个marker注记'} // props ); gFirstMarker.events.on('click', marker => { console.log(marker); // 首先删除当前marker gMap.markerLayer.removeMarkerById(marker.id); // 删除对应text gFirstTextLayer.removeTextById(textId); // 删除对应feature gFirstFeatureLayer.removeFeatureById(feature.id); }); gMap.markerLayer.addMarker(gFirstMarker); }); gMap.events.on('featureUnselected', feature => { console.log('取消featureSelected'); gMap.setActiveFeature(null); gMap.markerLayer.removeMarkerById(feature.props.deleteMarkerId); }); gMap.events.on('featureUpdated', (feature, shape) => { console.log("移动更新"); console.log("featureUpdated",feature,shape); feature.updateShape(shape); // 更新标记 // 更新text位置 // 唯一ID const markerId = feature.props.deleteMarkerId; const textId = feature.props.textId; console.log(markerId,textId); // 更新marker位置 targetMarker = gMap.markerLayer.getMarkerById(markerId); // console.log(targetMarker); targetMarker.updatePosition(feature.type == "POLYGON" ? feature.shape.points[1] : feature.getPoints()[1]); // 更新text位置 targetText = gFirstTextLayer.getTextById(textId); console.log('--targetText--', targetText); targetText.updatePosition(feature.type == "POLYGON" ? feature.shape.points[0] : feature.getPoints()[0]); }); gMap.events.on('featureDeleted', ({id: featureId}) => { gFirstFeatureLayer.removeFeatureById(featureId); }); }, }; @import "~@/styles/variables.scss"; .dashboard { width: 100%; height: 100%; display: flex; justify-content: flex-start; .index_left { width: 320px; min-height: calc(100vh - 72px); background-color: $backGrounds; border-right: 2px solid $bordercolor; // float: left; display: flex; flex-direction: column; align-items: center; .index_div { border-bottom: 2px solid $bordercolor; padding: 9px 0; width: 100%; .layer22 { height: 36px; border-radius: 18px; padding: 10px 0; background-color: rgba(0, 150, 136, 1); width: 280px; display: flex; justify-content: center; align-items: center; margin: 0 auto; .info6 { width: 55px; display: block; overflow-wrap: break-word; color: rgba(252, 252, 252, 1); font-size: 11px; white-space: nowrap; text-align: center; } } } .inputval { padding: 0 5px; i { font-size: 18px; } } .index_list{ width: 100%; // height: 560px; // overflow: scroll; .index_title{ font-size: 13px; color: $BIAOTIcolor; width: 100%; height: 42px; display: flex; justify-content: flex-start; align-items: center; border-bottom: 2px solid $bordercolor; &>div{ width: 100px; margin-left: 30px; display: flex; justify-content: flex-start; align-items: center; } i{ display: block; width: 21px; height: 18px; background: #D7D7D7; border-radius: 3px; line-height: 18px; text-align: center; font-size: 9px; color: #FFFFFF; transform: scale(.9); margin-left: 6px; } } .index_item{ font-size: 12px; color: $colors; width: 100%; height: 42px; display: flex; justify-content: flex-start; align-items: center; cursor: pointer; border-bottom: 2px solid $bordercolor; &>div{ width: 100px; margin-left: 30px; display: flex; justify-content: flex-start; align-items: center; } i{ display: block; width: 16px; height: 16px; background: #da5f5f; border-radius: 50%; margin-right: 10px; } } // 当前选中项 .currcolor{ color: #009688; } } } .index_right { width: 100%; min-height: calc(100vh - 72px); display: flex; flex-direction: column; align-items: center; background-color: $bottomback; .right_top_title{ width: 900px; // width: 100%; height: 56px; display: flex; justify-content: center; align-items: center; font-size: 13px; color: $colors; background-color: $backGrounds; border-bottom: 2px solid $bordercolor; } .index_detail{ width: 100%; display: flex; justify-content: center; margin-top: 20px; .item_detail{ width: 275px; height: 557px; margin: 0 10px; background: $backGrounds; box-shadow: 0px 2px 5px 0px rgba(0, 0, 0, 0.05); border-radius: 5px; .detail_p1{ margin-top: 30px; font-size: 11px; color: $colors; text-align: center; } .detail_p2{ margin-top: 15px; font-size: 11px; color: $XUNLIANcolor; text-align: center; } .detail_p3{ margin-top: 15px; font-size: 28px; color: $colors; font-weight: 600; text-align: center; span{ color: $BIAOTIcolor; font-size: 9px; } } .detail_line{ display: block; width: 90% ; padding: 0 5%; height: 2px; background: $bordercolor; margin: 0 auto; margin-top: 30px; } .item_detail_list{ width: 92%; display: flex; justify-content: flex-start; flex-wrap: wrap; margin: 0 auto; margin-top: 30px; border-radius: 24px; border: 2px solid #D7D7D7; padding: 2px; .item_detail_item{ width: 59px; height: 39px; margin: 1px 0 0 2px; box-sizing: border-box; img{ width: 100%; height: 100%; } } .item_detail_item:nth-child(4) img{ border-top-right-radius: 24px; } .item_detail_item:nth-child(13) img{ border-bottom-left-radius: 24px; } .item_detail_item:first-child img{ border-top-left-radius: 24px; } .item_detail_item:last-child img{ border-bottom-right-radius: 24px; } } .detail_complete{ width: 240px; height: 44px; font-size: 9px; font-family: PingFangSC-Regular, PingFang SC; font-weight: 400; color: $XUNLIANcolor; line-height: 44px; text-align: center; margin: 0 auto; margin-top: 20px; } .detail_percentage{ display: block; width: 100%; height: 44px; font-size: 21px; font-family: PingFangSC-Medium, PingFang SC; font-weight: 500; color: $colors; text-align: center; line-height: 44px; } .detail_btn{ width: 110px; height: 28px; background: #009688; border-radius: 20px; border: 2px solid #D7D7D7; margin: 0 auto; font-size: 13px; color: #FCFCFC; display: flex; justify-content: center; align-items: center; margin-top: 12px; cursor: pointer; } } } // 底部btn .detail_bottom_btn{ width: 100%; max-width: 855px; display: flex; justify-content: flex-end; align-items: center; margin-top: 50px; div{ font-size: 13px; color: #FCFCFC; display: flex; justify-content: center; align-items: center; cursor: pointer; height: 36px; background: $bjcolor; border-radius: 20px; border: 2px solid #D7D7D7; padding: 0 28px; margin-left: 18px; } .btn3{ background-color: #F74236; } } // 材料轮播标题 .index_lunbo_title{ width: 845px; height: 72px; background: $backGrounds; box-shadow: 0px 2px 5px 0px rgba(0, 0, 0, 0.05); border-radius: 5px; display: flex; justify-content: flex-start; align-items: center; margin-top: 20px; .title_first{ display: flex; flex-direction: column; justify-content: center; align-items: center; margin-left: 20px; .title_top{ font-size: 11px; color: $colors; } .title_btm{ font-size: 9px; color: $activecolor; margin-top: 10px; min-width: 110px; text-align: center; .breadcrumb-container{ font-size: 9px; line-height: 0; span{ color: $activecolor !important; } } } } .title_line{ width: 3px; height: 32px; background: $bordercolor; margin: 0 25px; } .title_pro{ width: 144px; // height: 44px; font-size: 11px; font-family: PingFangSC-Medium, PingFang SC; font-weight: 500; color: #666666; line-height: 16px; } .title_img{ width: 144px; font-size: 11px; .active_img{ color: $activecolor; } } .title_rectangular{ width: 32px; height: 32px; cursor: pointer; } .title_polygon{ width: 30px; height: 34px; margin-left: 25px; margin-right: 26px; cursor: pointer; } .curimgbor{ background-color: #f0f0f0; } } // 轮播 .content_swiper{ display: flex; justify-content: flex-start; width: 845px; height: 436px; margin-top: 29px; .big_img{ width: 656px; height: 436px; #map{ width: 656px; height: 436px; border: 1px solid red; position: relative; cursor: pointer; } .ai-observer{ width: 650px !important; height: 430px !important; border: 1px solid #009688;// 轮播大图边框 background-color: #FFFFFF; .vmr-g-image{ width: 650px !important; height: 430px !important; } } // img{ // display: block; // width: 99% !important; // height: 97.5% !important; // top: 0; // left: 0; // right: 0; // bottom: 0; // margin: auto; // } .big_bottom_btn{ margin-top: 10px; width: 656px; padding: 0 20px; height: 72px; background: #FFFFFF; box-shadow: 0px 2px 5px 0px rgba(0, 0, 0, 0.05); border-radius: 5px; display: flex; justify-content: flex-start; align-items: center; .btn_msg{ display: block; height: 16px; font-size: 11px; font-family: PingFangSC-Medium, PingFang SC; font-weight: 500; color: #666666; span{ color: $activecolor; } } .img_size{ display: flex; justify-content: flex-start; align-items: center; flex-direction: column; span{ font-size: 11px; color: $colors; font-weight: 600; margin: 3px 0; margin-left: 50px; } } .btn_label{ height: 16px; font-size: 11px; font-family: PingFangSC-Medium, PingFang SC; font-weight: 500; color: $colors; line-height: 16px; margin-left: 50px; span{ color: $activecolor; } } .btn_red{ width: 100px; height: 36px; background: #F74236; border-radius: 20px; border: 2px solid #D7D7D7; font-size: 13px; display: flex; justify-content: center; align-items: center; margin-left: 55px; color: $btncolor; cursor: pointer; } .btn_green{ width: 100px; height: 36px; background: $bjcolor; border-radius: 20px; border: 2px solid #D7D7D7; font-size: 13px; display: flex; justify-content: center; align-items: center; color: $btncolor; margin-left: 16px; cursor: pointer; } } } .right_swiper{ width: 160px; height: 436px; margin-left: 25px; .swiper_top{ display: flex; justify-content: center; align-items: center; width: 160px; height: 28px; background: #D7D7D7; border-radius: 6px; margin-bottom: 8px; cursor: pointer; img{ width: 12px; height: 12px; } } .swiper_bottom{ display: flex; justify-content: center; align-items: center; width: 160px; height: 28px; background: #D7D7D7; border-radius: 6px; margin-top: 8px; cursor: pointer; img{ width: 12px; height: 12px; cursor: pointer; } } .swiper_list{ display:flex; flex-direction: column; align-items: center; } } } .option_img{ width: 300px; height: 400px; } } } .index_div { .el-input input::-webkit-input-placeholder { font-size: 11px; color: #aaaaaa; } .el-input input::-moz-input-placeholder { font-size: 11px; color: #aaaaaa; } .el-input input::-ms-input-placeholder { font-size: 11px; color: #aaaaaa; } } .index_div .el-input__inner { border: none; list-style: none; background-color: $subMenuBg; } .index_lunbo_title .el-input__inner{ width: 200px; height: 40px; border-radius: 25px; background-color: $bjcolor; font-size: 13px; color: #FCFCFC; } .el-select-dropdown__item{ // width: 240px; height: 40px; border-bottom: 2px solid $bordercolor; span{ width: 100%; display: block; text-align: center; } } .el-select-dropdown__item:last-child{ // width: 240px; height: 40px; border: none; } .el-select-dropdown__item.selected{ color: $activecolor; span{ width: 100%; display: block; text-align: center; } } .el-select__caret{ color: #FFFFFF !important; } .el-input__suffix{ right: 12px; } .el-input__inner{ padding-left: 25px !important; } .swiper-container { position: relative; width: 100%; height: 365px; overflow: hidden; } .swiper-wrapper { position: absolute; width: 100%; top: -120px; // height: 100%; display: flex; flex-direction: column; align-items: center; } .swiper-slide { width: 154px; height: 102px; display: flex; align-items: center; justify-content: center; border: 1px solid; margin: 9px 0; border-radius: 24px; border: 2px solid #D7D7D7; transition: all 1s ease; img{ transition: all 1s ease; width: 100%; height: 100%; border-radius: 24px; cursor: pointer; } } .swiper-wrapper .swiper-slide:nth-child(3){ transition: all 1s ease; width: 160px; height: 108px; img{ transition: all 1s ease; width: 100%; height: 100%; border-radius: 24px; } } // 修改标签大小 .g-image-op-content{ height: 20px; line-height: 20px; padding: 0 5px; font-size: 10px; }


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3