MultipleWindow3dScene事件处理:深入解析窗口状态监听与更新机制
【免费下载链接】multipleWindow3dScenebased on bgstaal/multipleWindow3dScene项目地址: https://gitcode.com/gh_mirrors/mul/multipleWindow3dScene
MultipleWindow3dScene是一个基于Three.js的多窗口3D场景项目,它允许在多个浏览器窗口之间创建协同的3D视觉效果。本文将深入解析其窗口状态监听与更新机制,帮助开发者理解如何实现跨窗口的实时状态同步和高效事件处理。
核心事件处理架构概览
MultipleWindow3dScene的事件处理系统主要依赖两个核心文件:WindowManager.js和main.js。前者负责管理多窗口状态,后者则处理具体的3D场景渲染和交互逻辑。
整个事件处理流程可以分为三个阶段:
- 窗口初始化:建立窗口标识和初始状态
- 状态监听:实时监测窗口位置、大小变化
- 状态同步:跨窗口共享状态并更新3D场景
窗口生命周期管理机制
初始化与标识分配
在窗口初始化阶段,WindowManager通过localStorage维护一个全局的窗口计数器和窗口列表:
// WindowManager.js 初始化逻辑 init (metaData) { this.#windows = JSON.parse(localStorage.getItem("windows")) || []; this.#count= localStorage.getItem("count") || 0; this.#count++; this.#id = this.#count; let shape = this.getWinShape(); this.#winData = {id: this.#id, shape: shape, metaData: metaData}; this.#windows.push(this.#winData); localStorage.setItem("count", this.#count); this.updateWindowsLocalStorage(); }每个新窗口会自动获取一个唯一ID,并将自身的初始状态(位置、大小等)加入到全局窗口列表中。
窗口关闭处理
当窗口关闭时,系统会自动从全局窗口列表中移除该窗口,并更新localStorage:
// WindowManager.js 窗口关闭处理 window.addEventListener('beforeunload', function (e) { let index = that.getWindowIndexFromId(that.#id); // 从列表中移除当前窗口并更新本地存储 that.#windows.splice(index, 1); that.updateWindowsLocalStorage(); });窗口状态监听系统
本地窗口状态监测
系统通过两种方式监测窗口状态变化:
- 窗口大小变化监听:在main.js中注册resize事件监听器
// main.js 窗口大小变化监听 window.addEventListener('resize', resize);- 周期性状态检查:在渲染循环中定期调用update方法检查窗口状态
// WindowManager.js 状态更新检查 update () { let winShape = this.getWinShape(); if (winShape.x != this.#winData.shape.x || winShape.y != this.#winData.shape.y || winShape.w != this.#winData.shape.w || winShape.h != this.#winData.shape.h) { this.#winData.shape = winShape; let index = this.getWindowIndexFromId(this.#id); this.#windows[index].shape = winShape; if (this.#winShapeChangeCallback) this.#winShapeChangeCallback(); this.updateWindowsLocalStorage(); } }跨窗口状态同步
系统利用localStorage的storage事件实现跨窗口通信:
// WindowManager.js 跨窗口状态同步 addEventListener("storage", (event) => { if (event.key == "windows") { let newWindows = JSON.parse(event.newValue); let winChange = that.#didWindowsChange(that.#windows, newWindows); that.#windows = newWindows; if (winChange) { if (that.#winChangeCallback) that.#winChangeCallback(); } } });当任何窗口的状态发生变化时,会更新localStorage中的"windows"数据,其他窗口通过监听storage事件接收状态变化通知。
事件回调与3D场景更新
回调函数注册机制
WindowManager提供了回调函数注册接口,允许应用程序在窗口状态变化时执行自定义逻辑:
// WindowManager.js 回调注册方法 setWinShapeChangeCallback (callback) { this.#winShapeChangeCallback = callback; } setWinChangeCallback (callback) { this.#winChangeCallback = callback; }在main.js中,应用程序注册了两个关键回调:
// main.js 注册回调函数 windowManager.setWinShapeChangeCallback(updateWindowShape); windowManager.setWinChangeCallback(windowsUpdated);3D场景更新流程
当窗口状态变化时,通过回调函数触发3D场景更新:
- 窗口形状变化处理:调整场景偏移量以保持视觉一致性
// main.js 窗口形状变化处理 function updateWindowShape (easing = true) { sceneOffsetTarget = {x: -window.screenX, y: -window.screenY}; if (!easing) sceneOffset = sceneOffsetTarget; }- 窗口数量变化处理:重新创建与窗口对应的3D对象
// main.js 窗口数量变化处理 function windowsUpdated () { updateNumberOfCubes(); } function updateNumberOfCubes () { let wins = windowManager.getWindows(); // 移除旧立方体 cubes.forEach((c) => { world.remove(c); }) cubes = []; // 根据当前窗口列表创建新立方体 for (let i = 0; i < wins.length; i++) { // 创建与窗口对应的3D对象... } }- 实时渲染更新:在渲染循环中平滑更新3D对象位置
// main.js 渲染循环中的更新逻辑 function render () { windowManager.update(); // 平滑更新场景偏移 let falloff = .05; sceneOffset.x = sceneOffset.x + ((sceneOffsetTarget.x - sceneOffset.x) * falloff); sceneOffset.y = sceneOffset.y + ((sceneOffsetTarget.y - sceneOffset.y) * falloff); world.position.x = sceneOffset.x; world.position.y = sceneOffset.y; // 更新每个窗口对应的3D对象 for (let i = 0; i < cubes.length; i++) { let complexSphere = cubes[i]; let win = wins[i]; let posTarget = {x: win.shape.x + (win.shape.w * .5), y: win.shape.y + (win.shape.h * .5)} // 平滑移动3D对象到目标位置 complexSphere.position.x = complexSphere.position.x + (posTarget.x - complexSphere.position.x) * falloff; complexSphere.position.y = complexSphere.position.y + (posTarget.y - complexSphere.position.y) * falloff; // 旋转动画等其他更新... }; renderer.render(scene, camera); requestAnimationFrame(render); }实际应用与扩展建议
基本使用流程
- 克隆项目仓库:
git clone https://gitcode.com/gh_mirrors/mul/multipleWindow3dScene - 在浏览器中打开index.html,系统会自动创建第一个3D场景窗口
- 复制URL并在新窗口中打开,新窗口会自动加入到3D场景系统中
- 拖动或调整任何窗口大小,所有窗口中的3D元素会实时同步更新
功能扩展建议
- 自定义元数据:通过WindowManager的init方法传递自定义元数据
// 示例:添加自定义窗口元数据 let metaData = {color: "#ff0000", priority: 1, type: "main"}; windowManager.init(metaData);扩展事件类型:可以在WindowManager中添加更多事件类型,如窗口焦点变化、自定义消息等
优化性能:对于大量窗口的场景,可以实现窗口可见性检测,只更新可见窗口的3D对象
总结
MultipleWindow3dScene通过精巧的事件处理系统,实现了跨窗口的状态同步和3D场景协同。其核心在于利用localStorage作为状态共享媒介,结合事件监听和回调机制,实现了高效的窗口状态管理。这种设计不仅适用于3D场景,也为任何需要多窗口协同的Web应用提供了宝贵的参考模式。
通过本文的解析,开发者可以深入理解多窗口Web应用的事件处理机制,并将这些技术应用到自己的项目中,创建更加丰富和交互性强的Web体验。
【免费下载链接】multipleWindow3dScenebased on bgstaal/multipleWindow3dScene项目地址: https://gitcode.com/gh_mirrors/mul/multipleWindow3dScene
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考