【今天我必须发一个封面!放文末!】
最近有工友问我前端怎么给图片做标注。使用 Fabric.js 或者 Konva.js 等库确实可以实现,但多少觉得有点大炮打蚊的感觉,好奇有没有专门做图片标注的工具呢?
在网上搜了一下发现 Annotorious 可以实现这个功能。Annotorious 提供了图片注释和标注功能,而且用法很简单。
本文分为 【快速入门】和【API讲解】两部分。
【快速入门】部分包含 Annotorious 的安装、使用、导入导出的讲解。这几点应该是项目中比较核心的流程,给希望快速入门的工友提供一丢丢帮助。
【API讲解】这部分主要讲一下我认为比较常用的功能。注意:是“我认为”。
快速入门部分会讲解Annotorious 的安装、使用、导入和导出数据功能。
<!-- 引入样式 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@recogito/annotorious@2.7.10/dist/annotorious.min.css">
<!-- 引入js -->
<script src="https://cdn.jsdelivr.net/npm/@recogito/annotorious@2.7.10/dist/annotorious.min.js"></script>
你可以把这两份文件下载到自己的项目里再引入。
用以下命令安装 Annotorious
npm install @recogito/annotorious
然后在项目中引入
import { Annotorious } from '@recogito/annotorious'
import '@recogito/annotorious/dist/annotorious.min.css'
把 Annotorious 安装到项目后就可以使用了。
Annotorious 的用法很简单,只需做以下2步:
CDN 和 NPM 在初始化时的用法稍微有点不同。
<img src="./img.jpg" id="my-image" />
<script>
let anno = Annotorious.init({
image: 'my-image' // 元素ID
})
</script>
使用 CDN 的方式引入 Annotorious,在初始化时要 Annotorious.init 这样写。
<img src="./img.jpg" id="my-image" />
<script>
const anno = new Annotorious({
image: document.getElementById('my-image') // 元素本身
})
</script>
使用 NPM 的方式引入 Annotorious 在初始化时需要 new Annotorious 这样写。
注意:在 Annotorious 初始化代码最好放在你所使用的框架的页面加载完成后的生命周期函数里!
如果你需要将图片上的标注保存到服务器,就需要把数据导出。
所用到的方法是 getAnnotations()。
<button onclick="save()">保存</button>
<img src="./44.jpg" id="img" />
<script>
let anno = null
onload = function() {
anno = Annotorious.init({
image: 'img'
})
}
function save() {
let res = anno.getAnnotations()
console.log(res)
}
</script>
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) 方法把数据渲染出来即可。
<button onclick="load()">加载</button>
<img src="./44.jpg" id="img" />
<script>
let anno = null
onload = function() {
anno = Annotorious.init({
image: 'img'
})
}
function load() {
anno.loadAnnotations("http://127.0.0.1:5500/data.json")
}
</script>
点击加载按钮后,图片上就会出现一个选框,点击选框可以看到数据已经成功加载出来。
但在实际项目中,后台不一定会给前端返回一个文件地址,后台可能会直接返回一个json数据。
这时候如果使用 loadAnnotations() 方法加载 json 数据是行不通的,要通过遍历读取数据中心的 data 里的数据,然后调用 addAnnotation() 方法将元素添加到页面。
我使用 json-server 简单的在本地搭建一个服务器给前端访问对应的资源,前端用 axios 请求资源。
<button onclick="load()">加载</button>
<img src="./44.jpg" id="img" />
<script>
let anno = null
onload = function() {
anno = Annotorious.init({
image: 'img'
})
}
function load() {
axios.get('http://localhost:3000/anno')
.then(res => {
res.data.data.forEach(item => {
anno.addAnnotation(item)
})
})
}
</script>
很久之前写过一篇 《『前端必备』本地数据接口 —— json-server 从入门到膨胀》 文章介绍 json-server 的基础用法,有兴趣的工友可以去瞧瞧。
这部分主要讲一些我关注到的功能,如果想全面了解 Annotorious 可以查看文档。
Annotorious 是根据浏览器的设置来确定使用哪种语言。
如果需要修改 Annotorious 使用的语言,可以在初始化时配置一下 locale 字段。
比如配置简体中文可以用 zh-CN,配置繁体中文可以用 zh-TW。
<img src="./img.jpg" id="my-image" />
<script>
let anno = Annotorious.init({
image: 'my-image',
locale: 'zh-CN' // 修改语言
})
</script>
如果想自定义按钮或者输入框的提示文本可以配置 messages 。
<img src="./img.jpg" id="my-image" />
<script>
// 创建一个包含自定义消息的对象
var customMessages = {
"Add a comment...": "评论评论",
"Add a reply...": "回复两句",
"Add tag...": "这是标签啊",
"Cancel": "取消",
"Close": "关闭",
"Edit": "编辑~",
"Delete": "删除❌",
"Ok": "确定"
}
let anno = Annotorious.init({
image: 'my-image',
messages: customMessages // 自定义消息内容
})
</script>
如果同时配置了 locale 和 messages ,会优先使用 message 的值。
默认情况下,如果框选后没输入标签或者评论就按确定是不会保存选框的。
如果想保存空选框,可以将 allowEmpty 设置为 true 。
<img src="./img.jpg" id="my-image" />
<script>
let anno = Annotorious.init({
image: 'my-image',
allowEmpty: true // 允许空注释
})
</script>
有些鼠标指针可能并不是那么标准,会影响你框选的准确性。
如果需要非常准确去框选,可以开启辅助线功能,只需将 crosshair 设置为 true 即可。
<img src="./img.jpg" id="my-image" />
<script>
let anno = Annotorious.init({
image: 'my-image',
crosshair: true // 开启辅助线
})
</script>
如果不打算提供框选、添加和删除信息的操作给用户,可以将 readOnly 设置为 true 。
<img src="./img.jpg" id="my-image" />
<script>
let anno = Annotorious.init({
image: 'my-image',
readOnly: true // 只读模式
})
</script>
如果只需要画框框,不需要写注释,可以将 disableEditor 和 allowEmpty 同时设置为 true。
<img src="./img.jpg" id="my-image" />
<script>
let anno = Annotorious.init({
image: 'my-image',
allowEmpty: true, // 允许空注释
disableEditor: true // 禁用编辑
})
</script>
为什么要同时将 allowEmpty 设为 true ?
因为如果你不允许注释为空的话,当你点击空白处时选框就会消失。
将 disableSelect 设置为 true 后,画布上的选框就无法再次选中了。
<img src="./img.jpg" id="my-image" />
<script>
let anno = Annotorious.init({
image: 'my-image',
disableSelect: true // 禁止选中选框
})
</script>
虽然还没想到有什么引用场景,但还是打算记录一下。
箭头所指的就是手柄。
手柄的默认半径是6。如果需要修改手柄半径可以设置 handleRadius 属性。
<img src="./img.jpg" id="my-image" />
<script>
let anno = Annotorious.init({
image: 'my-image',
handleRadius: 20 // 设置手柄半径
})
</script>
Annotorious 的选框和编辑器都是可以使用 css 设置样式的。
选框部分使用了 SVG ,编辑器部分直接用了 HTML 元素。
对 SVG 不了解的工友可以阅读 《SVG专栏》。
回到 Annotorious ,官方也有给出一个自定义样式的案例 《Customizing Visual Appearance》。
<style>
/* 选框 */
/* 隐藏外部形状-对于这种风格,我们只需要一个 */
svg.a9s-annotationlayer .a9s-selection .a9s-outer,
svg.a9s-annotationlayer .a9s-annotation .a9s-outer {
display:none;
}
svg.a9s-annotationlayer .a9s-handle .a9s-handle-outer {
display:none;
}
/* 虚线边框 */
svg.a9s-annotationlayer .a9s-selection .a9s-inner,
svg.a9s-annotationlayer .a9s-annotation .a9s-inner {
stroke-width:4;
stroke:white;
stroke-dasharray:5;
}
/* 选中时的填充色 */
svg.a9s-annotationlayer .a9s-annotation.editable:hover .a9s-inner {
fill:transparent;
}
/* 手柄颜色 */
svg.a9s-annotationlayer .a9s-handle .a9s-handle-inner {
fill:white;
stroke:white;
}
/* 选中选框时,遮罩层颜色 */
svg.a9s-annotationlayer .a9s-selection-mask {
fill:rgba(0, 0, 0, 0.6);
}
/* 编辑器 */
/* 容器 */
.r6o-editor .r6o-editor-inner {
box-sizing: border-box;
padding: 10px;
border-radius: 6px;
background: #F4F2DE;
}
/* 箭头 */
.r6o-editor .r6o-arrow:after {
background-color: #F4F2DE;
}
/* 编辑器 */
.r6o-widget.comment.editable,
.r6o-widget.r6o-tag {
background-color: #EEE3CB;
}
.r6o-widget.comment {
background-color: #D7C0AE;
}
.r6o-editor .r6o-editor-inner .r6o-widget {
border-bottom-color: #7C9D96;
}
.r6o-editor .r6o-editor-inner .r6o-widget.r6o-tag {
border-bottom: none;
}
/* 按钮 */
.r6o-editor .r6o-btn {
border-radius: 100px;
background-color: #7C9D96;
border-color: #7C9D96;
color: #fff;
}
/* 线框按钮 */
.r6o-editor .r6o-btn.outline {
color: #7C9D96;
background-color: transparent;
}
</style>
<img src="./img.jpg" id="my-image" />
<script>
let anno = Annotorious.init({
image: 'my-image',
locale: 'zh-CN' // 修改语言
})
</script>
上面这份代码选框的样式是从 Annotorious 官网教程搬过来的。
编辑器的样式我随便配了一下,工友们也可以打开浏览器控制台看 Elements 面板的 HTML 代码,根据结构去修改样式即可。
输入时需要快速添加预选项时,可以这样配置:
<img src="./img.jpg" id="my-image" />
<script>
let anno = Annotorious.init({
image: 'my-image',
widgets: [
'COMMENT',
{ widget: 'TAG', vocabulary: [ '雷猴', '鲨鱼辣椒', '蝎子莱莱'] }
]
})
</script>
使用 setDrawingTool(toolName) 方法可以设置不同的绘制工具。
如果需要讲选框设置成多边形,可以传入 'polygon'。
<img src="./img.jpg" id="my-image" />
<script>
let anno = Annotorious.init({
image: 'my-image'
})
anno.setDrawingTool("polygon")
</script>
想要知道当前有哪些绘图工具,可以使用 anno.listDrawingTools() 方法查看
<img src="./img.jpg" id="my-image" />
<script>
let anno = Annotorious.init({
image: 'my-image'
})
const toolNames = anno.listDrawingTools()
console.log(toolNames)
</script>
除了上面介绍到的 API 外,Annotorious 还有很多玩法的,比如删除指定注释、清空所有注释等。
详情请看 《annotorious API文档》
Annotorious 也有一些好玩的插件,有兴趣的可以看看 《Annotorious 插件推荐》。
《提升日期处理效率:day.js 实战经验分享》
《OpenLayers.js 入门教程:打造互动地图的入门指南》
《物理世界的互动之旅:Matter.js入门指南》
《p5.js 光速入门》
《眨个眼就学会了Pixi.js》
《Fabric.js 从入门到膨胀》
点赞 + 关注 + 收藏 = 学会了
明:SVG 虽然也是标签,但它不是 HTML5,标题加了 HTML5 只是为了与 canvas 放到一起。
SVG 意为可缩放矢量图形(Scalable Vector Graphics),使用 XML 格式定义矢量图形。其他的图像格式都是基于像素的,但是 SVG 没有单位的概念,它的20只是表示1的20倍,所以 SVG 绘制的图形放大或缩小都不会失真。
与其他图像比较,SVG 的优势有以下几点:
2.1、svg 标签
SVG 的代码都放到 svg 标签呢,SVG 中的标签都是闭合标签,与html中标签用法一致。svg的属性有:
eg:画一条直线,完整代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body style="height:600px;">
<svg width="300" height="300">
<line x1="0" y1="0" x2="100" y2="100" stroke="black" stroke-width="20"></line>
</svg>
</body>
</html>
上述 svg 设置的宽高没有带单位,此时默认是像素值,如果需要添加单位时,除了绝对单位,也可以设置相对单位。
使用语法:<svg viewBox=" x1,y1,width,height "></svg>
四个参数分别是左上角的横纵坐标、视口的宽高。表示只看SVG的某一部分,由上述四个参数决定。
使用 viewBox 之后,相当于svg整体大小不变,只能看到 viewBox 设置部分,视觉上被放大。
2.2、SVG 如何嵌入 HTML
SVG 的代码可以直接嵌入到 html 页面中,也可以通过 html 的embed、object、iframe嵌入到html中。嵌入的时候嵌入的是 SVG 文件,SVG 文件必须使用 .svg 后缀。分别介绍各种方法如何使用?
2.2.1、embed 嵌入:
使用语法:<embed src="line.svg" type="image/svg+xml"></embed>
src是SVG文件路径,type 表示 embed 引入文件类型。
优点:所有浏览器都支持,并允许使用脚本。
缺点:不推荐 html4 和 html 中使用,但 html5 支持。
2.2.2、object 嵌入:
使用语法:<object data="line.svg" type="image/svg+xml"></object>
data 是 SVG 文件路径,type 表示 object 引入文件类型。
优点:所有浏览器都支持,支持 html、html4 和 html5。
缺点:不允许使用脚本。
2.2.3、iframe 嵌入:
使用语法:<iframe width="300" height="300" src="./line.svg" frameborder="0"></iframe>
src是 SVG 文件路径,width、height、frameborder 设置的大小和边框。
优点:所有浏览器都支持,并允许使用脚本。
缺点:不推荐 html4 和 html 中使用,但 html5 支持。
2.2.4、html中嵌入:
svg 标签直接插入 html 内容内,与其他标签用法一致。
2.2.5、连接到svg文件:
使用 a 标签,直接链接到 SVG 文件。
使用语法:<a href="line.svg">查看SVG</a>
3.1、线 - line
使用语法:
<svg width="300" height="300" >
<line x1="0" y1="0" x2="300" y2="300" stroke="black" stroke-width="20"></line>
</svg>
使用line标签创建线条,(x1,y1)是起点,(x2,y2)是终点,stroke绘制黑线,stroke-width是线宽。
3.2、矩形 - rect
//使用语法:
<svg width="300" height="300" >
<rect
width="100" height="100" //大小设置
x="50" y="50" //可选 左上角位置,svg的左上角默认(0,0)
rx="20" ry="50" //可选 设置圆角
stroke-width="3" stroke="red" fill="pink" //绘制样式控制
></rect>
</svg>
上述参数 width、height是必填参数,x、y是可选参数,如不设置的时候,默认为(0,0),也就是svg的左上角开始绘制。rx、ry是可选参数,不设置是矩形没有圆角。fill定义填充颜色。
3.3、圆形 - circle
// 使用语法
<svg width="300" height="300" >
<circle
cx="100" cy="50" // 定义圆心 ,可选
r="40" // 圆的半径
stroke="black" stroke-width="2" fill="red"/> //绘制黑框填充红色
</svg>
上述(cx,xy)定义圆心的位置,是可选参数,如果不设置默认圆心是(0,0)。r是必需参数,设置圆的半径。
3.4、椭圆 - ellipse
椭圆与圆相似,不同之处在于椭圆有不同的x和y半径,而圆两个半径是相同的。
// 使用语法
<svg width="300" height="300" >
<ellipse
rx="20" ry="100" //设置椭圆的x、y方向的半径
fill="purple" // 椭圆填充色
cx="150" cy="150" //设置椭圆的圆心 ,可选参数
></ellipse>
</svg>
上述椭圆的两个rx、ry两个方向半径是必须参数,如果rx=ry就表示是圆形,(cx,cy)是椭圆的圆心,是可选参数,如果不设置,则默认圆心为(0,0)。
3.5、折线 - polyline
// 使用语法
<svg width="300" height="300" style="border:solid 1px red;">
<!-- 绘制出一个默认填充黑色的三角形 -->
<polyline
points=" //点的集合
0 ,0, // 第一个点坐标
100,100, // 第二个点坐标
100,200 // 第三个点坐标
"
stroke="green"
></polyline>
<!-- 绘制一个台阶式的一条折线 -->
<polyline
points="0,0,50,0,50,50,100,50,100,100,150,100,150,150"
stroke="#4b27ff" fill="none"
></polyline>
</svg>
上述代码执行结果如图所示:
需要注意的是 points 中包含了多个点的坐标,但不是一个数组。
3.6、多边形 - polygon
polygon 标签用来创建不少于3个边的图形,多边形是闭合的,即所有线条连接起来。
// 使用语法
<svg width="300" height="300" style="border:solid 1px red;">
<polygon
points="
0,0, //多边形的第一点
100,100, //多边形的第二点
0,100 //多边形的第三点
"
stroke="purple"
stroke-width="1"
fill="none"
></polygon>
</svg>
polygon绘制的时候与折线有些类似,但是polygon会自动闭合,折线不会。
3.7、路径 - path
path 是SVG基本形状中最强大的一个,不仅能创建其他基本形状,还能创建更多其他形状,如贝塞尔曲线、2次曲线等。
点个关注,下篇更精彩!
视觉内容常常能提升文档、演示文稿和报告所要传达的信息。在线办公套件 ONLYOFFICE 支持一系列图形对象和工具,助您创建引人入胜、细致周密的视觉效果,无论目标如何,总能吸引受众。
本指南会带您了解这些可用的功能,包括自选图形、图表、SmartArt、绘图、图片编辑、AI 生成的对象等有用的工具。掌握这些工具,即可提升文档的视觉吸引力,有效传达您的想法。
在展示概念、创建图表,或向文档添加视觉元素时,自选图形颇有用武之地。可以在“插入”选项卡中找到自选图形。
ONLYOFFICE 文档中可用的形状包括基本形状、流程图、箭头、标注等。每个类别都包含一系列特定形状,可自行选择,用在文档中。
添加形状后,我们可以使用选择手柄调整形状大小、旋转或移动形状。您也可以通过更改填充颜色、渐变或图片、线条颜色和线条样式,来对形状的外观做自定义设置。这些都可以通过右侧栏上可用的格式选项来实现。
还有一些功能,让使用自选形状更为轻松:用对齐网格可以精准对齐,还可以将形状组合在一起,方便操作。
甚至可以通过对自选图形指定宏,让自选图形可以实现交互。在文档中点击自选图形、执行操作时,此设置会启动所选脚本。
此外,还可以将任意对象保存为图片,包括自选图形、图表等,这样未来可以在其他文档中重复使用。
您可以使用“插入”选项卡中的图表,为统计信息、数字及趋势增加视觉展现形式。ONLYOFFICE 中可用的图表类型包括柱形图、条形图、折线图和饼图等诸多变体。
我们可以在电子表格中选择要在图表中展现的数据范围,就其外观做自定义设置,包括标题、标签和图例。还可以调整大小、重定位、更新和编辑图表数据。
还可以就图表中的每个元素,使用自动形状设置分别做自定义设置。这样,只要您有足够的时间,就可以构建非常独特、完全自定义的图表,随心设置填充和描边参数。
通过 ONLYOFFICE 中集成的 Draw.io 服务,图表构建可以易如反掌。您可以通过 ONLYOFFICE 文档中的插件,使用 Draw.io 丰富的形状和模板库,轻松实现复杂想法、过程和工作流可视化;您可以根据自己的喜好添加和编辑这些形状和模板:流程图、思维导图、组织结构图、维恩图、信息图、网络和架构图、UML 关系图等。
可以使用 SmartArt,创建更具视觉吸引力的图表和图形,提升文档和演示文稿的效果。可以在“插入”选项卡中找到 SmartArt。
SmartArt 非常方便:不需要拥有完美的眼力或设计技能,也可以构建准确、合乎逻辑的方案。只要有想法,只需从多个可用预设中进行选择即可:流程、循环、层次结构、关系、矩阵、棱锥图等。每个类别都包含一系列特定的 SmartArt 图形,可以结合自己的目的选用。
与自选图形一样,您还可以自定义和配置 SmartArt 项目,更改颜色、样式和布局,对齐和分组对象等等。
从版本 7.4开始,ONLYOFFICE 增加了绘图功能,可以使用笔或荧光笔工具创建自己的手绘草图。如要使用此功能,请转到新增的“绘图”选项卡。在文本文档、电子表格和演示文稿中也有这个选项卡。
绘图时,可以选择喜欢的颜色和线条粗细。为了让颜色选择更方便,我们在编辑器中加入了颜色名称提示和取色器工具。取色器可以自动识别、在调色板中匹配到所需的颜色。
可以插入 BMP、GIF、JPEG、JPG 或 PNG 等常用格式的图片,在文档中对它们的位置、大小和对齐方式进行配置。
可以通过照片编辑器插件,用滑块或数字输入来调整图片的亮度、对比度、饱和度和清晰度。还有更多选项,如裁剪、旋转和翻转图片等。
可以对图片应用各种滤镜和效果:从一系列艺术滤镜中选择,如棕褐、灰度和油画,也可以应用模糊、阳文等效果。
除编辑功能外,照片编辑器还支持在图片中添加文本或形状选项。您可以插入文本框、形状或标注,通过选择字体样式、大小和颜色对它们的外观做自定义设置。
您也可以让 AI 为您工作。可以使用 AI 插件,要求人工智能插入一个对象的 HTML 代码,如图片或表格,给它一些提示,比如图片或表格应该是什么样子的。在正确的提示下,它可以在文档中生成一个适合的对象。
此外,还可以让它基于文本生成图片。从版本 7.4 起,便可以在文本上下文菜单中看到这一功能。
如果文档中有代码,又不想让它与文本的其余部分混起来,要让代码更为突出、更容易被识别出,可以使用“突出显示代码”插件。只需选择代码、选择语言,这个插件就会自动将其格式设置为适合的字体和颜色。
我们可以使用在线办公套件 | ONLYOFFICE 中一系列图形对象,轻松创建具有视觉吸引力、富有感染力的文档:自选图形、图表、SmartArt、手绘草图、图片编辑、AI 生成的对象和突出显示代码。而其集成的 Draw.io 和照片编辑器插件,还可助拓展更多创意可能。
*请认真填写需求信息,我们会在24小时内与您取得联系。