前言
我的 "關於 PoE 以及 Raspberry Pi 的 PoE" 這一篇貼文裡, 有來自 "維基百科" 的三張 Raspberry Pi 的照片及一張從網路搜來的圖片. 而我, 需要在它們上頭作一些標記. 由於圖片已經上傳到 pixnet 了, 不想用小畫家改圖後再重新上傳, 於是突發奇想: 是否可以在貼文中直接利用 HTML 語法將 SVG 疊在它們上面?
可是一直無法在網路上找到相關主題的貼文, StackOverflow 也搜不到類似的問題解答 (可能是搜尋時使用的 keyword 不對??), 所以就先放著. 最近得空, 總算自己把它解決了. 故有此篇記錄如何解決.
方法一: 原先的想法
更新 2024/10/01
今日發現一個問題, 使用手機查看本篇時, 圖2.原本可以放大的功能消失了. 仔細檢查後發現, <label> tag 手機的瀏覽器裡不能放入諸如 <div> tag 等原本顯示屬性為 block 的 HTML tag (但是 PC 桌機卻可以! Why~~~?). 基於上述原因這一段 HTML tag 的順序被打亂了, 所以我的 CSS 作用不到它上頭. 不過還好, 還有方法二可用.
先來看前後對照: 左側 (圖1.) 是原始圖片, 右側 (圖2.) 則是疊了一張用 SVG 畫的紅色方型標記.
如各位看到的, 和我原本在貼文中的圖片樣式完全相容. 右側 (圖2.) 圖片在放大縮小時 (PC 版), 底圖和疊在上面的 SVG 完全看不出是二張圖片.
下面是左側 (圖1.) 圖片的 HTML:
<div class='img_cel' style='width:45%'>
<label><input type="checkbox" />
<img class='img_tag left' src='https://pic.pimg.tw/magicjackting/1719323053-314073596-g_l.png' title='Raspberry Pi 3B+' alt='Raspberry Pi 3B+' />
<p class='img_dsc'>Pi 3B+<br />(來源: <a href='https://en.wikipedia.org/wiki/Raspberry_Pi#/media/File:Raspberry_Pi_3_B+_(39906369025).png'>維基百科</a>)</p>
</label></div>
再來是右側 (圖2.) 圖片的 HTML:
<div class='img_cel' style='width:45%'>
<label><input type="checkbox" />
<div class='img_tag right' title='Raspberry Pi 3B+' style='background: url(https://pic.pimg.tw/magicjackting/1719323053-314073596-g_l.png) no-repeat; background-size: 100%'>
<svg version="1.2" viewBox="0 0 1024 665" width="100%">
<g transform='translate(675, 72)'>
<path stroke='white' fill='none' stroke-width='9' d="M 0,5 V65 L5,70 H65 L70,65 V5 L65,0 H5 Z" />
<path stroke='red' fill='none' stroke-width='7' d="M 0,5 V65 L5,70 H65 L70,65 V5 L65,0 H5 Z" />
</g>
</svg>
</div>
<p class='img_dsc'>Pi 3B+<br />(來源: <a href='https://en.wikipedia.org/wiki/Raspberry_Pi#/media/File:Raspberry_Pi_3_B+_(39906369025).png'>維基百科</a>)</p>
</label></div>
- 由於 pixnet 的相簿並不支援 SVG 上傳, 同時這張 SVG 圖片也很小, 所以我選擇直接將 SVG 內容置於貼文. (第 4~9 行)
- 這裡我將原先的 <img /> tag (第 3 行) 換成上述 SVG 圖片, 並用一個 <div> tag (第 3 行, 第 10 行) 來包住它. 同時, 把原先的 <img /> tag 的圖片當作它 (<div> tag) 的底圖 (background).
- 另外, <img /> tag 裡有 title, alt 二個屬性.
- 由於 alt 屬性是圖片 <img /> tag 獨有的, 於是我就把它刪了.
- 至於 title 屬性, 可以直接放在新加的 <div> tag 裡; 也可以放在它的上一層: <div class='img_cel'> tag 裡.
效果和原先一樣: 滑鼠游標停在圖片上面時會出現一個小框框顥示 title 屬性的內容. - 最後是 SVG 的相關數值. 這裡要注意的只有 viewBox 的設定數值: viewbox="min-x min-y width height". 為了簡化設定, min-x 和 min-y 我都使用 0; 至於 width 和 height 各位可以先取得作為底圖圖片的 "長度x高度" 的像素值, 然後取二個比值大約相同的整數. 我的圖片是 3323x2158 px, 所以我取用 1024x665.
- 至於用什麼工具作圖, 則各位自便 (我是用 vs code 搭配插件 SVG Editor, 直接手動撰寫 SVG 的內容).
方法二: 研究改進後
除了上述的使用 <div> tag 來包住 SVG 的作法之外, 其實 SVG 本身就可以完成這件事: SVG 檔案裡也是可以放 <image /> tag 的. 直接將圖片嵌在 SVG 檔的 HTML 如下:
<div class='img_cel' style='width:45%'>
<label><input type="checkbox" />
<svg class='img_tag left' version="1.2" viewBox="0 0 1024 665" width="100%">
<title>PoE Head position of Raspberry Pi 3B+</title>
<image href="https://pic.pimg.tw/magicjackting/1719323053-314073596-g_l.png" x="0" y="0" width="100%" />
<g transform='translate(675, 72)'>
<path stroke='white' fill='none' stroke-width='9' d="M 0,5 V65 L5,70 H65 L70,65 V5 L65,0 H5 Z" />
<path stroke='red' fill='none' stroke-width='7' d="M 0,5 V65 L5,70 H65 L70,65 V5 L65,0 H5 Z" />
</g>
</svg>
<p class='img_dsc'>Pi 3B+<br />(來源: <a href='https://en.wikipedia.org/wiki/Raspberry_Pi#/media/File:Raspberry_Pi_3_B+_(39906369025).png'>維基百科</a>)</p>
</label></div>
這個方法, 和上一種的差異為:
- 不額外用一個 <div> tag 包住 SVG, 只是單純把 <img /> tag 換成 SVG. 然後把原本的 <img /> tag 轉換成 SVG 的 <image /> tag, 放在 SVG 裡.
- 由於 SVG 圖檔有圖層的概念, 放在前頭的圖形元素先被繪出 (render), 然後一層一層往上疊. 所以這個要作為底圖的 <image /> tag 必需放在紅色方型標記圖形的前面.
- 由於 title 屬性放在 svg tag 裡是無效的, 不過也有二種替代方式:
- 改放到它的上層 <div class='img_cel'> tag 裡.
- 轉成 <title> tag 放在 SVG 裡. (建議用這個)
效果如下: