Files
chatroom/public/js/effects/effect-manager.js

112 lines
3.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* 文件功能:聊天室特效管理器
*
* 统一管理全屏 Canvas 特效的入口、防重入和资源清理。
* 使用方式EffectManager.play('fireworks' | 'rain' | 'lightning')
*/
const EffectManager = (() => {
// 当前正在播放的特效名称(防止同时播放两个特效)
let _current = null;
// 全屏 Canvas 元素引用
let _canvas = null;
/**
* 获取或创建全屏 Canvas 元素
* 属性fixed 定位覆盖全屏pointer-events:none 不阻止用户交互
*/
function _getCanvas() {
if (_canvas && document.body.contains(_canvas)) {
return _canvas;
}
const c = document.createElement("canvas");
c.id = "effect-canvas";
c.style.cssText = [
"position:fixed",
"top:0",
"left:0",
"width:100vw",
"height:100vh",
"z-index:99999",
"pointer-events:none",
].join(";");
c.width = window.innerWidth;
c.height = window.innerHeight;
document.body.appendChild(c);
_canvas = c;
return c;
}
/**
* 特效结束后清理 Canvas重置状态并停止音效
*/
function _cleanup() {
if (_canvas && document.body.contains(_canvas)) {
document.body.removeChild(_canvas);
}
_canvas = null;
_current = null;
// 通知音效引擎停止(兜底:正常情况下音效会自行计时结束)
if (typeof EffectSounds !== "undefined") {
EffectSounds.stop();
}
}
/**
* 播放指定特效
*
* @param {string} type 特效类型fireworks / rain / lightning / snow
*/
function play(type) {
// 防重入:同时只允许一个特效
if (_current) {
console.log(
`[EffectManager] 特效 ${_current} 正在播放,忽略 ${type}`,
);
return;
}
const canvas = _getCanvas();
_current = type;
// 同步触发对应音效
if (typeof EffectSounds !== "undefined") {
EffectSounds.play(type);
}
switch (type) {
case "fireworks":
if (typeof FireworksEffect !== "undefined") {
FireworksEffect.start(canvas, _cleanup);
}
break;
case "wedding-fireworks":
// 婚礼专属:双倍礼花,粉金浪漫配色,持续 12 秒
if (typeof FireworksEffect !== "undefined") {
FireworksEffect.startDouble(canvas, _cleanup);
}
break;
case "rain":
if (typeof RainEffect !== "undefined") {
RainEffect.start(canvas, _cleanup);
}
break;
case "lightning":
if (typeof LightningEffect !== "undefined") {
LightningEffect.start(canvas, _cleanup);
}
break;
case "snow":
if (typeof SnowEffect !== "undefined") {
SnowEffect.start(canvas, _cleanup);
}
break;
default:
console.warn(`[EffectManager] 未知特效类型:${type}`);
_cleanup();
}
}
return { play };
})();