本文详解如何在网页中通过按钮点击实时切换多个 360° 全景图像,基于 panolens.js 实现无刷新加载与渲染,并提供可复用的初始化、销毁与重载逻辑。
本文详解如何在网页中通过按钮点击实时切换多个 360° 全景图像,基于 panolens.js 实现无刷新加载与渲染,并提供可复用的初始化、销毁与重载逻辑。
要实现点击按钮动态切换 Panolens.js 渲染的 360° 全景图,关键在于复用 Viewer 实例并正确管理场景资源——不能每次点击都新建 Viewer(会导致内存泄漏和重复初始化),而应调用 viewer.dispose() 清理当前全景图,再 viewer.add() 加载新图像。
以下是一个完整、健壮且适合初学者的实现方案:
✅ 正确结构:单 Viewer + 多图路径数组 + dataset 控制索引
首先,在 HTML 中定义容器和带状态标识的按钮(使用 data-index 记录当前显示的图片序号):
<script src="https://pchen66.github.io/js/three/three.min.js"></script><script src="https://pchen66.github.io/js/panolens/panolens.min.js"></script><button data-index="0">切换到全景图 1</button> <button data-index="1">切换到全景图 2</button> <div class="image-container"></div>
⚠️ 注意:Panolens.js 依赖 Three.js,两者的 CDN 必须按顺序引入,且建议使用 HTTPS 协议(原示例中 // 协议在现代浏览器中可能被拦截)。
✅ JavaScript 核心逻辑(含防错与复用)
document.addEventListener('DOMContentLoaded', () => {
// 1. 预定义所有全景图路径(支持本地或远程 URL)
const panoramaPaths = [
'images/field.jpg', // 替换为你的 image1.jpg
'images/mountain.jpg' // 替换为你的 image2.jpg
];
// 2. 初始化 Viewer(仅一次!)
const container = document.querySelector('.image-container');
const viewer = new PANOLENS.Viewer({ container });
// 3. 初始加载第一张图
let currentPanorama = new PANOLENS.ImagePanorama(panoramaPaths[0]);
viewer.add(currentPanorama);
// 4. 统一处理所有切换按钮
document.querySelectorAll('button').forEach(btn => {
btn.addEventListener('click', () => {
const targetIndex = parseInt(btn.dataset.index, 10);
if (isNaN(targetIndex) || targetIndex = panoramaPaths.length) return;
// ✅ 安全卸载旧图(避免残留纹理/几何体)
if (currentPanorama) {
viewer.remove(currentPanorama);
currentPanorama.dispose(); // 释放 GPU 资源
}
// ✅ 加载新图并更新引用
currentPanorama = new PANOLENS.ImagePanorama(panoramaPaths[targetIndex]);
viewer.add(currentPanorama);
// ✅ 可选:同步更新按钮状态(如高亮当前激活项)
document.querySelectorAll('button').forEach(b => b.classList.remove('active'));
btn.classList.add('active');
});
});
});
✅ CSS 基础样式(确保容器占满视口)
* { box-sizing: border-box; }
body {
margin: 0;
height: 100vh;
overflow: hidden;
}
.image-container {
width: 100%;
height: 100vh;
}
button {
position: absolute;
top: 1rem;
padding: 0.5rem 1rem;
margin: 0 0.5rem;
z-index: 10;
background: #fff;
border: 1px solid #ccc;
border-radius: 4px;
cursor: pointer;
}
button.active {
background: #007bff;
color: white;
}
? 关键要点说明
- 不要重复创建 Viewer:new PANOLENS.Viewer() 应只执行一次,否则会生成多个渲染上下文,导致性能崩溃。
- 必须调用 .dispose():ImagePanorama.dispose() 会清理 WebGL 纹理、缓冲区等资源,防止内存持续增长。
- 使用 viewer.remove() + viewer.add():比 viewer.dispose()(销毁整个 Viewer)更轻量,推荐用于单图切换。
- 路径需可访问:确保 images/xxx.jpg 在服务器上可被浏览器直接请求(开发时建议使用 http-server 或 VS Code Live Server 启动本地服务,避免 file:// 协议跨域限制)。
- 错误防护:添加 isNaN 和边界检查,避免因 data-index 错误导致脚本中断。
✅ 扩展建议(进阶)
- 支持更多图片?只需扩展 panoramaPaths 数组,并为每个按钮设置对应 data-index。
- 添加加载状态?可在 ImagePanorama 构造后监听 onLoad 事件,显示 loading 提示。
- 配合缩略图导航?可动态生成小图按钮,点击后触发同套切换逻辑。
掌握这一模式后,你就能轻松构建多场景 360° 导览系统——简洁、可控、符合现代 Web 开发最佳实践。











