React中使用map+area标签实现img图片特定区域标记功能(可用Photoshop精准拾取对应点位)

需求描述

  • 前段时间,工作中笔者接到了一个有意思的需求
  • 就是给图片做特定的交互效果
  • 图片中有几个特殊区域
  • 当用户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>
    )
}

参考:

相关推荐
骑自行车的码农4 小时前
React 合成事件的设计原理 3
react.js
liangshanbo12155 小时前
React 19 新特性:原生支持在组件中渲染 <meta> 与 <link>
前端·javascript·react.js
前端 贾公子6 小时前
《Vuejs设计与实现》第 18 章(同构渲染)(下)
前端·javascript·html
Never_Satisfied7 小时前
在JavaScript / HTML中,词内断行
开发语言·javascript·html
我命由我1234516 小时前
Photoshop - Photoshop 工具栏(5)多边套索工具
笔记·学习·ui·职场和发展·photoshop·ps·美工
whltaoin16 小时前
中秋赏月互动页面:用前端技术演绎传统节日之美
前端·javascript·html·css3·中秋主题前端
光影少年1 天前
react生态
前端·react.js·前端框架
qq_402605651 天前
python爬虫(一) ---- 静态html数据抓取
爬虫·python·html
瘦马1 天前
无需安装的Photoshop:网页版完整使用指南与在线图片编辑技巧
photoshop·photoshop网页版·在线ps·在线抠图·ps网页版·在线编辑图片