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

112 lines
3.4 KiB
JavaScript

/**
* 文件功能:聊天室特效管理器
*
* 统一管理全屏 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 };
})();