需求描述
- 前段时间,工作中笔者接到了一个有意思的需求
- 就是给图片做特定的交互效果
- 图片中有几个特殊区域
- 当用户hover特殊区域的时候,高亮
- 点击特殊区域的时候,弹框给到一些提示信息
效果图和线上演示

线上效果演示地址:ashuai.site/reactExampl...
技术方案选择
- 这个需求如果图片中的特定区域都是矩形
- 我们完全可以直接使用通过定位的方式,写几个div去定位到相应的位置
- 如下示例
html
<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效果仓库里
- github.com/shuirongshu...
- 仓库目前已经有57个有意思的css效果了
- 后续笔者会不断新增,欢迎star
当然,也可以使用svg或者canvas去绘制稀奇古怪的几何图形,但是针对于这种需求,不是最佳实践
使用map和area标签映射图片关联
代码示意
- 给img使用useMap取个唯一的名字(类似id),叫做#pathMap
- 使用map映射刚刚的名字pathMap (#号类似锚点)
- 这样的话,就完成了图片和图片地图的映射关系
- 然后使用area标签,在图片的指定坐标打点,搭配shape形状,就能绘制出区域了
html
<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半径的意思)
html
<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这两个库
- 在项目初始化的时候,进行一些对应的控制,如下
js
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,
});
}
当然 我们要提前对应引入
js
<script src="/js/jquery-3.6.0.min.js"></script>
<script src="/js/jquery.maphilight.js"></script>
完整代码
整个代码在笔者的github仓库里:github.com/shuirongshu...
js
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>
)
}
参考: