react-native-gradient-mask 0.1.0-beta.1

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.
Files changed (54) hide show
  1. package/.eslintrc.js +5 -0
  2. package/PUBLISHING.md +171 -0
  3. package/README.md +360 -0
  4. package/android/build.gradle +43 -0
  5. package/android/src/main/AndroidManifest.xml +2 -0
  6. package/android/src/main/java/expo/modules/gradientmask/GradientMaskModule.kt +33 -0
  7. package/android/src/main/java/expo/modules/gradientmask/GradientMaskView.kt +198 -0
  8. package/build/AnimatedGradientMaskView.d.ts +36 -0
  9. package/build/AnimatedGradientMaskView.d.ts.map +1 -0
  10. package/build/AnimatedGradientMaskView.js +37 -0
  11. package/build/AnimatedGradientMaskView.js.map +1 -0
  12. package/build/AnimatedGradientMaskView.web.d.ts +17 -0
  13. package/build/AnimatedGradientMaskView.web.d.ts.map +1 -0
  14. package/build/AnimatedGradientMaskView.web.js +100 -0
  15. package/build/AnimatedGradientMaskView.web.js.map +1 -0
  16. package/build/GradientMask.types.d.ts +38 -0
  17. package/build/GradientMask.types.d.ts.map +1 -0
  18. package/build/GradientMask.types.js +2 -0
  19. package/build/GradientMask.types.js.map +1 -0
  20. package/build/GradientMaskModule.d.ts +3 -0
  21. package/build/GradientMaskModule.d.ts.map +1 -0
  22. package/build/GradientMaskModule.js +4 -0
  23. package/build/GradientMaskModule.js.map +1 -0
  24. package/build/GradientMaskModule.web.d.ts +3 -0
  25. package/build/GradientMaskModule.web.d.ts.map +1 -0
  26. package/build/GradientMaskModule.web.js +3 -0
  27. package/build/GradientMaskModule.web.js.map +1 -0
  28. package/build/GradientMaskView.d.ts +4 -0
  29. package/build/GradientMaskView.d.ts.map +1 -0
  30. package/build/GradientMaskView.js +7 -0
  31. package/build/GradientMaskView.js.map +1 -0
  32. package/build/GradientMaskView.web.d.ts +8 -0
  33. package/build/GradientMaskView.web.d.ts.map +1 -0
  34. package/build/GradientMaskView.web.js +99 -0
  35. package/build/GradientMaskView.web.js.map +1 -0
  36. package/build/index.d.ts +6 -0
  37. package/build/index.d.ts.map +1 -0
  38. package/build/index.js +7 -0
  39. package/build/index.js.map +1 -0
  40. package/expo-module.config.json +9 -0
  41. package/ios/GradientMask.podspec +29 -0
  42. package/ios/GradientMaskModule.swift +29 -0
  43. package/ios/GradientMaskView.swift +133 -0
  44. package/package.json +83 -0
  45. package/rn-gradient-mask-design.md +657 -0
  46. package/src/AnimatedGradientMaskView.tsx +60 -0
  47. package/src/AnimatedGradientMaskView.web.tsx +149 -0
  48. package/src/GradientMask.types.ts +43 -0
  49. package/src/GradientMaskModule.ts +4 -0
  50. package/src/GradientMaskModule.web.ts +2 -0
  51. package/src/GradientMaskView.tsx +11 -0
  52. package/src/GradientMaskView.web.tsx +129 -0
  53. package/src/index.ts +7 -0
  54. package/tsconfig.json +9 -0
package/.eslintrc.js ADDED
@@ -0,0 +1,5 @@
1
+ module.exports = {
2
+ root: true,
3
+ extends: ['universe/native', 'universe/web'],
4
+ ignorePatterns: ['build'],
5
+ };
package/PUBLISHING.md ADDED
@@ -0,0 +1,171 @@
1
+ # 發佈流程指南
2
+
3
+ 本文件說明如何進行 NPM 套件的測試發佈與正式發佈。
4
+
5
+ ## 分支策略
6
+
7
+ | 分支 | 用途 | NPM 發佈 |
8
+ |------|------|----------|
9
+ | `main` | 正式穩定版本 | ✅ 正式發佈 |
10
+ | `feat/*` | 功能開發 | ❌ 不發佈 |
11
+ | `beta` | 測試版本 | ✅ Beta 發佈 |
12
+
13
+ ---
14
+
15
+ ## 測試發佈流程(非正式)
16
+
17
+ ### 方法一:使用 npm pack 本地測試
18
+
19
+ 這是最安全的方式,不會發佈到 npm registry。
20
+
21
+ ```bash
22
+ # 1. 確保程式碼已建置
23
+ npm run build
24
+
25
+ # 2. 產生 .tgz 壓縮包(模擬發佈)
26
+ npm pack
27
+
28
+ # 3. 檢視產生的檔案內容
29
+ tar -tzf react-native-gradient-mask-0.1.0.tgz
30
+
31
+ # 4. 在其他專案中測試安裝
32
+ cd /path/to/your/test-project
33
+ npm install /path/to/react-native-gradient-mask-0.1.0.tgz
34
+ ```
35
+
36
+ ### 方法二:使用 npm link 本地連結
37
+
38
+ 適合開發階段快速測試。
39
+
40
+ ```bash
41
+ # 在套件目錄
42
+ npm run build
43
+ npm link
44
+
45
+ # 在測試專案目錄
46
+ npm link react-native-gradient-mask
47
+ ```
48
+
49
+ ### 方法三:發佈 Beta 版本到 npm
50
+
51
+ 當需要讓其他人測試時使用。
52
+
53
+ ```bash
54
+ # 1. 建置
55
+ npm run build
56
+
57
+ # 2. 更新版本號為 beta
58
+ npm version prerelease --preid=beta
59
+ # 例如:0.1.0 → 0.1.1-beta.0
60
+
61
+ # 3. 發佈到 npm(使用 beta tag)
62
+ npm publish --tag beta
63
+
64
+ # 4. 其他人安裝 beta 版
65
+ npm install react-native-gradient-mask@beta
66
+ ```
67
+
68
+ ### 方法四:使用 GitHub 作為 npm 來源
69
+
70
+ 直接從 GitHub 分支安裝,適合內部測試。
71
+
72
+ ```bash
73
+ # 從特定分支安裝
74
+ npm install CS6/react-native-gradient-mask#feat/add-mask
75
+
76
+ # 或使用完整 URL
77
+ npm install git+https://github.com/CS6/react-native-gradient-mask.git#feat/add-mask
78
+ ```
79
+
80
+ ---
81
+
82
+ ## 正式發佈流程
83
+
84
+ ### 準備工作
85
+
86
+ 1. **確保在 main 分支**
87
+ ```bash
88
+ git checkout main
89
+ git pull origin main
90
+ ```
91
+
92
+ 2. **合併功能分支**
93
+ ```bash
94
+ git merge feat/add-mask
95
+ ```
96
+
97
+ 3. **確認程式碼品質**
98
+ ```bash
99
+ npm run lint
100
+ npm run test
101
+ npm run build
102
+ ```
103
+
104
+ 4. **確認 .npmignore 排除不需要的檔案**
105
+ ```bash
106
+ npm pack --dry-run
107
+ ```
108
+
109
+ ### 發佈步驟
110
+
111
+ ```bash
112
+ # 1. 更新版本號
113
+ npm version patch # 0.1.0 → 0.1.1(修復)
114
+ npm version minor # 0.1.0 → 0.2.0(新功能)
115
+ npm version major # 0.1.0 → 1.0.0(重大變更)
116
+
117
+ # 2. 推送到 GitHub(包含 tag)
118
+ git push origin main --tags
119
+
120
+ # 3. 發佈到 npm
121
+ npm publish
122
+
123
+ # 4. 在 GitHub 建立 Release
124
+ gh release create v0.1.1 --generate-notes
125
+ ```
126
+
127
+ ---
128
+
129
+ ## 發佈前檢查清單
130
+
131
+ - [ ] 程式碼已建置 (`npm run build`)
132
+ - [ ] 測試通過 (`npm run test`)
133
+ - [ ] Lint 檢查通過 (`npm run lint`)
134
+ - [ ] README.md 已更新
135
+ - [ ] package.json 版本號正確
136
+ - [ ] CHANGELOG.md 已更新(如有)
137
+ - [ ] 所有相依套件版本正確
138
+ - [ ] .npmignore 排除不必要檔案
139
+ - [ ] 在測試專案中驗證安裝
140
+
141
+ ---
142
+
143
+ ## 常用指令速查
144
+
145
+ ```bash
146
+ # 檢視將要發佈的檔案
147
+ npm pack --dry-run
148
+
149
+ # 檢視目前版本
150
+ npm version
151
+
152
+ # 檢視 npm 上的版本
153
+ npm view react-native-gradient-mask versions
154
+
155
+ # 撤銷發佈(24小時內)
156
+ npm unpublish react-native-gradient-mask@0.1.0
157
+
158
+ # 廢棄版本(不撤銷,但標記為不建議使用)
159
+ npm deprecate react-native-gradient-mask@0.1.0 "此版本有問題,請升級"
160
+ ```
161
+
162
+ ---
163
+
164
+ ## 版本號規則(Semantic Versioning)
165
+
166
+ | 變更類型 | 版本號變更 | 範例 |
167
+ |----------|-----------|------|
168
+ | 修復 Bug | PATCH | 0.1.0 → 0.1.1 |
169
+ | 新增功能(向下相容) | MINOR | 0.1.0 → 0.2.0 |
170
+ | 重大變更(不向下相容) | MAJOR | 0.1.0 → 1.0.0 |
171
+ | 測試版 | PRERELEASE | 0.1.0 → 0.1.1-beta.0 |
package/README.md ADDED
@@ -0,0 +1,360 @@
1
+ # react-native-gradient-mask
2
+
3
+ React Native 原生漸層遮罩元件,支援 Reanimated 動畫。適用於建立淡入淡出效果、列表遮罩等視覺效果。
4
+
5
+ ## 特色
6
+
7
+ - **跨平台支援**:iOS、Android、Web 三平台完整支援
8
+ - **原生效能**:iOS 使用 `CAGradientLayer`,Android 使用 `Bitmap` + `PorterDuff`,Web 使用 CSS `mask-image`
9
+ - **支援 Reanimated**:透過 `AnimatedGradientMaskView` 實現流暢的遮罩動畫
10
+ - **彈性設定**:自訂顏色、位置、方向與遮罩強度
11
+ - **TypeScript 支援**:完整的型別定義
12
+
13
+ ## 安裝
14
+
15
+ ```bash
16
+ npm install react-native-gradient-mask
17
+ # 或
18
+ yarn add react-native-gradient-mask
19
+ ```
20
+
21
+ ### 前置需求
22
+
23
+ - Expo SDK 50+
24
+ - React Native 0.73+
25
+ - react-native-reanimated >= 3.0.0(如需使用 AnimatedGradientMaskView)
26
+
27
+ ### iOS 設定
28
+
29
+ ```bash
30
+ cd ios && pod install
31
+ ```
32
+
33
+ ### Android 設定
34
+
35
+ 無需額外設定,自動連結。
36
+
37
+ ---
38
+
39
+ ## API 參考
40
+
41
+ ### 匯出項目
42
+
43
+ | 名稱 | 類型 | 說明 |
44
+ |------|------|------|
45
+ | `GradientMaskView` | Component | 基礎漸層遮罩元件 |
46
+ | `AnimatedGradientMaskView` | Component | 支援 Reanimated 動畫的漸層遮罩元件 |
47
+ | `GradientMaskViewProps` | Type | GradientMaskView 的 Props 型別定義 |
48
+ | `AnimatedGradientMaskViewProps` | Type | AnimatedGradientMaskView 的 Props 型別定義 |
49
+
50
+ ### GradientMaskView Props
51
+
52
+ | 屬性 | 型別 | 必填 | 預設值 | 說明 |
53
+ |------|------|:----:|--------|------|
54
+ | `colors` | `(number \| null)[]` | ✅ | - | 漸層顏色陣列,需使用 `processColor()` 處理 |
55
+ | `locations` | `number[]` | ✅ | - | 每個顏色的位置 (0-1) |
56
+ | `direction` | `'top' \| 'bottom' \| 'left' \| 'right'` | | `'top'` | 漸層方向 |
57
+ | `maskOpacity` | `number` | | `1` | 遮罩效果強度 (0-1) |
58
+ | `style` | `StyleProp<ViewStyle>` | | - | 元件樣式 |
59
+ | `children` | `React.ReactNode` | | - | 子元件 |
60
+
61
+ ### AnimatedGradientMaskView Props
62
+
63
+ | 屬性 | 型別 | 必填 | 預設值 | 說明 |
64
+ |------|------|:----:|--------|------|
65
+ | `colors` | `(number \| null)[]` | ✅ | - | 同 GradientMaskView |
66
+ | `locations` | `number[]` | ✅ | - | 同 GradientMaskView |
67
+ | `direction` | `'top' \| 'bottom' \| 'left' \| 'right'` | | `'top'` | 同 GradientMaskView |
68
+ | `maskOpacity` | `SharedValue<number>` | ✅ | - | Reanimated SharedValue,用於動畫控制 |
69
+ | `style` | `StyleProp<ViewStyle>` | | - | 元件樣式 |
70
+ | `children` | `React.ReactNode` | | - | 子元件 |
71
+
72
+ ### 方向說明
73
+
74
+ | 值 | 效果 |
75
+ |------|------|
76
+ | `'top'` | 頂部透明,底部不透明(預設) |
77
+ | `'bottom'` | 底部透明,頂部不透明 |
78
+ | `'left'` | 左側透明,右側不透明 |
79
+ | `'right'` | 右側透明,左側不透明 |
80
+
81
+ ### 平台支援
82
+
83
+ | 平台 | 支援狀態 | 說明 |
84
+ |------|:--------:|------|
85
+ | iOS | ✅ | 使用 CAGradientLayer 原生實作 |
86
+ | Android | ✅ | 使用 Bitmap + LinearGradient 實作 |
87
+ | Web | ✅ | 使用 CSS mask-image + linear-gradient 實作 |
88
+
89
+ ---
90
+
91
+ ## 使用範例
92
+
93
+ ### 基本用法
94
+
95
+ ```tsx
96
+ import { processColor } from 'react-native';
97
+ import { GradientMaskView } from 'react-native-gradient-mask';
98
+
99
+ // 定義漸層顏色(從透明到不透明)
100
+ const colors = [
101
+ 'rgba(0, 0, 0, 0)', // 完全透明
102
+ 'rgba(0, 0, 0, 0.5)', // 半透明
103
+ 'rgba(0, 0, 0, 1)', // 完全不透明
104
+ ];
105
+
106
+ // 使用 processColor 處理顏色
107
+ const processedColors = colors.map(c => processColor(c));
108
+
109
+ // 定義每個顏色的位置
110
+ const locations = [0, 0.3, 1];
111
+
112
+ function MyComponent() {
113
+ return (
114
+ <GradientMaskView
115
+ colors={processedColors}
116
+ locations={locations}
117
+ direction="top"
118
+ maskOpacity={1}
119
+ style={{ flex: 1 }}
120
+ >
121
+ {/* 你的內容 */}
122
+ <ScrollView>
123
+ <Text>這裡的內容會套用漸層遮罩效果</Text>
124
+ </ScrollView>
125
+ </GradientMaskView>
126
+ );
127
+ }
128
+ ```
129
+
130
+ ### 搭配 Reanimated 動畫
131
+
132
+ ```tsx
133
+ import { processColor } from 'react-native';
134
+ import { AnimatedGradientMaskView } from 'react-native-gradient-mask';
135
+ import {
136
+ useSharedValue,
137
+ withTiming,
138
+ Easing,
139
+ } from 'react-native-reanimated';
140
+
141
+ function AnimatedMaskExample() {
142
+ // 建立動畫 SharedValue
143
+ const maskOpacity = useSharedValue(0);
144
+
145
+ const colors = [
146
+ 'rgba(0, 0, 0, 0)',
147
+ 'rgba(0, 0, 0, 1)',
148
+ ].map(c => processColor(c));
149
+
150
+ const locations = [0, 1];
151
+
152
+ // 顯示遮罩效果
153
+ const showMask = () => {
154
+ maskOpacity.value = withTiming(1, {
155
+ duration: 600,
156
+ easing: Easing.in(Easing.quad),
157
+ });
158
+ };
159
+
160
+ // 隱藏遮罩效果
161
+ const hideMask = () => {
162
+ maskOpacity.value = withTiming(0, {
163
+ duration: 400,
164
+ easing: Easing.out(Easing.quad),
165
+ });
166
+ };
167
+
168
+ return (
169
+ <AnimatedGradientMaskView
170
+ colors={colors}
171
+ locations={locations}
172
+ direction="top"
173
+ maskOpacity={maskOpacity}
174
+ style={{ flex: 1 }}
175
+ >
176
+ <YourContent />
177
+ </AnimatedGradientMaskView>
178
+ );
179
+ }
180
+ ```
181
+
182
+ ### 實際應用:聊天列表淡出效果
183
+
184
+ ```tsx
185
+ import { useMemo, useCallback, useRef } from 'react';
186
+ import { processColor, NativeSyntheticEvent, NativeScrollEvent } from 'react-native';
187
+ import { FlashList } from '@shopify/flash-list';
188
+ import { AnimatedGradientMaskView } from 'react-native-gradient-mask';
189
+ import {
190
+ useSharedValue,
191
+ withTiming,
192
+ cancelAnimation,
193
+ Easing,
194
+ } from 'react-native-reanimated';
195
+
196
+ function ChatListWithMask({ messages }) {
197
+ const maskOpacity = useSharedValue(0);
198
+ const isAtBottomRef = useRef(false);
199
+
200
+ // 定義漸層顏色
201
+ const maskColors = useMemo(() => {
202
+ return [
203
+ 'rgba(0,0,0,0)',
204
+ 'rgba(0,0,0,0)',
205
+ 'rgba(0,0,0,0.2)',
206
+ 'rgba(0,0,0,0.6)',
207
+ 'rgba(0,0,0,0.9)',
208
+ 'rgba(0,0,0,1)',
209
+ ].map(c => processColor(c));
210
+ }, []);
211
+
212
+ const maskLocations = useMemo(() => [0, 0.42, 0.45, 0.48, 0.5, 1], []);
213
+
214
+ // 偵測滾動位置,動態控制遮罩
215
+ const handleScroll = useCallback((e: NativeSyntheticEvent<NativeScrollEvent>) => {
216
+ const { contentOffset, layoutMeasurement, contentSize } = e.nativeEvent;
217
+ const distanceFromBottom = contentSize.height - contentOffset.y - layoutMeasurement.height;
218
+
219
+ const isAtBottom = distanceFromBottom <= 30;
220
+
221
+ if (isAtBottom !== isAtBottomRef.current) {
222
+ isAtBottomRef.current = isAtBottom;
223
+ cancelAnimation(maskOpacity);
224
+
225
+ if (isAtBottom) {
226
+ // 滾動到底部時顯示遮罩
227
+ maskOpacity.value = withTiming(1, {
228
+ duration: 600,
229
+ easing: Easing.in(Easing.quad),
230
+ });
231
+ } else {
232
+ // 離開底部時隱藏遮罩
233
+ maskOpacity.value = withTiming(0, {
234
+ duration: 400,
235
+ easing: Easing.out(Easing.quad),
236
+ });
237
+ }
238
+ }
239
+ }, []);
240
+
241
+ return (
242
+ <AnimatedGradientMaskView
243
+ colors={maskColors}
244
+ locations={maskLocations}
245
+ direction="top"
246
+ maskOpacity={maskOpacity}
247
+ style={{ flex: 1 }}
248
+ >
249
+ <FlashList
250
+ data={messages}
251
+ renderItem={({ item }) => <MessageItem item={item} />}
252
+ onScroll={handleScroll}
253
+ scrollEventThrottle={16}
254
+ />
255
+ </AnimatedGradientMaskView>
256
+ );
257
+ }
258
+ ```
259
+
260
+ ### 不同方向的遮罩
261
+
262
+ ```tsx
263
+ // 頂部淡出(預設)
264
+ <GradientMaskView direction="top" {...props}>
265
+ {children}
266
+ </GradientMaskView>
267
+
268
+ // 底部淡出
269
+ <GradientMaskView direction="bottom" {...props}>
270
+ {children}
271
+ </GradientMaskView>
272
+
273
+ // 左側淡出
274
+ <GradientMaskView direction="left" {...props}>
275
+ {children}
276
+ </GradientMaskView>
277
+
278
+ // 右側淡出
279
+ <GradientMaskView direction="right" {...props}>
280
+ {children}
281
+ </GradientMaskView>
282
+ ```
283
+
284
+ ### 控制遮罩強度
285
+
286
+ ```tsx
287
+ // maskOpacity = 0:無遮罩效果,內容完全可見
288
+ <GradientMaskView maskOpacity={0} {...props}>
289
+ {children}
290
+ </GradientMaskView>
291
+
292
+ // maskOpacity = 0.5:半透明遮罩效果
293
+ <GradientMaskView maskOpacity={0.5} {...props}>
294
+ {children}
295
+ </GradientMaskView>
296
+
297
+ // maskOpacity = 1:完整遮罩效果(預設)
298
+ <GradientMaskView maskOpacity={1} {...props}>
299
+ {children}
300
+ </GradientMaskView>
301
+ ```
302
+
303
+ ---
304
+
305
+ ## 進階技巧
306
+
307
+ ### 顏色處理
308
+
309
+ 顏色必須使用 React Native 的 `processColor()` 函式處理:
310
+
311
+ ```tsx
312
+ import { processColor } from 'react-native';
313
+
314
+ // ✅ 正確做法
315
+ const colors = [
316
+ processColor('rgba(0, 0, 0, 0)'),
317
+ processColor('rgba(0, 0, 0, 1)'),
318
+ ];
319
+
320
+ // ❌ 錯誤做法(不會正常運作)
321
+ const colors = [
322
+ 'rgba(0, 0, 0, 0)',
323
+ 'rgba(0, 0, 0, 1)',
324
+ ];
325
+ ```
326
+
327
+ ### 使用 useMemo 優化效能
328
+
329
+ ```tsx
330
+ const maskColors = useMemo(() => {
331
+ return [
332
+ 'rgba(0,0,0,0)',
333
+ 'rgba(0,0,0,1)',
334
+ ].map(c => processColor(c));
335
+ }, []); // 只計算一次
336
+
337
+ const maskLocations = useMemo(() => [0, 1], []);
338
+ ```
339
+
340
+ ### 避免閃爍
341
+
342
+ 使用 `AnimatedGradientMaskView` 搭配 `cancelAnimation` 可以避免快速切換時的閃爍問題:
343
+
344
+ ```tsx
345
+ import { cancelAnimation } from 'react-native-reanimated';
346
+
347
+ // 在改變動畫前先取消之前的動畫
348
+ cancelAnimation(maskOpacity);
349
+ maskOpacity.value = withTiming(newValue, { duration: 300 });
350
+ ```
351
+
352
+ ---
353
+
354
+ ## 授權
355
+
356
+ MIT License
357
+
358
+ ## 作者
359
+
360
+ DaYuan Lin (CS6)
@@ -0,0 +1,43 @@
1
+ apply plugin: 'com.android.library'
2
+
3
+ group = 'expo.modules.gradientmask'
4
+ version = '0.1.0'
5
+
6
+ def expoModulesCorePlugin = new File(project(":expo-modules-core").projectDir.absolutePath, "ExpoModulesCorePlugin.gradle")
7
+ apply from: expoModulesCorePlugin
8
+ applyKotlinExpoModulesCorePlugin()
9
+ useCoreDependencies()
10
+ useExpoPublishing()
11
+
12
+ // If you want to use the managed Android SDK versions from expo-modules-core, set this to true.
13
+ // The Android SDK versions will be bumped from time to time in SDK releases and may introduce breaking changes in your module code.
14
+ // Most of the time, you may like to manage the Android SDK versions yourself.
15
+ def useManagedAndroidSdkVersions = false
16
+ if (useManagedAndroidSdkVersions) {
17
+ useDefaultAndroidSdkVersions()
18
+ } else {
19
+ buildscript {
20
+ // Simple helper that allows the root project to override versions declared by this library.
21
+ ext.safeExtGet = { prop, fallback ->
22
+ rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
23
+ }
24
+ }
25
+ project.android {
26
+ compileSdkVersion safeExtGet("compileSdkVersion", 36)
27
+ defaultConfig {
28
+ minSdkVersion safeExtGet("minSdkVersion", 24)
29
+ targetSdkVersion safeExtGet("targetSdkVersion", 36)
30
+ }
31
+ }
32
+ }
33
+
34
+ android {
35
+ namespace "expo.modules.gradientmask"
36
+ defaultConfig {
37
+ versionCode 1
38
+ versionName "0.1.0"
39
+ }
40
+ lintOptions {
41
+ abortOnError false
42
+ }
43
+ }
@@ -0,0 +1,2 @@
1
+ <manifest>
2
+ </manifest>
@@ -0,0 +1,33 @@
1
+ package expo.modules.gradientmask
2
+
3
+ import expo.modules.kotlin.modules.Module
4
+ import expo.modules.kotlin.modules.ModuleDefinition
5
+
6
+ class GradientMaskModule : Module() {
7
+ override fun definition() = ModuleDefinition {
8
+ Name("GradientMask")
9
+
10
+ // View definition
11
+ View(GradientMaskView::class) {
12
+ // colors: List of processed colors (from processColor in JS)
13
+ Prop("colors") { view: GradientMaskView, colors: List<Int>? ->
14
+ view.setColors(colors)
15
+ }
16
+
17
+ // locations: Array of floats (0-1) for gradient stops
18
+ Prop("locations") { view: GradientMaskView, locations: List<Double>? ->
19
+ view.setLocations(locations)
20
+ }
21
+
22
+ // direction: "top" | "bottom" | "left" | "right"
23
+ Prop("direction") { view: GradientMaskView, direction: String? ->
24
+ view.setDirection(direction ?: "top")
25
+ }
26
+
27
+ // maskOpacity: 0 = no mask effect, 1 = full gradient mask
28
+ Prop("maskOpacity") { view: GradientMaskView, opacity: Double? ->
29
+ view.setMaskOpacity(opacity ?: 1.0)
30
+ }
31
+ }
32
+ }
33
+ }