Compare commits

..

2 Commits

View File

@@ -492,35 +492,109 @@ 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);
}
/**
* 窗体最大化、最小化和恢复默认 动画
* @param startX
* @param startY
* @param startW
* @param startH
* @param targetX
* @param targetY
* @param targetW
* @param targetH
* @param duration
* @param onComplete
* @private
*/
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) {