feat(面板): 实现浮动面板拖拽功能并优化样式

添加面板拖拽功能,允许用户通过标题栏拖动面板。重构面板样式,移除固定位置属性,改为居中显示并支持动态调整。同时添加语言面板状态管理,优化面板动画效果。
This commit is contained in:
2026-05-07 08:46:47 +08:00
parent 7c01dc5f2e
commit 03c8db8826
2 changed files with 67 additions and 12 deletions

View File

@@ -121,9 +121,65 @@ const fullscreenState = {
const panelState = {
configPanel: false,
captionPanel: false,
languagePanel: false,
logPanel: false
};
let panelDragState = {
isDragging: false,
currentPanel: null,
offsetX: 0,
offsetY: 0,
originalHeight: null
};
function initPanelDrag() {
document.querySelectorAll('.floating-panel').forEach(panel => {
const header = panel.querySelector('.panel-header');
if (!header) return;
header.style.cursor = 'move';
header.addEventListener('mousedown', (e) => {
if (e.target.tagName === 'BUTTON') return;
panelDragState.isDragging = true;
panelDragState.currentPanel = panel;
const rect = panel.getBoundingClientRect();
panelDragState.offsetX = e.clientX - rect.left;
panelDragState.offsetY = e.clientY - rect.top;
panelDragState.originalHeight = panel.offsetHeight;
panel.style.transform = 'none';
panel.style.height = panelDragState.originalHeight + 'px';
});
document.addEventListener('mousemove', (e) => {
if (!panelDragState.isDragging || !panelDragState.currentPanel) return;
const x = e.clientX - panelDragState.offsetX;
const y = e.clientY - panelDragState.offsetY;
const maxX = window.innerWidth - panelDragState.currentPanel.offsetWidth;
const maxY = window.innerHeight - panelDragState.currentPanel.offsetHeight;
panelDragState.currentPanel.style.left = Math.max(0, Math.min(x, maxX)) + 'px';
panelDragState.currentPanel.style.top = Math.max(0, Math.min(y, maxY)) + 'px';
});
document.addEventListener('mouseup', () => {
if (panelDragState.isDragging) {
panelDragState.isDragging = false;
if (panelDragState.currentPanel) {
panelDragState.currentPanel.style.height = '';
}
panelDragState.currentPanel = null;
}
});
});
}
const logger = {
log(level, message, data = null) {
const timestamp = new Date().toLocaleTimeString('zh-CN', { hour12: false });
@@ -1248,6 +1304,7 @@ function init() {
bindEvents();
updateUIState();
initScaling();
initPanelDrag();
watchCaptionContainer();
}

View File

@@ -182,26 +182,28 @@ body {
z-index: 999;
display: none;
flex-direction: column;
max-height: 80vh;
overflow: hidden;
animation: panelSlideIn 0.2s ease-out;
}
.floating-panel.visible {
display: flex;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
@keyframes panelSlideIn {
from {
opacity: 0;
transform: translateY(10px);
transform: translate(-50%, -50%) translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
transform: translate(-50%, -50%) translateY(0);
}
}
.floating-panel.visible {
display: flex;
}
.panel-header {
display: flex;
justify-content: space-between;
@@ -246,10 +248,8 @@ body {
/* ===== 连接配置面板 ===== */
.config-panel {
bottom: calc(var(--spacing-xl) + 60px);
right: var(--spacing-xl);
width: 360px;
max-height: 70vh;
}
.config-section {
@@ -338,6 +338,7 @@ body {
bottom: calc(var(--spacing-xl) + 60px);
right: var(--spacing-xl);
width: 320px;
max-height: 90vh;
}
.caption-style-section {
@@ -364,7 +365,6 @@ body {
/* ===== 语言切换面板 ===== */
.language-panel {
bottom: calc(var(--spacing-xl) + 60px);
right: var(--spacing-xl);
width: 280px;
}
@@ -408,10 +408,8 @@ body {
/* ===== 日志面板 ===== */
.log-panel {
bottom: calc(var(--spacing-xl) + 60px);
right: var(--spacing-xl);
width: 450px;
max-height: 60vh;
}
.log-toolbar {