修改组件逻辑+优化代码
This commit is contained in:
@@ -45,7 +45,7 @@ body {
|
||||
background-color: var(--color-light);
|
||||
-webkit-font-smoothing: antialiased; /* 字体抗锯齿 */
|
||||
text-rendering: optimizeLegibility;
|
||||
overflow-x: hidden;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* ===== 排版元素 ===== */
|
||||
|
||||
@@ -42,10 +42,10 @@ interface IElementRect {
|
||||
width: number;
|
||||
/** 高度 */
|
||||
height: number;
|
||||
/** 顶点坐标(相对 offsetParent) */
|
||||
top: number;
|
||||
/** 左点坐标(相对 offsetParent) */
|
||||
left: number;
|
||||
/** x坐标 */
|
||||
x: number;
|
||||
/** y坐标 */
|
||||
y: number;
|
||||
}
|
||||
|
||||
/** 窗口自定义事件 */
|
||||
@@ -75,38 +75,50 @@ export class WindowFormElement extends LitElement {
|
||||
@property({ type: Boolean }) closable = true
|
||||
@property({ type: Boolean, reflect: true }) focused: boolean = true
|
||||
@property({ type: String, reflect: true }) windowFormState: TWindowFormState = 'default'
|
||||
@property({ type: Object }) dragContainer?: HTMLElement
|
||||
@property({ type: Boolean }) allowOverflow = true // 允许窗口超出容器
|
||||
@property({ type: Number }) snapDistance = 20 // 吸附距离
|
||||
@property({ type: Boolean }) snapAnimation = true // 吸附动画
|
||||
@property({ type: Object }) dragContainer?: HTMLElement // 元素的父容器
|
||||
@property({ type: Number }) snapDistance = 0 // 吸附距离
|
||||
@property({ type: Boolean }) snapAnimation = false // 吸附动画
|
||||
@property({ type: Number }) snapAnimationDuration = 300 // 吸附动画时长 ms
|
||||
@property({ type: Number }) maxWidth?: number = Infinity
|
||||
@property({ type: Number }) minWidth?: number = 0
|
||||
@property({ type: Number }) minWidth?: number = 200
|
||||
@property({ type: Number }) maxHeight?: number = Infinity
|
||||
@property({ type: Number }) minHeight?: number = 0
|
||||
@property({ type: Number }) minHeight?: number = 200
|
||||
@property({ type: String }) taskbarElementId?: string
|
||||
@property({ type: Object }) wfData: any;
|
||||
|
||||
private _listeners: Array<{ type: string; original: Function; wrapped: EventListener }> = []
|
||||
|
||||
// ==== 拖拽/缩放状态(内部变量,不触发渲染) ====
|
||||
private dragging = false
|
||||
private resizeDir: TResizeDirection | null = null
|
||||
private startX = 0
|
||||
private startY = 0
|
||||
private startWidth = 0
|
||||
private startHeight = 0
|
||||
private startX_host = 0
|
||||
private startY_host = 0
|
||||
|
||||
// 自身的x坐标
|
||||
private x = 0
|
||||
// 自身的y坐标
|
||||
private y = 0
|
||||
private preX = 0
|
||||
private preY = 0
|
||||
// 自身的宽度
|
||||
private width = 640
|
||||
// 自身的高度
|
||||
private height = 360
|
||||
|
||||
// 记录拖拽开始时自身x坐标
|
||||
private originalX = 0
|
||||
// 记录拖拽开始时自身y坐标
|
||||
private originalY = 0
|
||||
// 鼠标开始拖拽时自身宽度
|
||||
private originalWidth = 640
|
||||
// 鼠标开始拖拽时高度
|
||||
private originalHeight = 360
|
||||
|
||||
// 鼠标开始拖拽时x坐标
|
||||
private pointStartX = 0
|
||||
// 鼠标开始拖拽时x坐标
|
||||
private pointStartY = 0
|
||||
|
||||
private animationFrame?: number
|
||||
// 是否拖拽状态
|
||||
private dragging = false
|
||||
// 是否缩放状态
|
||||
private resizing = false
|
||||
// 缩放方向
|
||||
private resizeDir: TResizeDirection | null = null
|
||||
|
||||
// private get x() {
|
||||
// return this.wfData.state.x
|
||||
@@ -198,25 +210,28 @@ export class WindowFormElement extends LitElement {
|
||||
}
|
||||
|
||||
override firstUpdated() {
|
||||
console.log(this.wfData)
|
||||
// wfem.addEventListener('windowFormFocus', this.windowFormFocusFun)
|
||||
window.addEventListener('pointerup', this.onPointerUp)
|
||||
window.addEventListener('pointermove', this.onPointerMove)
|
||||
this.addEventListener('pointerdown', this.toggleFocus)
|
||||
const { width, height } = this.getBoundingClientRect()
|
||||
this.width = width || this.width
|
||||
this.height = height || this.height
|
||||
|
||||
const container = this.dragContainer || document.body
|
||||
const containerRect = container.getBoundingClientRect()
|
||||
this.x = containerRect.width / 2 - this.width / 2
|
||||
this.y = containerRect.height / 2 - this.height / 2
|
||||
|
||||
this.style.width = `${this.width}px`
|
||||
this.style.height = `${this.height}px`
|
||||
this.style.transform = `translate(${this.x}px, ${this.y}px)`
|
||||
|
||||
window.addEventListener('pointerup', this.onPointerUp)
|
||||
window.addEventListener('pointermove', this.onPointerMove)
|
||||
this.addEventListener('pointerdown', this.toggleFocus)
|
||||
|
||||
this.targetBounds = {
|
||||
width: this.offsetWidth,
|
||||
height: this.offsetHeight,
|
||||
top: this.x,
|
||||
left: this.y,
|
||||
width: this.width,
|
||||
height: this.height,
|
||||
x: this.x,
|
||||
y: this.y,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -257,10 +272,10 @@ export class WindowFormElement extends LitElement {
|
||||
e.preventDefault()
|
||||
|
||||
this.dragging = true
|
||||
this.startX = e.clientX
|
||||
this.startY = e.clientY
|
||||
this.preX = this.x
|
||||
this.preY = this.y
|
||||
this.pointStartX = e.clientX
|
||||
this.pointStartY = e.clientY
|
||||
this.originalX = this.x
|
||||
this.originalY = this.y
|
||||
this.setPointerCapture?.(e.pointerId)
|
||||
|
||||
this.dispatchEvent(
|
||||
@@ -272,15 +287,20 @@ export class WindowFormElement extends LitElement {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 鼠标指针移动
|
||||
* @param e
|
||||
*/
|
||||
private onPointerMove = (e: PointerEvent) => {
|
||||
if (this.dragging) {
|
||||
const dx = e.clientX - this.startX
|
||||
const dy = e.clientY - this.startY
|
||||
const dx = e.clientX - this.pointStartX
|
||||
const dy = e.clientY - this.pointStartY
|
||||
|
||||
const x = this.preX + dx
|
||||
const y = this.preY + dy
|
||||
const x = this.originalX + dx
|
||||
const y = this.originalY + dy
|
||||
|
||||
this.applyPosition(x, y, false)
|
||||
const pos = this.applyBoundary(x, y, e.clientX, e.clientY)
|
||||
this.applyPosition(pos.x, pos.y)
|
||||
this.dispatchEvent(
|
||||
new CustomEvent('windowForm:dragMove', {
|
||||
detail: { x, y },
|
||||
@@ -293,6 +313,10 @@ export class WindowFormElement extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 鼠标指针抬起
|
||||
* @param e
|
||||
*/
|
||||
private onPointerUp = (e: PointerEvent) => {
|
||||
if (this.dragging) {
|
||||
this.dragUp(e)
|
||||
@@ -320,13 +344,14 @@ export class WindowFormElement extends LitElement {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取最近的吸附点
|
||||
* @param x 左上角起始点x
|
||||
* @param y 左上角起始点y
|
||||
* 根据传入的坐标点位计算吸附距离最近的坐标位置
|
||||
* @param x 坐标点 x
|
||||
* @param y 坐标点 y
|
||||
* @returns {x: number, y: number} 新的位置坐标
|
||||
*/
|
||||
private applySnapping(x: number, y: number) {
|
||||
let snappedX = x,
|
||||
snappedY = y
|
||||
private calculateSnapping(x: number, y: number): { x: number, y: number} {
|
||||
let snappedX = x
|
||||
let snappedY = y
|
||||
const containerSnap = this.getSnapPoints()
|
||||
if (this.snapDistance > 0) {
|
||||
for (const sx of containerSnap.x)
|
||||
@@ -343,22 +368,28 @@ export class WindowFormElement extends LitElement {
|
||||
return { x: snappedX, y: snappedY }
|
||||
}
|
||||
|
||||
/**
|
||||
* 拖拽结束
|
||||
* @param e
|
||||
* @private
|
||||
*/
|
||||
private dragUp(e: PointerEvent) {
|
||||
const snapped = this.applySnapping(this.x, this.y)
|
||||
const snapped = this.calculateSnapping(this.x, this.y)
|
||||
if (this.snapAnimation) {
|
||||
this.animateTo(snapped.x, snapped.y, this.snapAnimationDuration, () => {
|
||||
this.updateTargetBounds(snapped.x, snapped.y)
|
||||
this.dispatchEvent(
|
||||
new CustomEvent('windowForm:dragEnd', {
|
||||
this.animateTo(this.x, this.y, snapped.x, snapped.y, this.snapAnimationDuration,
|
||||
(x, y) => {
|
||||
this.applyPosition(x, y)
|
||||
},
|
||||
(x, y) => {
|
||||
this.applyPosition(snapped.x, snapped.y)
|
||||
this.dispatchEvent(new CustomEvent('windowForm:dragEnd', {
|
||||
detail: { x: snapped.x, y: snapped.y },
|
||||
bubbles: true,
|
||||
composed: true,
|
||||
}),
|
||||
)
|
||||
}))
|
||||
})
|
||||
} else {
|
||||
this.applyPosition(snapped.x, snapped.y, true)
|
||||
this.updateTargetBounds(snapped.x, snapped.y)
|
||||
this.applyPosition(snapped.x, snapped.y)
|
||||
this.dispatchEvent(
|
||||
new CustomEvent('windowForm:dragEnd', {
|
||||
detail: { x: snapped.x, y: snapped.y },
|
||||
@@ -369,29 +400,65 @@ export class WindowFormElement extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
private applyPosition(x: number, y: number, isFinal: boolean) {
|
||||
/**
|
||||
* 根据鼠标指针的位置是否在容器边界内来限制窗口坐标
|
||||
* @param x 当前元素的左上角坐标 x
|
||||
* @param y 当前元素的左上角坐标 y
|
||||
* @param pointerX 当前鼠标在容器中的 X 坐标
|
||||
* @param pointerY 当前鼠标在容器中的 Y 坐标
|
||||
* @returns 限制后的坐标点 { x, y }
|
||||
*/
|
||||
private applyBoundary(x: number, y: number, pointerX: number, pointerY: number): { x: number; y: number } {
|
||||
const containerRect = (this.dragContainer || document.body).getBoundingClientRect()
|
||||
|
||||
// 限制指针在容器内
|
||||
const limitedPointerX = Math.min(Math.max(pointerX, containerRect.left), containerRect.right)
|
||||
const limitedPointerY = Math.min(Math.max(pointerY, containerRect.top), containerRect.bottom)
|
||||
|
||||
// 计算指针被限制后的偏移量
|
||||
const dx = limitedPointerX - pointerX
|
||||
const dy = limitedPointerY - pointerY
|
||||
|
||||
// 根据指针偏移调整窗口位置
|
||||
x += dx
|
||||
y += dy
|
||||
|
||||
return { x, y }
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置拖拽的窗口位置
|
||||
* @param x 当前元素的左上角坐标点 x
|
||||
* @param y 当前元素的左上角坐标点 y
|
||||
* @private
|
||||
*/
|
||||
private applyPosition(x: number, y: number) {
|
||||
this.x = x
|
||||
this.y = y
|
||||
this.style.transform = `translate(${x}px, ${y}px)`
|
||||
if (isFinal) this.applyBoundary()
|
||||
}
|
||||
|
||||
private applyBoundary() {
|
||||
if (this.allowOverflow) return
|
||||
let { x, y } = { x: this.x, y: this.y }
|
||||
|
||||
const rect = this.getBoundingClientRect()
|
||||
const containerRect = (this.dragContainer || document.body).getBoundingClientRect()
|
||||
x = Math.min(Math.max(x, 0), containerRect.width - rect.width)
|
||||
y = Math.min(Math.max(y, 0), containerRect.height - rect.height)
|
||||
|
||||
this.applyPosition(x, y, false)
|
||||
}
|
||||
|
||||
private animateTo(targetX: number, targetY: number, duration: number, onComplete?: () => void) {
|
||||
/**
|
||||
* 动画移动窗口
|
||||
* @param startX 窗口起始点 x
|
||||
* @param startY 窗口起始点 y
|
||||
* @param targetX 目标点 x
|
||||
* @param targetY 目标点 y
|
||||
* @param duration 动画时长
|
||||
* @param onMove 移动回调
|
||||
* @param onComplete 完成回调
|
||||
* @private
|
||||
*/
|
||||
private animateTo(
|
||||
startX: number,
|
||||
startY: number,
|
||||
targetX: number,
|
||||
targetY: number,
|
||||
duration: number,
|
||||
onMove?: (x: number, y: number) => void,
|
||||
onComplete?: (x: number, y: number) => void
|
||||
) {
|
||||
if (this.animationFrame) cancelAnimationFrame(this.animationFrame)
|
||||
const startX = this.x
|
||||
const startY = this.y
|
||||
const deltaX = targetX - startX
|
||||
const deltaY = targetY - startY
|
||||
const startTime = performance.now()
|
||||
@@ -404,7 +471,7 @@ export class WindowFormElement extends LitElement {
|
||||
const x = startX + deltaX * ease
|
||||
const y = startY + deltaY * ease
|
||||
|
||||
this.applyPosition(x, y, false)
|
||||
onMove?.(x, y)
|
||||
this.dispatchEvent(
|
||||
new CustomEvent('windowForm:dragMove', {
|
||||
detail: { x, y },
|
||||
@@ -416,8 +483,7 @@ export class WindowFormElement extends LitElement {
|
||||
if (progress < 1) {
|
||||
this.animationFrame = requestAnimationFrame(step)
|
||||
} else {
|
||||
this.applyPosition(targetX, targetY, true)
|
||||
onComplete?.()
|
||||
onComplete?.(targetX, targetY)
|
||||
}
|
||||
}
|
||||
this.animationFrame = requestAnimationFrame(step)
|
||||
@@ -432,14 +498,12 @@ export class WindowFormElement extends LitElement {
|
||||
e.stopPropagation()
|
||||
this.resizing = true
|
||||
this.resizeDir = dir
|
||||
this.startX = e.clientX
|
||||
this.startY = e.clientY
|
||||
|
||||
const rect = this.getBoundingClientRect()
|
||||
this.startWidth = rect.width
|
||||
this.startHeight = rect.height
|
||||
this.startX_host = rect.left
|
||||
this.startY_host = rect.top
|
||||
this.pointStartX = e.clientX
|
||||
this.pointStartY = e.clientY
|
||||
this.originalX = this.x
|
||||
this.originalY = this.y
|
||||
this.originalWidth = this.width
|
||||
this.originalHeight = this.height
|
||||
|
||||
const target = e.target as HTMLElement
|
||||
document.body.style.cursor = target.style.cursor || window.getComputedStyle(target).cursor
|
||||
@@ -454,59 +518,72 @@ export class WindowFormElement extends LitElement {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 缩放
|
||||
* @param e
|
||||
* @private
|
||||
*/
|
||||
private performResize(e: PointerEvent) {
|
||||
if (!this.resizeDir || !this.resizing) return
|
||||
|
||||
let newWidth = this.startWidth
|
||||
let newHeight = this.startHeight
|
||||
let newX = this.startX_host
|
||||
let newY = this.startY_host
|
||||
let newWidth = this.originalWidth
|
||||
let newHeight = this.originalHeight
|
||||
let newX = this.originalX
|
||||
let newY = this.originalY
|
||||
|
||||
const dx = e.clientX - this.startX
|
||||
const dy = e.clientY - this.startY
|
||||
const dx = e.clientX - this.pointStartX
|
||||
const dy = e.clientY - this.pointStartY
|
||||
|
||||
// ====== 根据方向计算临时尺寸与位置 ======
|
||||
switch (this.resizeDir) {
|
||||
case 'r':
|
||||
case 'r': // 右侧
|
||||
newWidth += dx
|
||||
break
|
||||
case 'b':
|
||||
case 'b': // 下方
|
||||
newHeight += dy
|
||||
break
|
||||
case 'l':
|
||||
case 'l': // 左侧
|
||||
newWidth -= dx
|
||||
newX += dx
|
||||
break
|
||||
case 't':
|
||||
case 't': // 上方
|
||||
newHeight -= dy
|
||||
newY += dy
|
||||
break
|
||||
case 'tl':
|
||||
case 'tl': // 左上角
|
||||
newWidth -= dx
|
||||
newX += dx
|
||||
newHeight -= dy
|
||||
newY += dy
|
||||
break
|
||||
case 'tr':
|
||||
case 'tr': // 右上角
|
||||
newWidth += dx
|
||||
newHeight -= dy
|
||||
newY += dy
|
||||
break
|
||||
case 'bl':
|
||||
case 'bl': // 左下角
|
||||
newWidth -= dx
|
||||
newX += dx
|
||||
newHeight += dy
|
||||
break
|
||||
case 'br':
|
||||
case 'br': // 右下角
|
||||
newWidth += dx
|
||||
newHeight += dy
|
||||
break
|
||||
}
|
||||
|
||||
const d = this.applyResizeBounds(newX, newY, newWidth, newHeight)
|
||||
const { x, y, width, height } = this.applyResizeBounds(newX, newY, newWidth, newHeight, this.resizeDir)
|
||||
|
||||
this.x = x
|
||||
this.y = y
|
||||
this.width = width
|
||||
this.height = height
|
||||
this.style.width = `${this.width}px`
|
||||
this.style.height = `${this.height}px`
|
||||
this.style.transform = `translate(${this.x}px, ${this.y}px)`
|
||||
this.dispatchEvent(
|
||||
new CustomEvent('windowForm:resizeMove', {
|
||||
detail: { dir: this.resizeDir, width: d.width, height: d.height, left: d.left, top: d.top },
|
||||
detail: { dir: this.resizeDir, width: width, height: height, left: x, top: y },
|
||||
bubbles: true,
|
||||
composed: true,
|
||||
}),
|
||||
@@ -514,68 +591,107 @@ export class WindowFormElement extends LitElement {
|
||||
}
|
||||
|
||||
/**
|
||||
* 应用尺寸调整边界
|
||||
* @param newX 新的X坐标
|
||||
* @param newY 新的Y坐标
|
||||
* @param newWidth 新的宽度
|
||||
* @param newHeight 新的高度
|
||||
* 计算尺寸调整约束逻辑,返回约束后的尺寸
|
||||
* @param x 坐标 x
|
||||
* @param y 坐标 y
|
||||
* @param width 宽度
|
||||
* @param height 高度
|
||||
* @private
|
||||
* @returns { x: number, y: number, width: number, height: number } 约束后的尺寸
|
||||
*/
|
||||
private applyResizeBounds(
|
||||
newX: number,
|
||||
newY: number,
|
||||
newWidth: number,
|
||||
newHeight: number,
|
||||
x: number,
|
||||
y: number,
|
||||
width: number,
|
||||
height: number,
|
||||
resizeDir: TResizeDirection
|
||||
): {
|
||||
left: number
|
||||
top: number
|
||||
x: number
|
||||
y: number
|
||||
width: number
|
||||
height: number
|
||||
} {
|
||||
// 最小/最大宽高限制
|
||||
if (this.minWidth != null) newWidth = Math.max(this.minWidth, newWidth)
|
||||
if (this.maxWidth != null) newWidth = Math.min(this.maxWidth, newWidth)
|
||||
if (this.minHeight != null) newHeight = Math.max(this.minHeight, newHeight)
|
||||
if (this.maxHeight != null) newHeight = Math.min(this.maxHeight, newHeight)
|
||||
const { minWidth = 100, minHeight = 100, maxWidth = Infinity, maxHeight = Infinity } = this
|
||||
|
||||
// 边界限制
|
||||
if (this.allowOverflow) {
|
||||
this.x = newX
|
||||
this.y = newY
|
||||
this.width = newWidth
|
||||
this.height = newHeight
|
||||
this.style.width = `${newWidth}px`
|
||||
this.style.height = `${newHeight}px`
|
||||
this.applyPosition(newX, newY, false)
|
||||
|
||||
return {
|
||||
left: newX,
|
||||
top: newY,
|
||||
width: newWidth,
|
||||
height: newHeight,
|
||||
}
|
||||
//#region 限制最大/最小尺寸
|
||||
// 限制宽度
|
||||
if (width < minWidth) {
|
||||
// 左缩时要修正X坐标,否则会跳动
|
||||
if (resizeDir.includes('l')) x -= minWidth - width
|
||||
width = minWidth
|
||||
} else if (width > maxWidth) {
|
||||
if (resizeDir.includes('l')) x += width - maxWidth
|
||||
width = maxWidth
|
||||
}
|
||||
|
||||
// 限制高度
|
||||
if (height < minHeight) {
|
||||
if (resizeDir.includes('t')) y -= minHeight - height
|
||||
height = minHeight
|
||||
} else if (height > maxHeight) {
|
||||
if (resizeDir.includes('t')) y += height - maxHeight
|
||||
height = maxHeight
|
||||
}
|
||||
//#endregion
|
||||
|
||||
//#region 限制在容器边界内
|
||||
const containerRect = (this.dragContainer || document.body).getBoundingClientRect()
|
||||
newX = Math.min(Math.max(0, newX), containerRect.width - newWidth)
|
||||
newY = Math.min(Math.max(0, newY), containerRect.height - newHeight)
|
||||
const maxLeft = containerRect.width - width
|
||||
const maxTop = containerRect.height - height
|
||||
|
||||
this.x = newX
|
||||
this.y = newY
|
||||
this.width = newWidth
|
||||
this.height = newHeight
|
||||
this.style.width = `${newWidth}px`
|
||||
this.style.height = `${newHeight}px`
|
||||
this.applyPosition(newX, newY, false)
|
||||
// 左越界(从左侧缩放时)
|
||||
if (x < 0) {
|
||||
if (resizeDir.includes('l')) {
|
||||
// 如果是往左拉出容器,锁定边界
|
||||
width += x // 因为x是负数,相当于减小宽度
|
||||
}
|
||||
x = 0
|
||||
}
|
||||
|
||||
// 顶部越界(从上侧缩放时)
|
||||
if (y < 0) {
|
||||
if (resizeDir.includes('t')) {
|
||||
height += y // y是负数,相当于减小高度
|
||||
}
|
||||
y = 0
|
||||
}
|
||||
|
||||
// 右越界(从右侧缩放时)
|
||||
if (x + width > containerRect.width) {
|
||||
if (resizeDir.includes('r')) {
|
||||
width = containerRect.width - x
|
||||
} else {
|
||||
x = Math.min(x, maxLeft)
|
||||
}
|
||||
}
|
||||
|
||||
// 底部越界(从下侧缩放时)
|
||||
if (y + height > containerRect.height) {
|
||||
if (resizeDir.includes('b')) {
|
||||
height = containerRect.height - y
|
||||
} else {
|
||||
y = Math.min(y, maxTop)
|
||||
}
|
||||
}
|
||||
//#endregion
|
||||
|
||||
// 二次防护:确保不小于最小值
|
||||
width = Math.max(width, minWidth)
|
||||
height = Math.max(height, minHeight)
|
||||
|
||||
return {
|
||||
left: newX,
|
||||
top: newY,
|
||||
width: newWidth,
|
||||
height: newHeight,
|
||||
x,
|
||||
y,
|
||||
width,
|
||||
height
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 缩放结束
|
||||
* @param e
|
||||
* @private
|
||||
*/
|
||||
private resizeUp(e: PointerEvent) {
|
||||
if (!this.resizable) return
|
||||
|
||||
@@ -617,12 +733,16 @@ export class WindowFormElement extends LitElement {
|
||||
startY,
|
||||
startW,
|
||||
startH,
|
||||
rect.left,
|
||||
rect.top,
|
||||
rect.x,
|
||||
rect.y,
|
||||
rect.width,
|
||||
rect.height,
|
||||
400,
|
||||
() => {
|
||||
(x, y, w, h) => {
|
||||
this.applyWindowStyle(x, y, w, h)
|
||||
},
|
||||
(x, y, w, h) => {
|
||||
this.applyWindowStyle(x, y, w, h)
|
||||
this.style.display = 'none'
|
||||
this.dispatchEvent(
|
||||
new CustomEvent('windowForm:stateChange:minimize', {
|
||||
@@ -667,7 +787,11 @@ export class WindowFormElement extends LitElement {
|
||||
targetW,
|
||||
targetH,
|
||||
300,
|
||||
() => {
|
||||
(x, y, w, h) => {
|
||||
this.applyWindowStyle(x, y, w, h)
|
||||
},
|
||||
(x, y, w, h) => {
|
||||
this.applyWindowStyle(x, y, w, h)
|
||||
this.dispatchEvent(
|
||||
new CustomEvent('windowForm:stateChange:maximize', {
|
||||
detail: { state: this.windowFormState },
|
||||
@@ -713,12 +837,16 @@ export class WindowFormElement extends LitElement {
|
||||
startY,
|
||||
startW,
|
||||
startH,
|
||||
b.left,
|
||||
b.top,
|
||||
b.x,
|
||||
b.y,
|
||||
b.width,
|
||||
b.height,
|
||||
300,
|
||||
() => {
|
||||
(x, y, w, h) => {
|
||||
this.applyWindowStyle(x, y, w, h)
|
||||
},
|
||||
(x, y, w, h) => {
|
||||
this.applyWindowStyle(x, y, w, h)
|
||||
onComplete?.()
|
||||
this.dispatchEvent(
|
||||
new CustomEvent('windowForm:stateChange:restore', {
|
||||
@@ -731,6 +859,24 @@ export class WindowFormElement extends LitElement {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 应用窗体样式
|
||||
* @param x
|
||||
* @param y
|
||||
* @param w
|
||||
* @param h
|
||||
* @private
|
||||
*/
|
||||
private applyWindowStyle(x: number, y: number, w: number, h: number) {
|
||||
this.width = w
|
||||
this.height = h
|
||||
this.x = x
|
||||
this.y = y
|
||||
this.style.width = `${w}px`
|
||||
this.style.height = `${h}px`
|
||||
this.style.transform = `translate(${x}px, ${y}px)`
|
||||
}
|
||||
|
||||
private windowFormClose() {
|
||||
this.dispatchEvent(
|
||||
new CustomEvent('windowForm:close', {
|
||||
@@ -764,7 +910,8 @@ export class WindowFormElement extends LitElement {
|
||||
targetW: number,
|
||||
targetH: number,
|
||||
duration: number,
|
||||
onComplete?: () => void,
|
||||
onUpdating?: (x: number, y: number, w: number, h: number) => void,
|
||||
onComplete?: (x: number, y: number, w: number, h: number) => void,
|
||||
) {
|
||||
const startTime = performance.now()
|
||||
const step = (now: number) => {
|
||||
@@ -777,17 +924,14 @@ export class WindowFormElement extends LitElement {
|
||||
const w = startW + (targetW - startW) * ease
|
||||
const h = startH + (targetH - startH) * ease
|
||||
|
||||
this.style.width = `${w}px`
|
||||
this.style.height = `${h}px`
|
||||
this.applyPosition(x, y, false)
|
||||
onUpdating?.(x, y, w, h)
|
||||
|
||||
if (progress < 1) {
|
||||
requestAnimationFrame(step)
|
||||
} else {
|
||||
this.style.width = `${targetW}px`
|
||||
this.style.height = `${targetH}px`
|
||||
this.applyPosition(targetX, targetY, true)
|
||||
onComplete?.()
|
||||
onComplete?.(x, y, w, h)
|
||||
this.dispatchEvent(
|
||||
new CustomEvent('windowForm:stateChange', {
|
||||
detail: { state: this.windowFormState },
|
||||
@@ -800,10 +944,10 @@ export class WindowFormElement extends LitElement {
|
||||
requestAnimationFrame(step)
|
||||
}
|
||||
|
||||
private updateTargetBounds(left: number, top: number, width?: number, height?: number) {
|
||||
private updateTargetBounds(x: number, y: number, width?: number, height?: number) {
|
||||
this.targetBounds = {
|
||||
left,
|
||||
top,
|
||||
x,
|
||||
y,
|
||||
width: width ?? this.offsetWidth,
|
||||
height: height ?? this.offsetHeight,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user