需求描述
- 前段時間,工作中筆者接到了一個有意思的需求
- 就是給圖片做特定的交互效果
- 圖片中有幾個特殊區域
- 當用户hover特殊區域的時候,高亮
- 點擊特殊區域的時候,彈框給到一些提示信息
效果圖和線上演示
線上效果演示地址:https://ashuai.site/reactExamples/imagePoint
技術方案選擇
- 這個需求如果圖片中的特定區域都是矩形
- 我們完全可以直接使用通過定位的方式,寫幾個div去定位到相應的位置
- 如下示例
<body>
<!-- 父元素開啓絕對定位 -->
<div class="wrap">
<!-- 圖片和父元素寬高保持一致 -->
<img src="./a.png" alt="a.png">
<!-- 各個矩形設置寬高,再absolute微調定位到對應位置即可 -->
<div class="rectangle1"></div>
<div class="rectangle2"></div>
</div>
</body>
- 但若是圖片中的特定區域不是常見的矩形
- 而是一些特殊的樣子形狀
- 直接使用div就不太好畫出來了
- 當然,我們也可以使用css的clip-path畫出來特定稀奇古怪的形狀
- 但是,我們不太好控制形狀的大小寬高半徑之類的具體參數(不太好和圖片中的區域保持一致)
一些clip-path的繪製效果
- 上圖的效果圖代碼,都在筆者整理的一些有意思的css效果倉庫裏
- https://github.com/shuirongshuifu/interestingCSS
- 倉庫目前已經有57個有意思的css效果了
- 後續筆者會不斷新增,歡迎star
當然,也可以使用svg或者canvas去繪製稀奇古怪的幾何圖形,但是針對於這種需求,不是最佳實踐
使用map和area標籤映射圖片關聯
代碼示意
- 給img使用useMap取個唯一的名字(類似id),叫做#pathMap
- 使用map映射剛剛的名字pathMap (#號類似錨點)
- 這樣的話,就完成了圖片和圖片地圖的映射關係
- 然後使用area標籤,在圖片的指定座標打點,搭配shape形狀,就能繪製出區域了
<div>
<img
src={exampleImg}
className="example-image"
useMap="#pathMap"
/>
<map name="pathMap">
<area
shape="rect"
coords="84,188,200,255"
href="#"
onClick={(e) => { e.preventDefault(); showPathInfo('矩形區域'); }}
title="矩形區域"
/>
</map>
</div>
平面直角座標系知識
- 矩形兩個點可以確定 84,188,200,255就是 x1 y1 x2 y2
- 三角形三個點 439,158,513,284,366,284 就是 x1 y1 x2 y2 z1 z2
- 圓形是一個點搭配一個半徑 752,221,72就是 x1 y1 r (r半徑的意思)
<area
shape="rect"
coords="84,188,200,255"
/>
<area
shape="poly"
coords="439,158,513,284,366,284"
/>
<area
shape="circle"
coords="752,221,72"
/>
使用Photoshop拾取對應點位
上述各個形狀的各個座標點,可以通過ps進行拾取確定
使用jquery和jquery.maphilight進行區域審查效果
- map、area這兩個標籤,F12審查dom元素看不到
- 可以自己不停按下Tab鍵進行切換查看,但是依舊不直觀
- 這裏我們可以藉助jquery和jquery.maphilight這兩個庫
- 在項目初始化的時候,進行一些對應的控制,如下
if ($ && $.fn.maphilight) {
// 初始化maphilight,使用正確的選擇器
// jquery選中圖片,使用jquery.maphilight.js提供的maphilight函數,進行高亮控制
$('.example-image').maphilight({
fill: true, // 填充區域
fillOpacity: 0.3, // 填充透明度(0.3為半透明)
// 為true的話,會初始高亮,為false的話,則是懸浮高亮
// alwaysOn: true,
alwaysOn: false,
});
}
當然 我們要提前對應引入
<script src="/js/jquery-3.6.0.min.js"></script>
<script src="/js/jquery.maphilight.js"></script>
完整代碼
整個代碼在筆者的github倉庫裏:https://github.com/shuirongshuifu/react-examples
import React, { useEffect } from 'react'
import exampleImg from '@/assets/img/example.png'
import { message } from 'antd'
export default function ImagePoint() {
useEffect(() => {
// 確保 jQuery 和 maphilight 已加載
if ($ && $.fn.maphilight) {
// 初始化maphilight,使用正確的選擇器
$('.example-image').maphilight({
fill: true, // 填充區域
fillOpacity: 0.3, // 填充透明度(0.3為半透明)
// 為true的話,會初始高亮,為false的話,則是懸浮高亮
// alwaysOn: true,
alwaysOn: false,
});
}
}, []);
const showPathInfo = (pathName) => {
message.info(pathName);
};
return (
<div>
<h2>圖片區域打點</h2>
<p>鼠標懸停在圖片的矩形、多邊形、圓形區域上查看高亮效果,點擊查看信息</p>
<img
src={exampleImg}
alt="example"
className="example-image"
useMap="#pathMap"
style={{ width: 'fit-content', height: 'auto' }}
/>
<map name="pathMap" id="pathMapID">
<area
shape="rect"
coords="84,188,200,255"
href="#"
onClick={(e) => { e.preventDefault(); showPathInfo('矩形區域'); }}
alt="矩形"
title="矩形區域"
/>
<area
shape="circle"
coords="752,221,72"
href="#"
onClick={(e) => { e.preventDefault(); showPathInfo('圓形區域'); }}
alt="圓形"
title="圓形區域"
/>
<area
shape="poly"
coords="439,158,513,284,366,284"
href="#"
onClick={(e) => { e.preventDefault(); showPathInfo('多邊形區域'); }}
alt="多邊形"
title="多邊形區域"
/>
</map>
</div>
)
}
參考: