一、网址以及demo

官方文档:AILabel与你一路同行

demo地址1: AILabel-标注篇
demo地址2: AILabel示例一览

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

三、完整代码

  • 首先  npm i ailabel

<template><div class="main"><div class="operation"><div class="button-wrap"><el-button type="text" class="el-icon-thumb" @click="setMode('PAN')">平移</el-button><el-buttontype="text"class="el-icon-location-outline"@click="setMode('MARKER')">注记</el-button><el-buttontype="text"class="el-icon-more-outline"@click="setMode('POINT')">点</el-button><el-button type="text" class="el-icon-minus" @click="setMode('LINE')">线段</el-button><el-buttontype="text"class="el-icon-share"@click="setMode('POLYLINE')">多段线</el-button><el-button type="text" class="el-icon-orange" @click="setMode('CIRCLE')">圆</el-button><el-buttontype="text"class="el-icon-full-screen"@click="setMode('RECT')">矩形</el-button><el-button type="text" class="el-icon-house" @click="setMode('POLYGON')">多边形</el-button><el-button type="text" class="el-icon-magic-stick" @click="Fill()">填充</el-button><el-button type="text" class="el-icon-refresh-left" @click="Revoke()">撤销</el-button><el-button type="text" @click="getFeatures()">获取标注数据</el-button><!-- <button class="btn btn-default" @click="setMode('DRAWMASK')">涂抹</button> --><!-- <button class="btn btn-default" @click="setMode('CLEARMASK')">擦除</button> --><!-- <button class="btn btn-default" @click="getRle()">获取rle数据</button> --></div><div class="zoom-icon-wrapper"><div class="zoom-icon-plus" @click="zoomIn">+</div><div class="zoom-icon-minus" @click="zoomOut">-</div></div></div><div id="map"></div></div>
</template><script>
import AILabel from "ailabel";export default {name: "HelloWorld",data() {return {imgUrl:"https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fimg.zcool.cn%2Fcommunity%2F0186f0570f33d132f875a83991e34b.jpg&refer=http%3A%2F%2Fimg.zcool.cn&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1650076295&t=c0b8a135c2f9298d1d714703f5d30423",drawingStyle: {},mode: "",itemName: "",editId: "", //待填充图形iddeleteIconId: "delete01",gMap: null, //AILabel实例gFirstFeatureLayer: null, //矢量图层实例(矩形,多边形等矢量)allFeatures: null, //所有features};},watch: {mode(mode) {this.gMap.setMode(mode);this.setDrawingStyle(mode);},},methods: {zoomIn() {this.gMap.zoomIn();},zoomOut() {this.gMap.zoomOut();},setMode(mode) {this.mode = mode;},// 获取所有featuresgetFeatures() {this.allFeatures = this.gFirstFeatureLayer.getAllFeatures();console.log("--allFeatures--", this.allFeatures);},// 初始样式setDrawingStyle(mode) {let drawingStyle = {};switch (mode) {//平移case "PAN": {break;}//注记case "MARKER": {// 忽略break;}//点case "POINT": {this.drawingStyle = { fillStyle: "#FF8C00" };this.gMap.setDrawingStyle(drawingStyle);break;}//圆case "CIRCLE": {this.drawingStyle = {fillStyle: "#87CEFF",strokeStyle: "#87CEFF",lineWidth: 5,};this.gMap.setDrawingStyle(drawingStyle);break;}//线段case "LINE": {this.drawingStyle = {strokeStyle: "#BA55D3",lineJoin: "round",lineCap: "round",lineWidth: 10,arrow: false,};this.gMap.setDrawingStyle(drawingStyle);break;}//多线段case "POLYLINE": {this.drawingStyle = {strokeStyle: "#FF1493",lineJoin: "round",lineCap: "round",lineWidth: 10,};this.gMap.setDrawingStyle(drawingStyle);break;}//矩形case "RECT": {this.drawingStyle = { strokeStyle: "#0f0", lineWidth: 1 };this.gMap.setDrawingStyle(drawingStyle);break;}//多边形case "POLYGON": {this.drawingStyle = {strokeStyle: "#0099CC", //边框颜色fill: true, //是否填充fillStyle: "#FF6666", //填充色globalAlpha: 0.3,lineWidth: 3,fill: true,stroke: true,};this.gMap.setDrawingStyle(drawingStyle);break;}//涂抹case "DRAWMASK": {this.drawingStyle = {strokeStyle: "rgba(255, 0, 0, .5)",fillStyle: "#00f",lineWidth: 50,};this.gMap.setDrawingStyle(drawingStyle);break;}//擦除case "CLEARMASK": {this.drawingStyle = { fillStyle: "#00f", lineWidth: 30 };this.gMap.setDrawingStyle(drawingStyle);break;}default:break;}},// 添加图形addFeature(data, type, id) {let that = this;let drawingStyle = this.drawingStyle;//线if (type === "LINE") {const scale = that.gMap.getScale();const width = drawingStyle.lineWidth / scale;const lineFeature = new AILabel.Feature.Line(id, // id{ ...data, width }, // shape{ name }, // propsdrawingStyle // style);that.gFirstFeatureLayer.addFeature(lineFeature);}//线段else if (type === "POLYLINE") {const scale = that.gMap.getScale();const width = drawingStyle.lineWidth / scale;const polylineFeature = new AILabel.Feature.Polyline(id, // id{ points: data, width }, // shape{ name }, // propsdrawingStyle // style);that.gFirstFeatureLayer.addFeature(polylineFeature);}//矩形else if (type === "RECT") {const rectFeature = new AILabel.Feature.Rect(id, // iddata, // shape{ name }, // propsdrawingStyle // style);that.gFirstFeatureLayer.addFeature(rectFeature);}//多边形else if (type === "POLYGON") {const polygonFeature = new AILabel.Feature.Polygon(id, // id{ points: data }, // shape{ name }, // propsdrawingStyle // style);that.gFirstFeatureLayer.addFeature(polygonFeature);}//点else if (type == "POINT") {const gFirstFeaturePoint = new AILabel.Feature.Point(id, // id{ x: data.x, y: data.y, r: 5 }, // shape{ name }, // props{ fillStyle: "#FF8C00", zIndex: 5, lineWidth: 2 } // style);that.gFirstFeatureLayer.addFeature(gFirstFeaturePoint);}//注记else if (type == "MARKER") {const gFirstMarker = new AILabel.Marker(id, // id{src: "http://ailabel.com.cn/public/ailabel/demo/marker.png",position: {// marker坐标位置x: data.x,y: data.y,},offset: {x: -16,y: 32,},}, // markerInfo{ name: "第一个marker注记" } // props);that.gFirstFeatureLayer.addFeature(gFirstMarker);}//圆else if (type == "CIRCLE") {const gFirstFeatureCircle = new AILabel.Feature.Circle(id, // id{ cx: data.cx, cy: data.cy, r: data.r }, // shape{ name: "第一个矢量图层" }, // props{fillStyle: "#87CEFF",strokeStyle: "#3CB371",globalAlpha: 1,lineWidth: 5,} // style);that.gFirstFeatureLayer.addFeature(gFirstFeatureCircle);}//涂抹else if (type == "DRAWMASK") {const drawMaskAction = new AILabel.Mask.Draw(`${+new Date()}`, // id"铅笔",{ points: data, width: 5 }, // shape{ name: "港币", price: "1元" }, // props{ strokeStyle: "#FF0000" } // style);that.gFirstFeatureLayer.addAction(drawMaskAction);}//擦除else if (type == "CLEARMASK") {const clearMaskAction = new AILabel.Mask.Clear("first-action-clear", // id{ points: data, width: 5 } // shape);that.gFirstMaskLayer.addAction(clearMaskAction);}this.getFeatures();},// 画完取名getName(mode) {return this.$prompt("请输入填写名字", {confirmButtonText: "确定",showCancelButton: false,}).then(({ value }) => {this.itemName = value;return value;}).catch(() => {return null;});},// 增加删除图标addDeleteIcon(feature, shape) {let gMap = this.gMap;let that = this;// 添加delete-icon// let points = that.getPoints(feature);console.log(shape, "shape");const gFirstMarker = new AILabel.Marker(that.deleteIconId, // id{src: "https://s1.aigei.com/src/img/png/45/45aabfc232a34e5b9bfaf75412973c08.png?|watermark/3/image/aHR0cHM6Ly9zMS5haWdlaS5jb20vd2F0ZXJtYXJrLzUwMC0xLnBuZz9lPTE3MzU0ODgwMDAmdG9rZW49UDdTMlhwemZ6MTF2QWtBU0xUa2ZITjdGdy1vT1pCZWNxZUpheHlwTDpjYWQ1NHVoRlhGUUViSGR3Vm02aXctVTJoWVE9/dissolve/40/gravity/NorthWest/dx/18/dy/21/ws/0.0/wst/0&e=1735488000&token=P7S2Xpzfz11vAkASLTkfHN7Fw-oOZBecqeJaxypL:C11LKqsRLbAqQo2uVPETYDya0QU=",position: { x: shape.x + shape.width, y: shape.y - 15 }, // 矩形右上角 根据图形动态调整offset: {x: -20,y: -4,},}, // markerInfo{ name: "delete" } // props);gFirstMarker.events.on("click", (marker) => {// 首先删除当前markergMap.markerLayer.removeMarkerById(marker.id);// 删除对应text// gFirstTextLayer.removeTextById(textId);// 删除对应featurethat.gFirstFeatureLayer.removeFeatureById(feature.id);});gMap.markerLayer.addMarker(gFirstMarker);// that.gFirstFeatureLayer},// 删除 删除按钮deIcon() {this.gMap.markerLayer.removeAllMarkers();},// 增加事件addEvent() {let that = this;let gMap = this.gMap;gMap.events.on("drawDone", (type, data) => {console.log("--type, data--", type, data);// that.addFeature(data, type);if (type == "CLEARMASK" || type == "DRAWMASK") {that.addFeature(data, type);} else {that.getName(type).then((id) => {if (id) {that.addFeature(data, type, id);} else {this.$message({type: "info",message: "请填写名字",});}});}});gMap.events.on("boundsChanged", (data) => {console.log("--map boundsChanged--", data);return "";});// 双击编辑 在绘制模式下双击feature触发选中gMap.events.on("featureSelected", (feature) => {this.editId = feature.id;console.log("--map featureSelected--", feature, "双击编辑");//设置编辑featuregMap.setActiveFeature(feature);if (feature.type != "POINT") {// 增加删除按钮that.addDeleteIcon(feature, feature.shape);}});//右键 目前只针对点双击选中右键触发gMap.events.on("featureDeleted", (feature) => {if (feature.type == "POINT") {// 根据id删除对应featurethat.gFirstFeatureLayer.removeFeatureById(feature.id);}});// 单机空白取消编辑gMap.events.on("featureUnselected", () => {// 取消featureSelectedthat.editId = "";that.deIcon();gMap.setActiveFeature(null);});// 更新完gMap.events.on("featureUpdated", (feature, shape) => {console.log(feature);// 更新或者移动需要重新设置删除图标that.deIcon();feature.updateShape(shape);if (feature.type != "POINT") {that.addDeleteIcon(feature, shape);}});// 删除gMap.events.on("FeatureDeleted", () => {console.log(2222222);// that.gFirstFeatureLayer.removeFeatureById(that.editId);});},// 获取坐标 需要自行添加getPoints(feature) {switch (feature.type) {case "RECT":return feature.getPoints();case "LINE":return [feature.shape.start, feature.shape.end];case "POLYLINE":return feature.shape.points;case "POLYGON":return feature.shape.points;default:return [];}},//填充事件Fill() {console.log("填充事件");let fill = this.gFirstFeatureLayer.getFeatureById(this.editId);console.log("--填充对象--", fill);fill.style.fillStyle = "#FFDAB9";fill.style.fill = true;//刷新mapthis.gMap.refresh();},//撤销Revoke() {console.log("撤销");this.getFeatures();this.allFeatures.pop();//刷新mapthis.gMap.refresh();console.log(this.allFeatures, "--所有操作--");},},mounted() {let that = this;const gMap = new AILabel.Map("map", {center: { x: 250, y: 150 }, // 为了让图片居中zoom: 500,mode: "PAN", // 绘制线段refreshDelayWhenZooming: true, // 缩放时是否允许刷新延时,性能更优zoomWhenDrawing: true,panWhenDrawing: true,zoomWheelRatio: 5, // 控制滑轮缩放缩率[0, 10), 值越小,则缩放越快,反之越慢withHotKeys: true, // 关闭快捷键});that.gMap = gMap;this.addEvent();// 图片层添加const gFirstImageLayer = new AILabel.Layer.Image("first-layer-image", // id{src: that.imgUrl,width: 500,height: 300,crossOrigin: false, // 如果跨域图片,需要设置为trueposition: {// 左上角相对中心点偏移量x: 0,y: 0,},// 网格grid: {// 3 * 3columns: [{ color: "#9370DB" }, { color: "#FF6347" }],rows: [{ color: "#9370DB" }, { color: "#FF6347" }],},}, // imageInfo{ name: "第一个图片图层" }, // props{ zIndex: 5 } // style);// 添加到gMap对象gMap.addLayer(gFirstImageLayer);// 添加矢量图层const gFirstFeatureLayer = new AILabel.Layer.Feature("first-layer-feature", // id{ name: "第一个矢量图层" }, // props{ zIndex: 10 } // style);this.gFirstFeatureLayer = gFirstFeatureLayer;gMap.addLayer(gFirstFeatureLayer);window.onresize = function () {this.gMap && this.gMap.resize();};},beforeDestroy() {this.gMap.destroy();},
};
</script><!-- Add "scoped" attribute to limit CSS to this component only -->
<style>
.main {display: flex;flex-direction: row;margin: 50px;justify-content: center;
}.button-wrap {display: flex;flex-direction: column;padding-bottom: 10px;position: relative;z-index: 99;
}#map {/* margin: 0 auto; */overflow: hidden;position: relative;height: 600px;width: 800px;border: 1px dashed #ccc;
}.zoom-icon-wrapper {position: absolute;/* left: 20px; *//* top: 20px; */z-index: 1000;
}.zoom-icon-plus {width: 30px;height: 30px;line-height: 20px;text-align: center;border: 3px solid #6495ed;font-size: 20px;border-top-left-radius: 6px;border-top-right-radius: 6px;color: #ff8c00;cursor: pointer;
}.zoom-icon-plus:hover {border-color: #4169e1;
}.zoom-icon-minus {margin-top: 6px;width: 30px;height: 30px;line-height: 20px;text-align: center;border: 3px solid #6495ed;font-size: 25px;border-bottom-left-radius: 6px;border-bottom-right-radius: 6px;color: #ff8c00;cursor: pointer;
}.zoom-icon-minus:hover {border-color: #4169e1;
}
/* 删除图标 */
#delete01 {width: 20px;height: 20px;
}
.el-button + .el-button {margin-left: 0px;
}
</style>

每个创建的图层都可以通过编辑进行删除操作

涂抹擦除 还有撤回功能(后续待更新)

2022/3/18

增加填充功能和撤回功能

Vue + AILabel.js 实现图片标注相关推荐

  1. vue 创建图片坐标点_利用vue+fabric.js获取图片坐标,并实现图片拖拽、旋转、拉伸等功能...

    什么是Fabric.js? Fabric.js是一个可以简化Canvas程序编写的库. Fabric.js为Canvas提供所缺少的对象模型, svg parser, 交互和一整套其他不可或缺的工具. ...

  2. Vue + ccropper.js裁切图片(vue-cropper)

    有什么问题可以加我的微信,有问必答. 致力于技术分享 按原比例裁切图片,不失真 安装: cnpm install vue-cropper 使用: import VueCropper from 'vue ...

  3. vue+konva.js图片数据标注多边形矩形---demo2.0。添加了其他功能和完善了代码。

    文章目录 前言 一. 自适应画布 二.新矩形和多边形 1.绘画多变形时,右击结束绘画.2.重新调整图形大小时,顶点已经约束不能拖拽出画布. 三.ctrl+z撤销和del删除 选中某一个图形,按ctrl ...

  4. js br不生效_前端标注工具-AILabel.js

    # AILabel.js 背景:在前端开发过程中难免遇到针对图片的缩放平移:以及在图片上进行矢量数据.文本.标注的展示:如果你有上面的任何需求,恭喜你,找到组织了....<br/> 在此背 ...

  5. vue本地上传并预览php,vue.js 实现图片本地预览 裁剪 压缩 上传功能

    以下代码涉及 Vue 2.0 及 ES6 语法. 目标 纯 javascrpit 实现,兼容ie9及以上浏览器,在本地做好文件格式.长宽.大小的检测,减少浏览器交互. 现实是残酷的,为了兼容Ie9 还 ...

  6. VUE实现前台图片 标注(添加矩形框)、放大、缩小、拖拽 -----个人记录

    VUE实现前台图片 标注(添加矩形框).放大.缩小.拖拽 需求:实现图片上自定义多个矩形选框,选框可移动缩放拖动,图片可以放大缩小.拖拽 ,选框内填充标注文字. 框内填充文字基本都会,不多赘述,后期可 ...

  7. JS图片标注打点管理工具,支持缩放、移动和灵活的自定义

    taggd-manager taggd-manager 是一个图片标注管理工具,支持缩放.移动和灵活的自定义. Installation Download the latest release npm ...

  8. vue 图片裁剪工具_使用Vue.js的图片裁剪工具,包括预览

    vue 图片裁剪工具 Vue作物 (vue-crop) Images Crop tool with Vue.js including preview. 使用Vue.js的图片裁剪工具,包括预览. Vi ...

  9. vue+konva.js(未使用vue-konva)实现数据标注矩形和多边形功能

    文章目录 前言 一.矩形和多边形绘画 二.矩形和多边形重新调整 三.代码 四,添加了其他功能和完善了代码.konva标注多边形矩形---demo2.0 源码下载 前言 vue+konva.js(未使用 ...

最新文章

  1. CentOS 6.4安装配置LNMP服务器(Nginx+PHP+MySQL)
  2. 棋盘上的孙子兵法之我见
  3. pil ImportError: DLL load failed: 找不到指定的模块
  4. 深究AngularJS——下拉框(selected)
  5. html5判断text文本是数字,JavaScript常用判断写法大全
  6. 谷歌浏览器使用IE内核
  7. JVM调优:CMS使用的算法
  8. 光模块的分类与HBA卡的区别
  9. HttpHandler
  10. 已知先序和中序得出后序
  11. Linux学习总结(30)——优秀程序员喜欢用Linux操作系统
  12. 大连理工大学计算机视觉实验室,首个镜子分割网络问世,大连理工、鹏城实验室、香港城大出品 | ICCV 2019...
  13. PHP根据开始、结束时间:计算开始、结束时间占当月总天数的百分比
  14. java8 stream中 forEach和 forEachOrdered 当parallel时候执行过程安全问题深入理解
  15. i2c-tools安装与使用总结
  16. 为什么国内的游戏公司吃相越来越难看了?
  17. [nssl 1322][jzoj cz 2109] 清兵线 {dp}
  18. Java中常见异常及异常处理方式
  19. 网络流模型与技巧总结
  20. 2019年注册测绘师 测绘管理与法律法规 精讲班视频课程

热门文章

  1. 【翻译】FFmpeg裁剪(seeking)视频后音画不同步的原因
  2. 只做有效的互联网推广服务!
  3. “华为杯”研究生数学建模竞赛2007年-【华为杯】B题:机械臂运动路径设计问题(附获奖论文)
  4. nginx访问限制模块limit_conn_zone 和limit_req_zone配置使用详解
  5. [Unity3D]Navigation导航系统讲解及其应用
  6. BottomSheetDialog仿抖音评论区的UI效果
  7. Paper:RNN之《Generating Sequences With Recurrent Neural Networks用循环神经网络生成序列》的翻译和解读
  8. 信捷plc和台达变频器通信程序通过信捷xc3的modbus通信控制台达vfd-m变频器的正转
  9. 信捷plc和台达变频器通信程序 通过信捷xc3的modbus通信控制台达vfd-m变频器的正转,反转,加减速,停止
  10. 电力系统为什么是三相的