Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
最近有工友問我前端怎么給圖片做標(biāo)注。使用 Fabric.js 或者 Konva.js 等庫確實(shí)可以實(shí)現(xiàn),但多少覺得有點(diǎn)大炮打蚊的感覺,好奇有沒有專門做圖片標(biāo)注的工具呢?
在網(wǎng)上搜了一下發(fā)現(xiàn) Annotorious 可以實(shí)現(xiàn)這個功能。Annotorious 提供了圖片注釋和標(biāo)注功能,而且用法很簡單。
本文分為 【快速入門】和【API講解】兩部分。
【快速入門】部分包含 Annotorious 的安裝、使用、導(dǎo)入導(dǎo)出的講解。這幾點(diǎn)應(yīng)該是項(xiàng)目中比較核心的流程,給希望快速入門的工友提供一丟丟幫助。
【API講解】這部分主要講一下我認(rèn)為比較常用的功能。注意:是“我認(rèn)為”。
快速入門部分會講解Annotorious 的安裝、使用、導(dǎo)入和導(dǎo)出數(shù)據(jù)功能。
<!-- 引入樣式 -->
<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>
你可以把這兩份文件下載到自己的項(xiàng)目里再引入。
用以下命令安裝 Annotorious
npm install @recogito/annotorious
然后在項(xiàng)目中引入
import { Annotorious } from '@recogito/annotorious'
import '@recogito/annotorious/dist/annotorious.min.css'
把 Annotorious 安裝到項(xiàng)目后就可以使用了。
Annotorious 的用法很簡單,只需做以下2步:
CDN 和 NPM 在初始化時(shí)的用法稍微有點(diǎn)不同。
<img src="./img.jpg" id="my-image" />
<script>
let anno = Annotorious.init({
image: 'my-image' // 元素ID
})
</script>
使用 CDN 的方式引入 Annotorious,在初始化時(shí)要 Annotorious.init 這樣寫。
<img src="./img.jpg" id="my-image" />
<script>
const anno = new Annotorious({
image: document.getElementById('my-image') // 元素本身
})
</script>
使用 NPM 的方式引入 Annotorious 在初始化時(shí)需要 new Annotorious 這樣寫。
注意:在 Annotorious 初始化代碼最好放在你所使用的框架的頁面加載完成后的生命周期函數(shù)里!
如果你需要將圖片上的標(biāo)注保存到服務(wù)器,就需要把數(shù)據(jù)導(dǎo)出。
所用到的方法是 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() 方法加載數(shù)據(jù)。
loadAnnotations(url) 支持傳入一個 URL 參數(shù),這個 URL 所指的是數(shù)據(jù)文件地址。
比如我在本地創(chuàng)建一個 data.json 文件,文件內(nèi)容是使用前面講到的 getAnnotations() 方法導(dǎo)出的數(shù)據(jù),我的數(shù)據(jù)內(nèi)容如下:
[
{
"@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"
}
]
在本地測試時(shí),我使用了本地服務(wù)器把 data.json 管理起來,在瀏覽器可以通過 http://127.0.0.1:5500/data.json 訪問到該文件。
然后再使用 loadAnnotations(url) 方法把數(shù)據(jù)渲染出來即可。
<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>
點(diǎn)擊加載按鈕后,圖片上就會出現(xiàn)一個選框,點(diǎn)擊選框可以看到數(shù)據(jù)已經(jīng)成功加載出來。
但在實(shí)際項(xiàng)目中,后臺不一定會給前端返回一個文件地址,后臺可能會直接返回一個json數(shù)據(jù)。
這時(shí)候如果使用 loadAnnotations() 方法加載 json 數(shù)據(jù)是行不通的,要通過遍歷讀取數(shù)據(jù)中心的 data 里的數(shù)據(jù),然后調(diào)用 addAnnotation() 方法將元素添加到頁面。
我使用 json-server 簡單的在本地搭建一個服務(wù)器給前端訪問對應(yīng)的資源,前端用 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>
很久之前寫過一篇 《『前端必備』本地?cái)?shù)據(jù)接口 —— json-server 從入門到膨脹》 文章介紹 json-server 的基礎(chǔ)用法,有興趣的工友可以去瞧瞧。
這部分主要講一些我關(guān)注到的功能,如果想全面了解 Annotorious 可以查看文檔。
Annotorious 是根據(jù)瀏覽器的設(shè)置來確定使用哪種語言。
如果需要修改 Annotorious 使用的語言,可以在初始化時(shí)配置一下 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>
// 創(chuàng)建一個包含自定義消息的對象
var customMessages = {
"Add a comment...": "評論評論",
"Add a reply...": "回復(fù)兩句",
"Add tag...": "這是標(biāo)簽啊",
"Cancel": "取消",
"Close": "關(guān)閉",
"Edit": "編輯~",
"Delete": "刪除?",
"Ok": "確定"
}
let anno = Annotorious.init({
image: 'my-image',
messages: customMessages // 自定義消息內(nèi)容
})
</script>
如果同時(shí)配置了 locale 和 messages ,會優(yōu)先使用 message 的值。
默認(rèn)情況下,如果框選后沒輸入標(biāo)簽或者評論就按確定是不會保存選框的。
如果想保存空選框,可以將 allowEmpty 設(shè)置為 true 。
<img src="./img.jpg" id="my-image" />
<script>
let anno = Annotorious.init({
image: 'my-image',
allowEmpty: true // 允許空注釋
})
</script>
有些鼠標(biāo)指針可能并不是那么標(biāo)準(zhǔn),會影響你框選的準(zhǔn)確性。
如果需要非常準(zhǔn)確去框選,可以開啟輔助線功能,只需將 crosshair 設(shè)置為 true 即可。
<img src="./img.jpg" id="my-image" />
<script>
let anno = Annotorious.init({
image: 'my-image',
crosshair: true // 開啟輔助線
})
</script>
如果不打算提供框選、添加和刪除信息的操作給用戶,可以將 readOnly 設(shè)置為 true 。
<img src="./img.jpg" id="my-image" />
<script>
let anno = Annotorious.init({
image: 'my-image',
readOnly: true // 只讀模式
})
</script>
如果只需要畫框框,不需要寫注釋,可以將 disableEditor 和 allowEmpty 同時(shí)設(shè)置為 true。
<img src="./img.jpg" id="my-image" />
<script>
let anno = Annotorious.init({
image: 'my-image',
allowEmpty: true, // 允許空注釋
disableEditor: true // 禁用編輯
})
</script>
為什么要同時(shí)將 allowEmpty 設(shè)為 true ?
因?yàn)槿绻悴辉试S注釋為空的話,當(dāng)你點(diǎn)擊空白處時(shí)選框就會消失。
將 disableSelect 設(shè)置為 true 后,畫布上的選框就無法再次選中了。
<img src="./img.jpg" id="my-image" />
<script>
let anno = Annotorious.init({
image: 'my-image',
disableSelect: true // 禁止選中選框
})
</script>
雖然還沒想到有什么引用場景,但還是打算記錄一下。
箭頭所指的就是手柄。
手柄的默認(rèn)半徑是6。如果需要修改手柄半徑可以設(shè)置 handleRadius 屬性。
<img src="./img.jpg" id="my-image" />
<script>
let anno = Annotorious.init({
image: 'my-image',
handleRadius: 20 // 設(shè)置手柄半徑
})
</script>
Annotorious 的選框和編輯器都是可以使用 css 設(shè)置樣式的。
選框部分使用了 SVG ,編輯器部分直接用了 HTML 元素。
對 SVG 不了解的工友可以閱讀 《SVG專欄》。
回到 Annotorious ,官方也有給出一個自定義樣式的案例 《Customizing Visual Appearance》。
<style>
/* 選框 */
/* 隱藏外部形狀-對于這種風(fēng)格,我們只需要一個 */
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;
}
/* 選中時(shí)的填充色 */
svg.a9s-annotationlayer .a9s-annotation.editable:hover .a9s-inner {
fill:transparent;
}
/* 手柄顏色 */
svg.a9s-annotationlayer .a9s-handle .a9s-handle-inner {
fill:white;
stroke:white;
}
/* 選中選框時(shí),遮罩層顏色 */
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 官網(wǎng)教程搬過來的。
編輯器的樣式我隨便配了一下,工友們也可以打開瀏覽器控制臺看 Elements 面板的 HTML 代碼,根據(jù)結(jié)構(gòu)去修改樣式即可。
輸入時(shí)需要快速添加預(yù)選項(xiàng)時(shí),可以這樣配置:
<img src="./img.jpg" id="my-image" />
<script>
let anno = Annotorious.init({
image: 'my-image',
widgets: [
'COMMENT',
{ widget: 'TAG', vocabulary: [ '雷猴', '鯊魚辣椒', '蝎子萊萊'] }
]
})
</script>
使用 setDrawingTool(toolName) 方法可以設(shè)置不同的繪制工具。
如果需要講選框設(shè)置成多邊形,可以傳入 'polygon'。
<img src="./img.jpg" id="my-image" />
<script>
let anno = Annotorious.init({
image: 'my-image'
})
anno.setDrawingTool("polygon")
</script>
想要知道當(dāng)前有哪些繪圖工具,可以使用 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文檔》
https://annotorious.github.io/api-docs/annotorious/
Annotorious 也有一些好玩的插件,有興趣的可以看看 《Annotorious 插件推薦》。
https://annotorious.github.io/plugins/
點(diǎn)贊 + 關(guān)注 + 收藏 = 學(xué)會了
HTML標(biāo)題通過<h1>-<h6>
標(biāo)題大小與字體大小的關(guān)系:1到6號標(biāo)題與1到6號字體是逆序?qū)?yīng)
實(shí)例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>文檔標(biāo)題</title>
</head>
<body>
<h1>標(biāo)題1</h1>
<h2>標(biāo)題2</h2>
</body>
</html>
HTML段落是通過標(biāo)簽<p>來定義
實(shí)例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>文檔標(biāo)題</title>
</head>
<body>
<p>段落1</p>
<p>段落2</p>
</body>
</html>
HTML鏈接是通過標(biāo)簽<a>來定義的
實(shí)例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>文檔標(biāo)題</title>
</head>
<body>
<a href = "https://www.baidu.com"> 這是一個鏈接</a>
</body>
</html>
HTML通過標(biāo)簽<img>來定義
實(shí)例:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>文檔標(biāo)題</title>
</head>
<body>
<img src="/images/logo.png" width="258" height="39" />
</body>
</html>
大多數(shù)HTML元素的屬性:
屬性 | 描述 |
class | 為html元素定義一個或多個類名(classname)(類名從樣式文件引入) |
id | 定義元素的唯一id |
style | 規(guī)定元素的行內(nèi)樣式(inline style) |
title | 描述了元素的額外信息 (作為工具條使用) |
<hr>標(biāo)簽在HTML頁面中創(chuàng)建水平線
hr元素可用于分隔內(nèi)容
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>文檔標(biāo)題</title>
</head>
<body>
<p>hr 標(biāo)簽定義水平線:</p>
<hr />
<p>這是段落。</p>
<hr />
<p>這是段落。</p>
<hr />
<p>這是段落。</p>
</body>
</html>
運(yùn)行結(jié)果:
可以將注釋插入 HTML 代碼中,這樣可以提高其可讀性,使代碼更易被人理解。瀏覽器會忽略注釋,也不會顯示它們。
注釋寫法如下:
<!-- 這是一個注釋 -->
*請認(rèn)真填寫需求信息,我們會在24小時(shí)內(nèi)與您取得聯(lián)系。