在图片中标记热点区域,实现图片可选择状态,并随着图片大小改变而自动匹配。

前言:在图片上圈出特定的范围,去实现点击事件或者悬浮效果。本章简单叙述如何在图片上实现热点区域,并动态的监听图片大小变化,实现热点区域随时匹配到图片上相应的位置。

一、 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;

        最后,图片无论怎么改变,热点区域照样匹配,之后大家就可以自己添加什么点击或者悬浮弹框,或者点击跳转等事件效果。

我这边是设计的悬浮框动画,并设计点击事件,到达自动展示和点击展示 最后最后我这边的效果:

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值