窗体最大化、最小化和恢复默认状态
This commit is contained in:
@@ -492,35 +492,95 @@ export class DraggableResizableWindow {
|
||||
this.updateCursor(dir);
|
||||
};
|
||||
|
||||
/** ---------------- 最小化/最大化 ---------------- */
|
||||
// 最小化到任务栏
|
||||
public minimize() {
|
||||
if (this.state === 'minimized') return;
|
||||
this.state = 'minimized';
|
||||
const taskbar = document.getElementById(this.taskbarElementId);
|
||||
if (!taskbar) return;
|
||||
|
||||
const taskbar = document.querySelector(this.taskbarElementId);
|
||||
if (!taskbar) throw new Error('任务栏元素未找到');
|
||||
|
||||
const rect = taskbar.getBoundingClientRect();
|
||||
this.animateTo(rect.left, rect.top, 200);
|
||||
this.target.style.width = '0px';
|
||||
this.target.style.height = '0px';
|
||||
const startX = this.currentX;
|
||||
const startY = this.currentY;
|
||||
const startW = this.target.offsetWidth;
|
||||
const startH = this.target.offsetHeight;
|
||||
|
||||
this.animateWindow(startX, startY, startW, startH, rect.left, rect.top, rect.width, rect.height, 400);
|
||||
}
|
||||
|
||||
/** 最大化 */
|
||||
public maximize() {
|
||||
if (this.state === 'maximized') return;
|
||||
this.state = 'maximized';
|
||||
const bounds = { top: 0, left: 0, width: window.innerWidth, height: window.innerHeight };
|
||||
this.maximizedBounds = bounds;
|
||||
this.animateTo(bounds.left, bounds.top, 200);
|
||||
this.target.style.width = `${bounds.width}px`;
|
||||
this.target.style.height = `${bounds.height}px`;
|
||||
|
||||
const rect = this.target.getBoundingClientRect();
|
||||
this.targetDefaultBounds = { width: rect.width, height: rect.height, left: rect.left, top: rect.top };
|
||||
|
||||
const startX = this.currentX;
|
||||
const startY = this.currentY;
|
||||
const startW = rect.width;
|
||||
const startH = rect.height;
|
||||
|
||||
const targetX = 0;
|
||||
const targetY = 0;
|
||||
const targetW = this.containerRect?.width ?? window.innerWidth;
|
||||
const targetH = this.containerRect?.height ?? window.innerHeight;
|
||||
|
||||
this.animateWindow(startX, startY, startW, startH, targetX, targetY, targetW, targetH, 300);
|
||||
}
|
||||
|
||||
/** 恢复到默认窗体状态 */
|
||||
public restore() {
|
||||
if (this.state === 'default') return;
|
||||
this.state = 'default';
|
||||
const b = this.targetDefaultBounds;
|
||||
this.animateTo(b.left, b.top, 200);
|
||||
this.target.style.width = `${b.width}px`;
|
||||
this.target.style.height = `${b.height}px`;
|
||||
|
||||
const startX = this.currentX;
|
||||
const startY = this.currentY;
|
||||
const startW = this.target.offsetWidth;
|
||||
const startH = this.target.offsetHeight;
|
||||
|
||||
this.animateWindow(startX, startY, startW, startH, b.left, b.top, b.width, b.height, 300);
|
||||
}
|
||||
|
||||
private animateWindow(
|
||||
startX: number,
|
||||
startY: number,
|
||||
startW: number,
|
||||
startH: number,
|
||||
targetX: number,
|
||||
targetY: number,
|
||||
targetW: number,
|
||||
targetH: number,
|
||||
duration: number,
|
||||
onComplete?: () => void
|
||||
) {
|
||||
const startTime = performance.now();
|
||||
const step = (now: number) => {
|
||||
const elapsed = now - startTime;
|
||||
const progress = Math.min(elapsed / duration, 1);
|
||||
const ease = 1 - Math.pow(1 - progress, 3);
|
||||
|
||||
const x = startX + (targetX - startX) * ease;
|
||||
const y = startY + (targetY - startY) * ease;
|
||||
const w = startW + (targetW - startW) * ease;
|
||||
const h = startH + (targetH - startH) * ease;
|
||||
|
||||
this.target.style.width = `${w}px`;
|
||||
this.target.style.height = `${h}px`;
|
||||
this.applyPosition(x, y, false);
|
||||
|
||||
if (progress < 1) {
|
||||
requestAnimationFrame(step);
|
||||
} else {
|
||||
this.target.style.width = `${targetW}px`;
|
||||
this.target.style.height = `${targetH}px`;
|
||||
this.applyPosition(targetX, targetY, true);
|
||||
onComplete?.();
|
||||
}
|
||||
};
|
||||
requestAnimationFrame(step);
|
||||
}
|
||||
|
||||
private updateDefaultBounds(left: number, top: number, width?: number, height?: number) {
|
||||
|
||||
Reference in New Issue
Block a user