前端設計應用,豐富圖片的可點擊區域與內容更新 (Image Map & SVG)


  1. ImageMap
  2. SVG
  3. 參考資料

如何在一張圖片,創造出不同連結的點擊區域,達到例如地圖位置、物件連結的效果?又如何讓圖片具有互動性,藉由使用者的輸入來改變圖片?

JavaScript logo

ImageMap

要在圖片創造出不同連結的點擊區域,達到例如地圖位置、物件連結的效果,可以藉由 HTML area 以及 rect Tag 來達到,而這個技術稱為 Image Map

但要直接在圖片中系統性地以座標與面積標註連結不太人性化,因此可以利用 Image Map Generator 的輔助,協助標示座標與連結。

預設情況下 rect 是以絕對座標的方式標註,因此不會配合圖片的縮放自動調整,會造成點擊區域跑掉的問題,這個時候可以使用 Matt Stow 所開發設計的 rwdImageMaps 來讓 rect 自動 RWD,配合圖片的縮放調整點擊區域。

要注意 rwdImageMaps 的載入一定要在 jQuery 之後,此外為避免傳輸時間的問題,造成 jQuery 以及 rwdImageMaps 的載入順序有誤,最好是將 rwdImageMaps 使用在本機的資源複本。

<div style="text-align: center;">
    <img src="dbq2.png" usemap="#image-map" style="width:80%" id="map">
</div>

<map name="image-map">
    <area target="" alt="Furrowfield" title="Furrowfield" href="#island1" coords="1668,547,1278,147" shape="rect">
    <area target="" alt="Khrumbul-Dun" title="Khrumbul-Dun" href="#island2" coords="883,582,1278,963" shape="rect">
    <area target="" alt="Moonbrooke" title="Moonbrooke" href="#island3" coords="598,782,257,298" shape="rect">
</map>

<script src="https://code.jquery.com/jquery-3.6.0.js"></script>
<script src="./rwdImageMaps.js"></script>
<script>
$(document).ready(function (e) {

    $('img#map').rwdImageMaps();
    
    $('area').on('mouseover', function (e) {
        $(this).focus();
    });
});
</script>

DQB2 的大地圖為示範 | 圖片來源:https://imgur.com/a/RzxRRPb

SVG

使用 SVG 的原因在於追求與圖片更高的互動性,可以結合 JS 來達到如同操作 DOM 元素的方式,對圖片進行操作。但前提是使用圖片的方式有所限定,使用 SVG 圖片的方式有三種:

一、使用 img Tag

維護方便如同管理 png, jpg,瀏覽器可以發揮 cache 效果,但無法透過 CSS 或者 JS 來與圖片互動。

<img src="characeter.svg">

二、使用 object Tag

維護方便,瀏覽器可以發揮 cache 效果,可以有限地與外部 CSS 互動。

<object data="character.svg" type="image/svg+xml"></object>

三、使用 inline SVG

維護不方便,SVG 眾多的 Tag 與 HTML 放在一起不好管理與維護,但可以透過 Webpack SVG loader 等機制來克服;瀏覽器無法快取,但有著最棒的互動性,包含使用 CSS 以及 JS 互動。


徒手繪製 SVG 學習成本高,而藉由理想的 SVG Editor 能夠讓編輯 SVG 的工作輕鬆完成。

diagrams.net 原名 draw.io 是開源的線上工具,編輯性高且容易上手,編輯檔案可以重複使用作為 template。例如可以藉由圖層疊加的方式創造互動性,搭配 inline SVG 鑲嵌在網頁,使用 CSS 與 JS 來達成互動。

使用 diagrams.net 編輯 SVG

inline SVG 的內容主動加入 id 方便之後操作。

<image id="i-helmet" x="463.5" y="3.5" width="72" height="72" href="https://via.placeholder.com/72"/>
<image id="i-armor" x="463.5" y="103.5" width="72" height="72" href="https://via.placeholder.com/72"/>
<image id="i-boots" x="463.5" y="303.5" width="72" height="72" href="https://via.placeholder.com/72"/>
<image id="i-gloves" x="463.5" y="203.5" width="72" height="72" href="https://via.placeholder.com/72"/>

實作簡單的互動邏輯,更新 SVG 當中 image tag 的屬性 href,達到更換裝備的效果 😁

<div>
    <h2>Cap</h2>
    <button onclick="changeCap('#i-helmet', './cap1.svg')">Cap1</button>
    <button onclick="changeCap('#i-helmet', './cap2.svg')">Cap2</button>
    <button onclick="changeCap('#i-helmet', './cap3.svg')">Cap3</button>
</div>

<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
function changeCap(slot, image) {
    $(slot).attr('href', image)
}
</script>

例如範例的人物裝備圖,可以藉由 diagrams.net 來設計 template,將要替換的裝備區域先準備好,匯出 SVG 後搭配 id 或者 name 的方式,讓 CSS 與 JS 可以進行互動。

SVG 與 JS 互動

但要注意的是使用 diagrams.net 鑲嵌使用的 SVG 無法被重複編輯,而是被視為封裝的整體,鑲嵌 SVG 進入 diagrams.net 都是以 base64 編碼並且經過 gzip 壓縮後的格式,無法再就該鑲嵌 SVG 的組成進行編輯。同時在 CSS 與 JS 的互動對象也是封裝的整體,而非該鑲嵌 SVG 的組成。

使用 diagrams.net 所產生的 SVG 分為兩種,分別是包含 diagrams.net 排版訊息的格式以及純粹的 SVG 格式,如果是後者一旦匯出之後就無法再度使用 diagrams.net 進行組成的編輯。

如果是可重複編輯 SVG 的需求,同時互動的完整性要包含到 SVG 的組成,例如 unDarw 所提供的插圖支援變換主色彩的功能,則 SVG 必須使用 inline SVG 的方式使用,同時不能有鑲嵌 base64 編碼的 SVG,這種 SVG Editor 可以改使用 Inkscape 來達成。

但使用 Inkscape 相對 diagrams.net 會有較高的的學習成本 😑

All emojis designed by OpenMoji – the open-source emoji and icon project. License: CC BY-SA 4.0

參考資料

如何建立 RWD 的 Image Map 影像地圖?

The Best Way to Embed SVG on HTML (2021)

The Best Way to Make Image Maps (2020)