最近有工友问我前端怎么给图片做标注。使用 Fabric.js 或者 Konva.js 等库确实可以实现,但我又好奇有没有专门做图片标注的工具呢?
在网上搜了一下发现 Annotorious 可以实现这个功能。Annotorious 提供了图片注释和标注功能,而且用法很简单。

【快速入门】部分包含 Annotorious 的安装、使用、导入导出的讲解。这几点应该是项目中比较核心的流程,给希望快速入门的工友提供一丢丢帮助。
【API讲解】这部分主要讲一下我认为比较常用的功能。注意:是“我认为”。
快速入门部分会讲解Annotorious 的安装、使用、导入和导出数据功能。
你可以把这两份文件下载到自己的项目里再引入。
用以下命令安装 Annotorious
npm install @recogito/annotorious然后在项目中引入
import { Annotorious } from '@recogito/annotorious'
import '@recogito/annotorious/dist/annotorious.min.css'把 Annotorious 安装到项目后就可以使用了。
Annotorious 的用法很简单,只需做以下2步:
Annotorious,并绑定图片元素(元素的ID或者元素本身)
CDN 和 NPM 在初始化时的用法稍微有点不同。
使用 CDN 的方式引入 Annotorious,在初始化时要 Annotorious.init 这样写。
使用 NPM 的方式引入 Annotorious 在初始化时需要 new Annotorious 这样写。
注意:在 Annotorious 初始化代码最好放在你所使用的框架的页面加载完成后的生命周期函数里!
如果你需要将图片上的标注保存到服务器,就需要把数据导出。
所用到的方法是 getAnnotations()。

Annotorious 可以通过 loadAnnotations() 方法加载数据。
loadAnnotations(url) 支持传入一个 URL 参数,这个 URL 所指的是数据文件地址。
比如我在本地创建一个 data.json 文件,文件内容是使用前面讲到的 getAnnotations() 方法导出的数据,我的数据内容如下:
[
{
"@context": "http://www.w3.org/ns/anno.jsonld",
"type": "Annotation",
"body": [
{
"type": "TextualBody",
"value": "1",
"purpose": "commenting"
}
],
"target": {
"source": "http://127.0.0.1:5500/44.jpg",
"selector": {
"type": "FragmentSelector",
"conformsTo": "http://www.w3.org/TR/media-frags/",
"value": "xywh=pixel:100,100,500,300"
}
},
"id": "#cabe2e71-b19f-4499-80c6-235882fd50ba"
}
]在本地测试时,我使用了本地服务器把 data.json 管理起来,在浏览器可以通过 http://127.0.0.1:5500/data.json 访问到该文件。
然后再使用 loadAnnotations(url) 方法把数据渲染出来即可。

点击加载按钮后,图片上就会出现一个选框,点击选框可以看到数据已经成功加载出来。
但在实际项目中,后台不一定会给前端返回一个文件地址,后台可能会直接返回一个json数据。
这时候如果使用 loadAnnotations() 方法加载 json 数据是行不通的,要通过遍历读取数据中心的 data 里的数据,然后调用 addAnnotation() 方法将元素添加到页面。
我使用 json-server 简单的在本地搭建一个服务器给前端访问对应的资源,前端用 axios 请求资源。
很久之前写过一篇 《『前端必备』本地数据接口 —— json-server 从入门到膨胀》 文章介绍 json-server 的基础用法,有兴趣的工友可以去瞧瞧。
这部分主要讲一些我关注到的功能,如果想全面了解 Annotorious 可以查看文档。
Annotorious 是根据浏览器的设置来确定使用哪种语言。

如果需要修改 Annotorious 使用的语言,可以在初始化时配置一下 locale 字段。
比如配置简体中文可以用 zh-CN,配置繁体中文可以用 zh-TW。

如果想自定义按钮或者输入框的提示文本可以配置 messages 。
如果同时配置了 locale 和 messages ,会优先使用 message 的值。
默认情况下,如果框选后没输入标签或者评论就按确定是不会保存选框的。

如果想保存空选框,可以将 allowEmpty 设置为 true 。

有些鼠标指针可能并不是那么标准,会影响你框选的准确性。
如果需要非常准确去框选,可以开启辅助线功能,只需将 crosshair 设置为 true 即可。

如果不打算提供框选、添加和删除信息的操作给用户,可以将 readOnly 设置为 true 。
如果只需要画框框,不需要写注释,可以将 disableEditor 和 allowEmpty 同时设置为 true。

为什么要同时将 allowEmpty 设为 true ?
因为如果你不允许注释为空的话,当你点击空白处时选框就会消失。
将 disableSelect 设置为 true 后,画布上的选框就无法再次选中了。
虽然还没想到有什么引用场景,但还是打算记录一下。
箭头所指的就是手柄。

手柄的默认半径是6。如果需要修改手柄半径可以设置 handleRadius 属性。

Annotorious 的选框和编辑器都是可以使用 css 设置样式的。
选框部分使用了 SVG ,编辑器部分直接用了 HTML 元素。
对 SVG 不了解的工友可以阅读 《SVG专栏》。
回到 Annotorious ,官方也有给出一个自定义样式的案例 《Customizing Visual Appearance》。

上面这份代码选框的样式是从 Annotorious 官网教程搬过来的。
编辑器的样式我随便配了一下,工友们也可以打开浏览器控制台看 Elements 面板的 HTML 代码,根据结构去修改样式即可。
输入时需要快速添加预选项时,可以这样配置:

使用 setDrawingTool(toolName) 方法可以设置不同的绘制工具。
如果需要讲选框设置成多边形,可以传入 'polygon'。

想要知道当前有哪些绘图工具,可以使用 anno.listDrawingTools() 方法查看

除了上面介绍到的 API 外,Annotorious 还有很多玩法的,比如删除指定注释、清空所有注释等。
详情请看 《annotorious API文档》
Annotorious 也有一些好玩的插件,有兴趣的可以看看 《Annotorious 插件推荐》。
👍《OpenLayers.js 入门教程:打造互动地图的入门指南》
点赞 + 关注 + 收藏 = 学会了 代码仓库