@talex-touch/utils 1.0.17 → 1.0.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/animation/window.ts +191 -0
- package/package.json +3 -2
- package/electron/window.ts +0 -71
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import gsap from 'gsap'
|
|
2
|
+
import { TalexTouch } from '../types'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Window animation controller return type
|
|
6
|
+
*/
|
|
7
|
+
export interface WindowAnimationController {
|
|
8
|
+
/**
|
|
9
|
+
* Update window height with animation
|
|
10
|
+
* @param newHeight - The new height to animate to
|
|
11
|
+
* @param duration - Animation duration in seconds (default: 0.5)
|
|
12
|
+
* @returns Promise that resolves to true if animation completed successfully, false if interrupted
|
|
13
|
+
*/
|
|
14
|
+
updateHeight: (newHeight: number, duration?: number) => Promise<boolean>
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Cancel current animation
|
|
18
|
+
* @returns Promise that resolves to true if there was an animation to cancel, false otherwise
|
|
19
|
+
*/
|
|
20
|
+
cancel: () => Promise<boolean>
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Toggle window visibility
|
|
24
|
+
* @param visible - Optional parameter to explicitly set visibility state
|
|
25
|
+
* @returns Promise that resolves to true if operation completed successfully, false otherwise
|
|
26
|
+
*/
|
|
27
|
+
toggleWindow: (visible?: boolean) => Promise<boolean>
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Change current window instance
|
|
31
|
+
* @param newWindow - New TouchWindow instance
|
|
32
|
+
*/
|
|
33
|
+
changeWindow: (newWindow: TalexTouch.ITouchWindow) => void
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Tracks the state of an animation
|
|
38
|
+
*/
|
|
39
|
+
interface AnimationState {
|
|
40
|
+
tween: gsap.core.Tween | null
|
|
41
|
+
completed: boolean
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Use GSAP to animate window with cubic-bezier easing
|
|
46
|
+
* @param window - TouchWindow instance (optional, can be set later with changeWindow)
|
|
47
|
+
* @returns WindowAnimationController with updateHeight, cancel, toggleWindow, and changeWindow methods
|
|
48
|
+
*/
|
|
49
|
+
export function useWindowAnimation(window?: TalexTouch.ITouchWindow): WindowAnimationController {
|
|
50
|
+
// Store current window reference inside the function scope
|
|
51
|
+
let currentWindow: TalexTouch.ITouchWindow | null = window || null
|
|
52
|
+
|
|
53
|
+
const animationState: AnimationState = {
|
|
54
|
+
tween: null,
|
|
55
|
+
completed: false
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Check if current window is valid
|
|
60
|
+
* @returns true if window is valid, false otherwise
|
|
61
|
+
*/
|
|
62
|
+
const isWindowValid = (): boolean => {
|
|
63
|
+
return (
|
|
64
|
+
currentWindow !== null &&
|
|
65
|
+
currentWindow.window !== null &&
|
|
66
|
+
!currentWindow.window.isDestroyed()
|
|
67
|
+
)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Get current window with validation
|
|
72
|
+
* @returns current window or throws error if invalid
|
|
73
|
+
*/
|
|
74
|
+
const getCurrentWindow = (): TalexTouch.ITouchWindow => {
|
|
75
|
+
if (!isWindowValid()) {
|
|
76
|
+
throw new Error('Window is not valid or has been destroyed')
|
|
77
|
+
}
|
|
78
|
+
return currentWindow!
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const updateHeight = async (newHeight: number, duration: number = 0.5): Promise<boolean> => {
|
|
82
|
+
try {
|
|
83
|
+
const window = getCurrentWindow()
|
|
84
|
+
|
|
85
|
+
// Cancel any existing animation
|
|
86
|
+
if (animationState.tween) {
|
|
87
|
+
animationState.tween.kill()
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Reset state for new animation
|
|
91
|
+
animationState.completed = false
|
|
92
|
+
|
|
93
|
+
const browserWindow = window.window
|
|
94
|
+
const [currentWidth, currentHeight] = browserWindow.getSize()
|
|
95
|
+
const [x, y] = browserWindow.getPosition()
|
|
96
|
+
|
|
97
|
+
return new Promise<boolean>((resolve) => {
|
|
98
|
+
animationState.tween = gsap.to(
|
|
99
|
+
{
|
|
100
|
+
height: currentHeight
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
height: newHeight,
|
|
104
|
+
duration,
|
|
105
|
+
ease: 'cubic-bezier(0.785, 0.135, 0.15, 0.86)',
|
|
106
|
+
onUpdate: function () {
|
|
107
|
+
// Check if animation was cancelled or window destroyed
|
|
108
|
+
if (!animationState.tween || !isWindowValid()) {
|
|
109
|
+
resolve(false)
|
|
110
|
+
return
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const animatedHeight = Math.round(this.targets()[0].height)
|
|
114
|
+
browserWindow.setSize(currentWidth, animatedHeight)
|
|
115
|
+
browserWindow.setPosition(x, y)
|
|
116
|
+
},
|
|
117
|
+
onComplete: () => {
|
|
118
|
+
animationState.tween = null
|
|
119
|
+
animationState.completed = true
|
|
120
|
+
resolve(true)
|
|
121
|
+
},
|
|
122
|
+
onKill: () => {
|
|
123
|
+
animationState.tween = null
|
|
124
|
+
resolve(false)
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
)
|
|
128
|
+
})
|
|
129
|
+
} catch (error) {
|
|
130
|
+
console.error('Error in updateHeight:', error)
|
|
131
|
+
return Promise.resolve(false)
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const cancel = async (): Promise<boolean> => {
|
|
136
|
+
if (animationState.tween) {
|
|
137
|
+
animationState.tween.kill()
|
|
138
|
+
animationState.tween = null
|
|
139
|
+
return Promise.resolve(true)
|
|
140
|
+
}
|
|
141
|
+
return Promise.resolve(false)
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const toggleWindow = async (visible?: boolean): Promise<boolean> => {
|
|
145
|
+
try {
|
|
146
|
+
const window = getCurrentWindow()
|
|
147
|
+
const browserWindow = window.window
|
|
148
|
+
|
|
149
|
+
// Determine target visibility state
|
|
150
|
+
const targetVisible = visible !== undefined ? visible : !browserWindow.isVisible()
|
|
151
|
+
|
|
152
|
+
if (targetVisible) {
|
|
153
|
+
// Show window
|
|
154
|
+
browserWindow.show()
|
|
155
|
+
} else {
|
|
156
|
+
// Hide window
|
|
157
|
+
if (process.platform === 'darwin') {
|
|
158
|
+
// On macOS, we can simply hide the window
|
|
159
|
+
browserWindow.hide()
|
|
160
|
+
} else {
|
|
161
|
+
// On other platforms, move window far off-screen before hiding
|
|
162
|
+
browserWindow.setPosition(-100000, -100000)
|
|
163
|
+
browserWindow.hide()
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
return Promise.resolve(true)
|
|
168
|
+
} catch (error) {
|
|
169
|
+
console.error('Error in toggleWindow:', error)
|
|
170
|
+
return Promise.resolve(false)
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const changeWindow = (newWindow: TalexTouch.ITouchWindow): void => {
|
|
175
|
+
// Cancel any ongoing animation
|
|
176
|
+
if (animationState.tween) {
|
|
177
|
+
animationState.tween.kill()
|
|
178
|
+
animationState.tween = null
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Set new window
|
|
182
|
+
currentWindow = newWindow
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
return {
|
|
186
|
+
updateHeight,
|
|
187
|
+
cancel,
|
|
188
|
+
toggleWindow,
|
|
189
|
+
changeWindow
|
|
190
|
+
}
|
|
191
|
+
}
|
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"module": "./index.ts",
|
|
6
6
|
"license": "MPL-2.0",
|
|
7
7
|
"private": false,
|
|
8
|
-
"version": "1.0.
|
|
8
|
+
"version": "1.0.18",
|
|
9
9
|
"exports": {
|
|
10
10
|
".": "./index.ts",
|
|
11
11
|
"./types": "./types/index.ts",
|
|
@@ -29,7 +29,8 @@
|
|
|
29
29
|
"./service": "./service/index.ts",
|
|
30
30
|
"./service/protocol": "./service/protocol/index.ts",
|
|
31
31
|
"./electron/env-tool": "./electron/env-tool.ts",
|
|
32
|
-
"./electron/download-manager": "./electron/download-manager.ts"
|
|
32
|
+
"./electron/download-manager": "./electron/download-manager.ts",
|
|
33
|
+
"./animation/": "./animation/"
|
|
33
34
|
},
|
|
34
35
|
"scripts": {
|
|
35
36
|
"publish": "npm publish --access public"
|
package/electron/window.ts
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
import gsap from 'gsap'
|
|
2
|
-
TalexTouch.
|
|
3
|
-
// 使用类型注释避免直接引用Electron命名空间
|
|
4
|
-
interface ITouchWindow {
|
|
5
|
-
window: {
|
|
6
|
-
getSize(): [number, number];
|
|
7
|
-
getPosition(): [number, number];
|
|
8
|
-
setSize(width: number, height: number): void;
|
|
9
|
-
setPosition(x: number, y: number): void;
|
|
10
|
-
};
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
// 保存当前动画实例的引用,用于取消上次动画
|
|
14
|
-
let currentTween: gsap.core.Tween | null = null
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* 使用GSAP动画设置窗口高度的函数
|
|
18
|
-
* @param window TouchWindow对象
|
|
19
|
-
* @returns 返回一个可以更新窗口高度的方法
|
|
20
|
-
*/
|
|
21
|
-
export function useWindowHeight(window: ITouchWindow): {
|
|
22
|
-
updateHeight: (newHeight: number, duration?: number) => void
|
|
23
|
-
} {
|
|
24
|
-
/**
|
|
25
|
-
* 更新窗口高度的方法
|
|
26
|
-
* @param newHeight 新的高度值
|
|
27
|
-
* @param duration 动画持续时间,默认为0.5秒
|
|
28
|
-
*/
|
|
29
|
-
const updateHeight = (newHeight: number, duration: number = 0.5): void => {
|
|
30
|
-
// 如果存在上次的动画,先取消它
|
|
31
|
-
if (currentTween) {
|
|
32
|
-
currentTween.kill()
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// 获取当前窗口的BrowserWindow实例
|
|
36
|
-
const browserWindow = window.window
|
|
37
|
-
|
|
38
|
-
// 获取当前窗口的位置和宽度
|
|
39
|
-
const [currentWidth, currentHeight] = browserWindow.getSize()
|
|
40
|
-
const [x, y] = browserWindow.getPosition()
|
|
41
|
-
|
|
42
|
-
// 使用GSAP创建动画
|
|
43
|
-
currentTween = gsap.to(
|
|
44
|
-
{
|
|
45
|
-
height: currentHeight
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
height: newHeight,
|
|
49
|
-
duration,
|
|
50
|
-
ease: 'cubic-bezier(0.785, 0.135, 0.15, 0.86)', // 使用指定的贝塞尔曲线
|
|
51
|
-
onUpdate: function () {
|
|
52
|
-
// 在动画更新时调整窗口大小
|
|
53
|
-
const animatedHeight = Math.round(this.targets()[0].height)
|
|
54
|
-
browserWindow.setSize(currentWidth, animatedHeight)
|
|
55
|
-
|
|
56
|
-
// 保持窗口的顶部位置不变,只改变高度
|
|
57
|
-
browserWindow.setPosition(x, y)
|
|
58
|
-
},
|
|
59
|
-
onComplete: () => {
|
|
60
|
-
// 动画完成时,清除引用
|
|
61
|
-
currentTween = null
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
)
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// 返回更新高度的方法
|
|
68
|
-
return {
|
|
69
|
-
updateHeight
|
|
70
|
-
}
|
|
71
|
-
}
|