@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.
@@ -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.17",
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"
@@ -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
- }