前言:在图片上圈出特定的范围,去实现点击事件或者悬浮效果。本章简单叙述如何在图片上实现热点区域,并动态的监听图片大小变化,实现热点区域随时匹配到图片上相应的位置。
一、 Map 和 Area
<map>和 <area> 用于创建可点击的图像热点区域的 HTML 元素。
<map>元素定义一个图像热点区域(或称为映射) 热点容器,配合 <img>使用。
<area>元素 在中添加热点区域, 热点映射。包含基本属性:
shape,指定热点区域的形状,可以是 "rect" (矩形)、"circle" (圆形)、"poly" (多边形) 或 "default" (默认)。
coords,指定热点区域的坐标信息,具体取决于热点区域的形状。圆形中coords 属性有3个值分别代表 横坐标、纵坐标、圆面积,矩形中分别表示左上角和右下角的坐标;对于多边形,coords 属性的值是一组表示每个顶点坐标的数字。
注意:<map> 和 <area>元素没有可见的内容,它仅作为热点区域的容器和创建热点区域映射。
二、上手!上手!操作!(圆形为例)
以下图为例,实现以下图中三个主角的头部可选状态 (网图,若有影响请联系作者更换)
在页面中导入图片,并绑定 map,代码如下。
import Monitoring from '@assets/image/Monitoring.jpg';
import './index.less';
import React, { useState, useEffect } from 'react';
const Mapareas = () => {
return (
<div className='map-area'>
<img src={Monitoring} id='mapImg' alt='' useMap='#jiankmap' />
{/* 给 img 设置useMap 与 map 标签绑定在一起 */}
<map name='jiankmap'>
{/* 先设置三个点的信息 */}
<area
shape='circle'
title='嫌疑人李四'
coords="0,0,10"
onClick={() => {
console.log('嫌疑人李四', );
}}
/>
<area
shape='circle'
title='嫌疑人张三'
coords="0,0,10"
onClick={() => {
console.log('嫌疑人张三');
}}
/>
<area
shape='circle'
title='嫌疑人王麻子'
coords="0,0,10"
onClick={() => {
console.log('嫌疑人王麻子');
}}
/>
</map>
</div>
);
};
export default Mapareas;
img 正确导入并和 map 成功绑定之后,左上角会出现可选状态,接下来就设置 coords属性。
coords 属性是相当于原图的尺寸大小的相对像素位置,这个具体的位置可以通过用电脑自带的画图工具或者 ps 工具打开自己的图片:
通过在画图 工具上得到的像素点坐标,我们就可以得到 coords 的数值,(从左至右)人物头像坐标:(180,330),(460,310),(490,350) 我取整为了后期计算方便。
<div className='map-area'>
<img src={Monitoring} id='mapImg' alt='' useMap='#jiankmap' />
{/* 给 img 设置useMap 与 map 标签绑定在一起 */}
<map name='jiankmap'>
<area
shape='circle'
title='嫌疑人李四'
coords="180,330,10"
onClick={() => {
console.log('嫌疑人李四', );
}}
/>
<area
shape='circle'
title='嫌疑人张三'
coords="460,310,10"
onClick={() => {
console.log('嫌疑人张三');
}}
/>
<area
shape='circle'
title='嫌疑人王麻子'
coords="490,350,10"
onClick={() => {
console.log('嫌疑人王麻子');
}}
/>
</map>
</div>
像素坐标添加完成之后,在标记的热点区域就会进行可选状态,我这边是直接设置的点击事件,自行补充。
三、解决图片大小变化时,热点区域不匹配问题。
在 coords 中似乎不支持百分比的写法,所有要实现图片大小改变时,自动匹配的话,可以采用监听屏幕大小变化,并动态获取图片大小,然后去设置热点区域值。想法很重要,代码量很少的。
这里我的图片宽是设置的 100% 高度 auto 自适应,不改变图片比例。
//获取图片元素
const mapImage:any = document.getElementById('mapImg');
//当前图片宽高
const [mapWidht, setMapWidth]: any = useState(mapImage?.clientWidth);
const [mapHeight, setMapHeight]: any = useState(mapImage?.clientHeight);
//监听屏幕大小变化,更改 热点区域
window.onresize = () => {
setMapHeight(mapImage?.clientHeight);
setMapWidth(mapImage?.clientWidth);
};
将真实的图片大小当作计算值,并计算像素坐标为百分比,转化在 coords 中即可。以下完整代码:
import Monitoring from '@assets/image/Monitoring.jpg';
import './index.less';
import React, { useState, useEffect } from 'react';
const Mapareas = () => {
const mapImage:any = document.getElementById('mapImg');
//图片的宽高
const [mapWidht, setMapWidth]: any = useState(mapImage?.clientWidth);
const [mapHeight, setMapHeight]: any = useState(mapImage?.clientHeight);
//监听屏幕大小变化,更改 热点区域
window.onresize = () => {
setMapHeight(mapImage?.clientHeight);
setMapWidth(mapImage?.clientWidth);
};
// 初始化时设置当前的 热点区域
useEffect(() => {
// 页面刚刚加载时,图片的大小还未加载,需要自己监听一下
if(mapImage?.clientHeight>0){
setMapHeight(mapImage?.clientHeight);
setMapWidth(mapImage?.clientWidth);
}
}, [mapImage?.clientHeight]);
return (
<div className='map-area'>
<img src={Monitoring} id='mapImg' alt='' useMap='#jiankmap' />
{/* 给 img 设置useMap 与 map 标签绑定在一起 */}
<map name='jiankmap'>
<area
shape='circle'
title='嫌疑人李四'
coords={`${mapWidht * 0.23},${mapHeight * 0.75},50`}
onClick={() => {
console.log('嫌疑人李四', );
}}
/>
<area
shape='circle'
coords={`${mapWidht * 0.564},${mapHeight * 0.69},50`}
onClick={() => {
console.log('嫌疑人张三');
}}
/>
<area
shape='circle'
title='嫌疑人王麻子'
coords={`${mapWidht * 0.625},${mapHeight * 0.795},50`}
onClick={() => {
console.log('嫌疑人王麻子');
}}
/>
</map>
</div>
);
};
export default Mapareas;
最后,图片无论怎么改变,热点区域照样匹配,之后大家就可以自己添加什么点击或者悬浮弹框,或者点击跳转等事件效果。
我这边是设计的悬浮框动画,并设计点击事件,到达自动展示和点击展示 最后最后我这边的效果: