Compare commits
2 Commits
442a44dfc1
...
fcf3c2933c
| Author | SHA1 | Date | |
|---|---|---|---|
| fcf3c2933c | |||
| 3d402de0af |
@@ -492,35 +492,109 @@ export class DraggableResizableWindow {
|
|||||||
this.updateCursor(dir);
|
this.updateCursor(dir);
|
||||||
};
|
};
|
||||||
|
|
||||||
/** ---------------- 最小化/最大化 ---------------- */
|
// 最小化到任务栏
|
||||||
public minimize() {
|
public minimize() {
|
||||||
if (this.state === 'minimized') return;
|
if (this.state === 'minimized') return;
|
||||||
this.state = 'minimized';
|
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();
|
const rect = taskbar.getBoundingClientRect();
|
||||||
this.animateTo(rect.left, rect.top, 200);
|
const startX = this.currentX;
|
||||||
this.target.style.width = '0px';
|
const startY = this.currentY;
|
||||||
this.target.style.height = '0px';
|
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() {
|
public maximize() {
|
||||||
if (this.state === 'maximized') return;
|
if (this.state === 'maximized') return;
|
||||||
this.state = 'maximized';
|
this.state = 'maximized';
|
||||||
const bounds = { top: 0, left: 0, width: window.innerWidth, height: window.innerHeight };
|
|
||||||
this.maximizedBounds = bounds;
|
const rect = this.target.getBoundingClientRect();
|
||||||
this.animateTo(bounds.left, bounds.top, 200);
|
this.targetDefaultBounds = { width: rect.width, height: rect.height, left: rect.left, top: rect.top };
|
||||||
this.target.style.width = `${bounds.width}px`;
|
|
||||||
this.target.style.height = `${bounds.height}px`;
|
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() {
|
public restore() {
|
||||||
if (this.state === 'default') return;
|
if (this.state === 'default') return;
|
||||||
this.state = 'default';
|
this.state = 'default';
|
||||||
const b = this.targetDefaultBounds;
|
const b = this.targetDefaultBounds;
|
||||||
this.animateTo(b.left, b.top, 200);
|
|
||||||
this.target.style.width = `${b.width}px`;
|
const startX = this.currentX;
|
||||||
this.target.style.height = `${b.height}px`;
|
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) {
|
private updateDefaultBounds(left: number, top: number, width?: number, height?: number) {
|
||||||
|
|||||||
Reference in New Issue
Block a user