class PugePanel { constructor() { this.loadedCSS = new Set(); this.init(); } // 初始化方法 init() { this.removeExistingStartBox(); this.createPanel(); this.createTriggerButton(); } // 加载CSS,避免重复加载 loadCSS(url) { if (this.loadedCSS.has(url)) return; this.loadedCSS.add(url); const link = document.createElement('link'); link.rel = 'stylesheet'; link.type = 'text/css'; link.href = url; (document.head || document.documentElement).appendChild(link); } // 移除已存在的start-box removeExistingStartBox() { const existingBox = document.querySelector('.start-box'); if (existingBox) { existingBox.remove(); } } // 创建关闭按钮 createCloseButton() { const closeBtn = document.createElement('div'); closeBtn.className = 'puge-close-btn'; closeBtn.innerHTML = '×'; closeBtn.setAttribute('aria-label', '关闭面板'); // 添加关闭按钮事件 closeBtn.addEventListener('click', () => this.togglePanel(false)); closeBtn.addEventListener('mouseenter', () => { closeBtn.style.color = '#ff4444'; }); closeBtn.addEventListener('mouseleave', () => { closeBtn.style.color = '#666'; }); return closeBtn; } // 创建标题栏 createTitleBar() { const titleBar = document.createElement('div'); titleBar.className = 'puge-title-bar'; const titleText = document.createElement('span'); titleText.className = 'puge-title'; titleText.textContent = '功能面板'; titleBar.appendChild(titleText); titleBar.appendChild(this.createCloseButton()); return titleBar; } // 创建内容区域 createContentArea() { const contentArea = document.createElement('div'); contentArea.className = 'puge-box puge-content-area'; // 根据屏幕方向设置高度 const isLandscape = window.innerWidth > window.innerHeight; if (isLandscape) { contentArea.style.maxHeight = '60%'; } else { contentArea.style.height = 'calc(100% - 40px)'; } return contentArea; } // 创建主面板 createPanel() { setTimeout(() => { if (document.querySelector('.start-box')) return; const panel = document.createElement('div'); panel.className = 'start-box owo puge-panel'; panel.setAttribute('aria-hidden', 'true'); // 设置面板样式 const isLandscape = window.innerWidth > window.innerHeight; Object.assign(panel.style, { display: 'none', zIndex: '9665', position: 'fixed', right: '0', bottom: '0', boxShadow: '1px 1px 9px rgba(204, 204, 204, 0.5)', backgroundColor: 'rgba(255, 255, 255, 0.95)', backdropFilter: 'blur(10px)', transition: 'opacity 0.3s ease, transform 0.3s ease' }); if (isLandscape) { panel.style.width = '320px'; panel.style.maxHeight = '60%'; } else { panel.style.width = '100%'; panel.style.height = '100%'; } const contentArea = this.createContentArea() // 组装面板 panel.appendChild(this.createTitleBar()); panel.appendChild(contentArea); setTimeout(() => { document.body.appendChild(panel); // 触发创建回调 if (window.pugeCreated) { window.pugeCreated(contentArea); window.pugeCreated = null; } }, 1000); }, 1000); } // 星星图标SVG get starIconSVG() { return ` `; } // 创建触发按钮 createTriggerButton() { if (document.querySelector('.puge-menu')) return; const triggerBtn = document.createElement('div'); triggerBtn.className = 'puge-menu puge-trigger-btn'; triggerBtn.setAttribute('aria-label', '打开功能面板'); triggerBtn.setAttribute('role', 'button'); triggerBtn.tabIndex = 0; Object.assign(triggerBtn.style, { position: 'fixed', width: '40px', height: '40px', right: '10px', bottom: '120px', zIndex: '9666', cursor: 'pointer', transition: 'transform 0.3s ease' }); triggerBtn.innerHTML = this.starIconSVG; // 添加点击事件 triggerBtn.addEventListener('click', () => this.togglePanel(true)); triggerBtn.addEventListener('keydown', (e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); this.togglePanel(true); } }); // 添加悬停效果 triggerBtn.addEventListener('mouseenter', () => { triggerBtn.style.transform = 'scale(1.1)'; }); triggerBtn.addEventListener('mouseleave', () => { triggerBtn.style.transform = 'scale(1)'; }); setTimeout(() => { document.body.appendChild(triggerBtn); }, 1000); } // 切换面板显示/隐藏 togglePanel(show) { const panel = document.querySelector('.start-box'); const triggerBtn = document.querySelector('.puge-menu'); if (!panel) return; const shouldShow = show ?? panel.style.display === 'none'; if (shouldShow) { panel.style.display = 'block'; panel.setAttribute('aria-hidden', 'false'); panel.style.opacity = '0'; panel.style.transform = 'translateY(20px)'; // 动画显示 requestAnimationFrame(() => { panel.style.opacity = '1'; panel.style.transform = 'translateY(0)'; }); if (triggerBtn) { triggerBtn.style.display = 'none'; } // 触发回调 if (window.pugeCreated) { window.pugeCreated(panel.querySelector('.puge-content-area')); window.pugeCreated = null; } } else { panel.style.opacity = '0'; panel.style.transform = 'translateY(20px)'; setTimeout(() => { panel.style.display = 'none'; panel.setAttribute('aria-hidden', 'true'); if (triggerBtn) { triggerBtn.style.display = 'block'; triggerBtn.style.opacity = '0'; triggerBtn.style.transform = 'scale(0.8)'; requestAnimationFrame(() => { triggerBtn.style.opacity = '1'; triggerBtn.style.transform = 'scale(1)'; }); } }, 300); } } // 全局方法挂载 static mountGlobalMethods() { window.owostart = () => { const instance = window.pugePanelInstance; if (instance) instance.togglePanel(); }; window.loadingDialog = () => { // 保留原接口,空实现 return; }; window.alertDialog = (text) => { if (window.logBox && window.logBox.add) { window.logBox.add(text); } else { console.log('Alert:', text); } }; } } // 创建样式(可以移到CSS文件中) function addStyles() { const style = document.createElement('style'); style.textContent = ` .puge-title-bar { position: relative; height: 40px; line-height: 40px; background: linear-gradient(135deg, #f5f5f5 0%, #e8e8e8 100%); border-bottom: 1px solid #e0e0e0; padding: 0 15px; font-weight: 600; font-size: 16px; color: #333; user-select: none; display: flex; justify-content: space-between; align-items: center; } .puge-title { font-size: 16px; color: #333; } .puge-close-btn { width: 30px; height: 40px; line-height: 40px; text-align: center; font-size: 24px; color: #666; cursor: pointer; transition: color 0.3s ease, transform 0.2s ease; border-radius: 4px; } .puge-close-btn:hover { color: #ff4444; transform: scale(1.1); } .puge-close-btn:active { transform: scale(0.95); } .puge-box { padding: 0 10px; overflow: auto; box-sizing: border-box; background-color: #fff; } .puge-trigger-btn { display: flex; align-items: center; justify-content: center; transition: all 0.3s ease !important; } .puge-star-icon { display: block; filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.1)); } .puge-login-box, .puge-box.puge-content-area { position: relative; padding-bottom: 10px; } @media (prefers-reduced-motion: reduce) { .puge-panel, .puge-trigger-btn, .puge-close-btn { transition: none !important; } } `; (document.head || document.documentElement).appendChild(style); } // 初始化 (function() { // 防止重复初始化 if (window.pugePanelInstance) return; // 添加样式 addStyles(); // 创建实例 window.pugePanelInstance = new PugePanel(); // 挂载全局方法 PugePanel.mountGlobalMethods(); })();