热点标记组件
一个功能丰富的图像热点标记组件,支持交互式热点标注、自定义提示和模态框详情
组件简介
CutestUI热点标记组件是一个专为网页设计的交互式图像标记工具,允许开发者在图片上创建各种类型的热点标记点。该组件支持自定义样式、提示框、交互动画和详情模态框,为用户提供直观的图像导航和信息展示体验。适用于地图标注、产品展示、建筑平面图、医学图像标记等多种场景。
组件特性
- 支持多种热点类型(主色调、成功、警告、信息)
- 自定义热点大小(小、默认、大、超大)
- 精美的脉冲动画效果
- 悬停显示详细提示信息
- 点击热点打开详情模态框
- 响应式设计,适配各种屏幕尺寸
- 支持自定义热点内容(文本、图标等)
- 缩放区域功能,支持局部放大查看
- 完整的无障碍支持和打印样式
基本使用示例
基本热点标记
主要热点
成功热点
警告热点
信息热点
小热点
大热点
!
超大热点
高级使用示例
产品详情
服务介绍
HTML结构
<!-- 基础图像映射容器 -->
<div class="cutest-image-map">
<img src="image.jpg" alt="示例图片">
<!-- 基本热点标记 -->
<div class="cutest-hotspot" style="top: 30%; left: 20%;">
<div class="cutest-hotspot-tooltip">热点提示信息</div>
</div>
<!-- 不同类型的热点 -->
<div class="cutest-hotspot type-primary" style="top: 45%; left: 60%;"></div>
<div class="cutest-hotspot type-success" style="top: 65%; left: 30%;"></div>
<div class="cutest-hotspot type-warning" style="top: 20%; left: 70%;"></div>
<div class="cutest-hotspot type-info" style="top: 55%; left: 85%;"></div>
<!-- 不同大小的热点 -->
<div class="cutest-hotspot size-small" style="top: 35%; left: 45%;"></div>
<div class="cutest-hotspot size-large" style="top: 70%; left: 60%;"></div>
<div class="cutest-hotspot size-xl" style="top: 15%; left: 40%;">
<div class="cutest-hotspot-content">!</div>
</div>
<!-- 缩放区域 -->
<div class="cutest-zoom-area" data-zoom="1.5" style="top: 25%; left: 15%; width: 25%; height: 30%;"></div>
</div>
<!-- 模态框结构 -->
<div class="cutest-image-modal" id="hotspotModal">
<div class="cutest-modal-content">
<div class="cutest-modal-header">
<h3 class="cutest-modal-title" id="modalTitle">热点详情</h3>
<button class="cutest-modal-close" id="closeModal">×</button>
</div>
<div class="cutest-modal-body" id="modalBody">
<!-- 模态框内容将通过JavaScript动态填充 -->
</div>
</div>
</div>
JavaScript实现
// CutestUI 热点标记组件 JavaScript实现
class CutestImageMap {
constructor(containerSelector, options = {}) {
this.container = document.querySelector(containerSelector);
this.image = this.container.querySelector('img');
this.hotspots = this.container.querySelectorAll('.cutest-hotspot');
this.zoomAreas = this.container.querySelectorAll('.cutest-zoom-area');
this.modal = document.getElementById('hotspotModal');
this.modalTitle = document.getElementById('modalTitle');
this.modalBody = document.getElementById('modalBody');
this.closeModalBtn = document.getElementById('closeModal');
this.options = {
zoomFactor: 1.5,
hotspotData: {},
...options
};
this.currentZoom = 1;
this.initEvents();
}
initEvents() {
// 热点点击事件
this.hotspots.forEach(hotspot => {
hotspot.addEventListener('click', () => this.handleHotspotClick(hotspot));
});
// 缩放区域点击事件
this.zoomAreas.forEach(area => {
area.addEventListener('click', () => this.handleZoomAreaClick(area));
});
// 模态框关闭事件
if (this.closeModalBtn) {
this.closeModalBtn.addEventListener('click', () => this.closeModal());
}
// 点击模态框背景关闭
if (this.modal) {
this.modal.addEventListener('click', (e) => {
if (e.target === this.modal) {
this.closeModal();
}
});
}
}
handleHotspotClick(hotspot) {
const hotspotId = hotspot.dataset.hotspotId;
const hotspotData = this.options.hotspotData[hotspotId];
if (hotspotData && this.modal) {
// 填充模态框内容
this.modalTitle.textContent = hotspotData.title || '热点详情';
this.modalBody.innerHTML = `
<div class="cutest-hotspot-details">
${hotspotData.description ? `<p class="cutest-hotspot-description">${hotspotData.description}</p>` : ''}
${hotspotData.details ? hotspotData.details : ''}
${hotspotData.meta ? this.renderMeta(hotspotData.meta) : ''}
</div>
`;
// 显示模态框
this.modal.classList.add('show');
}
// 添加激活状态
this.hotspots.forEach(h => h.classList.remove('active'));
hotspot.classList.add('active');
}
handleZoomAreaClick(area) {
const zoom = parseFloat(area.dataset.zoom) || this.options.zoomFactor;
this.currentZoom = zoom;
// 计算缩放中心
const rect = area.getBoundingClientRect();
const containerRect = this.container.getBoundingClientRect();
const centerX = (rect.left - containerRect.left + rect.width / 2) / this.image.offsetWidth;
const centerY = (rect.top - containerRect.top + rect.height / 2) / this.image.offsetHeight;
// 应用缩放和定位
this.image.style.transform = `scale(${zoom})`;
this.image.style.transformOrigin = `${centerX * 100}% ${centerY * 100}%`;
}
renderMeta(meta) {
let metaHtml = '<div class="cutest-hotspot-meta">';
Object.entries(meta).forEach(([key, value]) => {
metaHtml += `<span class="cutest-hotspot-meta-item">${key}: ${value}</span>`;
});
metaHtml += '</div>';
return metaHtml;
}
closeModal() {
if (this.modal) {
this.modal.classList.remove('show');
}
}
toggleHotspots() {
const isHidden = this.hotspots[0].style.display === 'none';
this.hotspots.forEach(hotspot => {
hotspot.style.display = isHidden ? 'flex' : 'none';
});
return !isHidden;
}
zoomIn() {
this.currentZoom += 0.2;
this.image.style.transform = `scale(${this.currentZoom})`;
}
zoomOut() {
this.currentZoom = Math.max(1, this.currentZoom - 0.2);
this.image.style.transform = `scale(${this.currentZoom})`;
}
resetZoom() {
this.currentZoom = 1;
this.image.style.transform = 'scale(1)';
this.image.style.transformOrigin = 'center center';
}
}
// 使用示例
document.addEventListener('DOMContentLoaded', function() {
// 初始化高级示例
const advancedMap = new CutestImageMap('#advancedImageMap', {
hotspotData: {
'detail1': {
title: '产品详情',
description: '这是我们的旗舰产品,具有高性能、低功耗的特点。',
meta: {
'型号': 'Pro Max',
'价格': '¥9999',
'库存': '充足'
}
},
'detail2': {
title: '服务介绍',
description: '我们提供全方位的售后服务支持,包括24小时技术支持和上门维修服务。',
meta: {
'响应时间': '24小时',
'保修期': '2年',
'满意度': '98%'
}
}
}
});
// 绑定控制按钮事件
document.getElementById('toggleHotspots').addEventListener('click', () => {
advancedMap.toggleHotspots();
});
document.getElementById('zoomIn').addEventListener('click', () => {
advancedMap.zoomIn();
});
document.getElementById('zoomOut').addEventListener('click', () => {
advancedMap.zoomOut();
});
document.getElementById('resetZoom').addEventListener('click', () => {
advancedMap.resetZoom();
});
});
使用指南
基本设置
- 引入CSS文件:
<link rel="stylesheet" href="/static/css/image-map.css"> - 创建图像映射容器:
<div class="cutest-image-map"><img src="image.jpg"></div> - 添加热点标记:
<div class="cutest-hotspot" style="top: 30%; left: 20%;"></div>
热点类型
.type-primary- 主色调热点(蓝色).type-success- 成功热点(绿色).type-warning- 警告热点(橙色).type-info- 信息热点(青色)
热点大小
.size-small- 小热点(16px).size-large- 大热点(28px).size-xl- 超大热点(40px)
热点定位
使用CSS的top和left属性(百分比值)定位热点在图像中的位置。例如:style="top: 30%; left: 20%;"
JavaScript初始化
// 简单初始化
const imageMap = new CutestImageMap('#yourImageMap');
// 带选项的初始化
const imageMap = new CutestImageMap('#yourImageMap', {
zoomFactor: 1.5, // 默认缩放因子
hotspotData: { // 热点数据
'hotspot1': {
title: '热点标题',
description: '热点描述内容',
meta: {
'属性1': '值1',
'属性2': '值2'
}
}
}
});
主题定制
CutestUI热点标记组件支持通过修改CSS变量来定制主题颜色。以下是主要的定制选项:
/* 自定义热点颜色 */
.cutest-hotspot {
/* 基础红色热点 */
--hotspot-primary-bg: rgba(255, 77, 77, 0.7);
--hotspot-primary-hover: rgba(255, 77, 77, 0.9);
}
.cutest-hotspot.type-primary {
/* 蓝色热点 */
--hotspot-primary-bg: rgba(77, 153, 255, 0.7);
--hotspot-primary-hover: rgba(77, 153, 255, 0.9);
}
/* 自定义脉冲动画 */
@keyframes custom-pulse {
0% {
transform: translate(-50%, -50%) scale(1);
opacity: 1;
}
100% {
transform: translate(-50%, -50%) scale(2.5);
opacity: 0;
}
}
.cutest-hotspot.custom-pulse::before {
animation: custom-pulse 1.5s infinite;
}