expo-mesh-gradient 0.3.4 → 0.4.0-canary-20250611-f0afe80

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 (40) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/android/build.gradle +36 -0
  3. package/android/src/main/AndroidManifest.xml +3 -0
  4. package/android/src/main/java/expo/modules/meshgradient/CubicInterpolation.kt +16 -0
  5. package/android/src/main/java/expo/modules/meshgradient/MeshGradientModule.kt +12 -0
  6. package/android/src/main/java/expo/modules/meshgradient/MeshGradientPointData.kt +229 -0
  7. package/android/src/main/java/expo/modules/meshgradient/MeshGradientView.kt +105 -0
  8. package/build/MeshGradient.types.d.ts +13 -2
  9. package/build/MeshGradient.types.d.ts.map +1 -1
  10. package/build/MeshGradientView.d.ts +2 -2
  11. package/build/MeshGradientView.d.ts.map +1 -1
  12. package/expo-module.config.json +11 -1
  13. package/local-maven-repo/host/exp/exponent/expo.modules.meshgradient/0.4.0-canary-20250611-f0afe80/expo.modules.meshgradient-0.4.0-canary-20250611-f0afe80-sources.jar +0 -0
  14. package/local-maven-repo/host/exp/exponent/expo.modules.meshgradient/0.4.0-canary-20250611-f0afe80/expo.modules.meshgradient-0.4.0-canary-20250611-f0afe80-sources.jar.md5 +1 -0
  15. package/local-maven-repo/host/exp/exponent/expo.modules.meshgradient/0.4.0-canary-20250611-f0afe80/expo.modules.meshgradient-0.4.0-canary-20250611-f0afe80-sources.jar.sha1 +1 -0
  16. package/local-maven-repo/host/exp/exponent/expo.modules.meshgradient/0.4.0-canary-20250611-f0afe80/expo.modules.meshgradient-0.4.0-canary-20250611-f0afe80-sources.jar.sha256 +1 -0
  17. package/local-maven-repo/host/exp/exponent/expo.modules.meshgradient/0.4.0-canary-20250611-f0afe80/expo.modules.meshgradient-0.4.0-canary-20250611-f0afe80-sources.jar.sha512 +1 -0
  18. package/local-maven-repo/host/exp/exponent/expo.modules.meshgradient/0.4.0-canary-20250611-f0afe80/expo.modules.meshgradient-0.4.0-canary-20250611-f0afe80.aar +0 -0
  19. package/local-maven-repo/host/exp/exponent/expo.modules.meshgradient/0.4.0-canary-20250611-f0afe80/expo.modules.meshgradient-0.4.0-canary-20250611-f0afe80.aar.md5 +1 -0
  20. package/local-maven-repo/host/exp/exponent/expo.modules.meshgradient/0.4.0-canary-20250611-f0afe80/expo.modules.meshgradient-0.4.0-canary-20250611-f0afe80.aar.sha1 +1 -0
  21. package/local-maven-repo/host/exp/exponent/expo.modules.meshgradient/0.4.0-canary-20250611-f0afe80/expo.modules.meshgradient-0.4.0-canary-20250611-f0afe80.aar.sha256 +1 -0
  22. package/local-maven-repo/host/exp/exponent/expo.modules.meshgradient/0.4.0-canary-20250611-f0afe80/expo.modules.meshgradient-0.4.0-canary-20250611-f0afe80.aar.sha512 +1 -0
  23. package/local-maven-repo/host/exp/exponent/expo.modules.meshgradient/0.4.0-canary-20250611-f0afe80/expo.modules.meshgradient-0.4.0-canary-20250611-f0afe80.module +101 -0
  24. package/local-maven-repo/host/exp/exponent/expo.modules.meshgradient/0.4.0-canary-20250611-f0afe80/expo.modules.meshgradient-0.4.0-canary-20250611-f0afe80.module.md5 +1 -0
  25. package/local-maven-repo/host/exp/exponent/expo.modules.meshgradient/0.4.0-canary-20250611-f0afe80/expo.modules.meshgradient-0.4.0-canary-20250611-f0afe80.module.sha1 +1 -0
  26. package/local-maven-repo/host/exp/exponent/expo.modules.meshgradient/0.4.0-canary-20250611-f0afe80/expo.modules.meshgradient-0.4.0-canary-20250611-f0afe80.module.sha256 +1 -0
  27. package/local-maven-repo/host/exp/exponent/expo.modules.meshgradient/0.4.0-canary-20250611-f0afe80/expo.modules.meshgradient-0.4.0-canary-20250611-f0afe80.module.sha512 +1 -0
  28. package/local-maven-repo/host/exp/exponent/expo.modules.meshgradient/0.4.0-canary-20250611-f0afe80/expo.modules.meshgradient-0.4.0-canary-20250611-f0afe80.pom +47 -0
  29. package/local-maven-repo/host/exp/exponent/expo.modules.meshgradient/0.4.0-canary-20250611-f0afe80/expo.modules.meshgradient-0.4.0-canary-20250611-f0afe80.pom.md5 +1 -0
  30. package/local-maven-repo/host/exp/exponent/expo.modules.meshgradient/0.4.0-canary-20250611-f0afe80/expo.modules.meshgradient-0.4.0-canary-20250611-f0afe80.pom.sha1 +1 -0
  31. package/local-maven-repo/host/exp/exponent/expo.modules.meshgradient/0.4.0-canary-20250611-f0afe80/expo.modules.meshgradient-0.4.0-canary-20250611-f0afe80.pom.sha256 +1 -0
  32. package/local-maven-repo/host/exp/exponent/expo.modules.meshgradient/0.4.0-canary-20250611-f0afe80/expo.modules.meshgradient-0.4.0-canary-20250611-f0afe80.pom.sha512 +1 -0
  33. package/local-maven-repo/host/exp/exponent/expo.modules.meshgradient/maven-metadata.xml +13 -0
  34. package/local-maven-repo/host/exp/exponent/expo.modules.meshgradient/maven-metadata.xml.md5 +1 -0
  35. package/local-maven-repo/host/exp/exponent/expo.modules.meshgradient/maven-metadata.xml.sha1 +1 -0
  36. package/local-maven-repo/host/exp/exponent/expo.modules.meshgradient/maven-metadata.xml.sha256 +1 -0
  37. package/local-maven-repo/host/exp/exponent/expo.modules.meshgradient/maven-metadata.xml.sha512 +1 -0
  38. package/package.json +4 -5
  39. package/src/MeshGradient.types.ts +14 -2
  40. package/src/MeshGradientView.tsx +19 -1
package/CHANGELOG.md CHANGED
@@ -6,6 +6,8 @@
6
6
 
7
7
  ### 🎉 New features
8
8
 
9
+ - [Android] Add mesh gradient on Android. ([#37056](https://github.com/expo/expo/pull/37056) by [@jakex7](https://github.com/jakex7))
10
+
9
11
  ### 🐛 Bug fixes
10
12
 
11
13
  ### 💡 Others
@@ -0,0 +1,36 @@
1
+ buildscript {
2
+
3
+ repositories {
4
+ mavenCentral()
5
+ }
6
+ dependencies {
7
+ classpath("org.jetbrains.kotlin.plugin.compose:org.jetbrains.kotlin.plugin.compose.gradle.plugin:${kotlinVersion}")
8
+ }
9
+
10
+ }
11
+
12
+ apply plugin: 'com.android.library'
13
+ apply plugin: 'expo-module-gradle-plugin'
14
+ apply plugin: 'org.jetbrains.kotlin.plugin.compose'
15
+
16
+ group = 'host.exp.exponent'
17
+ version = '0.4.0-canary-20250611-f0afe80'
18
+
19
+ android {
20
+ namespace "expo.modules.meshgradient"
21
+ defaultConfig {
22
+ versionCode 1
23
+ versionName "0.4.0-canary-20250611-f0afe80"
24
+ }
25
+ buildFeatures {
26
+ compose true
27
+ }
28
+ lintOptions {
29
+ abortOnError false
30
+ }
31
+ }
32
+
33
+ dependencies {
34
+ implementation 'androidx.compose.foundation:foundation-android:1.7.6'
35
+ implementation 'androidx.compose.ui:ui-android:1.7.6'
36
+ }
@@ -0,0 +1,3 @@
1
+ <manifest>
2
+
3
+ </manifest>
@@ -0,0 +1,16 @@
1
+ package expo.modules.meshgradient
2
+
3
+ import androidx.compose.ui.graphics.Color
4
+ import kotlin.math.pow
5
+
6
+ fun cubic(a: Color, b: Color, t: Float): Color {
7
+ // Smoothstep Cubic Polynomial function
8
+ val easedT = 3 * t.pow(2) - 2 * t.pow(3)
9
+
10
+ return Color(
11
+ red = a.red * (1 - easedT) + b.red * easedT,
12
+ green = a.green * (1 - easedT) + b.green * easedT,
13
+ blue = a.blue * (1 - easedT) + b.blue * easedT,
14
+ alpha = a.alpha * (1 - easedT) + b.alpha * easedT
15
+ )
16
+ }
@@ -0,0 +1,12 @@
1
+ package expo.modules.meshgradient
2
+
3
+ import expo.modules.kotlin.modules.Module
4
+ import expo.modules.kotlin.modules.ModuleDefinition
5
+
6
+ class MeshGradientModule : Module() {
7
+ override fun definition() = ModuleDefinition {
8
+ Name("ExpoMeshGradient")
9
+
10
+ View(MeshGradientView::class)
11
+ }
12
+ }
@@ -0,0 +1,229 @@
1
+ package expo.modules.meshgradient
2
+
3
+ import androidx.compose.ui.geometry.Offset
4
+ import androidx.compose.ui.graphics.Color
5
+ import androidx.compose.ui.graphics.Path
6
+ import androidx.compose.ui.graphics.PathMeasure
7
+ import androidx.compose.ui.graphics.lerp
8
+
9
+ // Based on https://gist.github.com/sinasamaki/05725557c945c5329fdba4a3494aaecb
10
+ class PointData(
11
+ private val points: List<List<Pair<Offset, Color>>>,
12
+ private val stepsX: Int,
13
+ private val stepsY: Int,
14
+ private val smoothsColors: Boolean
15
+ ) {
16
+ val offsets: MutableList<Offset>
17
+ val colors: MutableList<Color>
18
+ val indices: List<Int>
19
+ private val xLength: Int = (points[0].size * stepsX) - (stepsX - 1)
20
+ private val yLength: Int = (points.size * stepsY) - (stepsY - 1)
21
+ private val measure = PathMeasure()
22
+
23
+ private val indicesBlocks: List<IndicesBlock>
24
+
25
+ init {
26
+ offsets = buildList {
27
+ repeat(xLength * yLength) {
28
+ add(Offset(0f, 0f))
29
+ }
30
+ }.toMutableList()
31
+
32
+ colors = buildList {
33
+ repeat(xLength * yLength) {
34
+ add(Color.Transparent)
35
+ }
36
+ }.toMutableList()
37
+
38
+ indicesBlocks =
39
+ buildList {
40
+ for (y in 0..yLength - 2) {
41
+ for (x in 0..xLength - 2) {
42
+ val a = (y * xLength) + x
43
+ val b = a + 1
44
+ val c = ((y + 1) * xLength) + x
45
+ val d = c + 1
46
+ add(
47
+ IndicesBlock(
48
+ indices = buildList {
49
+ add(a)
50
+ add(c)
51
+ add(d)
52
+
53
+ add(a)
54
+ add(b)
55
+ add(d)
56
+ },
57
+ x = x, y = y
58
+ )
59
+ )
60
+ }
61
+ }
62
+ }
63
+
64
+ indices = indicesBlocks.flatMap { it.indices }
65
+ generateInterpolatedOffsets()
66
+ }
67
+
68
+ private fun generateInterpolatedOffsets() {
69
+ for (y in 0..points.lastIndex) {
70
+ for (x in 0..points[y].lastIndex) {
71
+ this[x * stepsX, y * stepsY] = points[y][x].first
72
+ this[x * stepsX, y * stepsY] = points[y][x].second
73
+ if (x != points[y].lastIndex) {
74
+ val path = cubicPathX(
75
+ point1 = points[y][x].first,
76
+ point2 = points[y][x + 1].first,
77
+ when (x) {
78
+ 0 -> 0
79
+ points[y].lastIndex - 1 -> 2
80
+ else -> 1
81
+ }
82
+ )
83
+ measure.setPath(path, false)
84
+ for (i in 1..<stepsX) {
85
+ measure.getPosition(i / stepsX.toFloat() * measure.length).let {
86
+ this[(x * stepsX) + i, (y * stepsY)] = Offset(it.x, it.y)
87
+ this[(x * stepsX) + i, (y * stepsY)] =
88
+ interpolateColor(
89
+ points[y][x].second,
90
+ points[y][x + 1].second,
91
+ i / stepsX.toFloat()
92
+ )
93
+ }
94
+ }
95
+ }
96
+ }
97
+ }
98
+
99
+ for (y in 0..<points.lastIndex) {
100
+ for (x in 0..<this.xLength) {
101
+ val path = cubicPathY(
102
+ point1 = this[x, y * stepsY].let { Offset(it.x, it.y) },
103
+ point2 = this[x, (y + 1) * stepsY].let { Offset(it.x, it.y) },
104
+ when (y) {
105
+ 0 -> 0
106
+ points[y].lastIndex - 1 -> 2
107
+ else -> 1
108
+ }
109
+ )
110
+ measure.setPath(path, false)
111
+ for (i in (1..<stepsY)) {
112
+ val point3 = measure.getPosition(i / stepsY.toFloat() * measure.length).let {
113
+ Offset(it.x, it.y)
114
+ }
115
+ this[x, ((y * stepsY) + i)] = point3
116
+ this[x, ((y * stepsY) + i)] = interpolateColor(
117
+ this.getColor(x, y * stepsY),
118
+ this.getColor(x, (y + 1) * stepsY),
119
+ i / stepsY.toFloat()
120
+ )
121
+ }
122
+ }
123
+ }
124
+ }
125
+
126
+ data class IndicesBlock(val indices: List<Int>, val x: Int, val y: Int)
127
+
128
+ operator fun get(x: Int, y: Int): Offset {
129
+ val index = (y * xLength) + x
130
+ return offsets[index]
131
+ }
132
+
133
+ private fun getColor(x: Int, y: Int): Color {
134
+ val index = (y * xLength) + x
135
+ return colors[index]
136
+ }
137
+
138
+ private operator fun set(x: Int, y: Int, offset: Offset) {
139
+ val index = (y * xLength) + x
140
+ offsets[index] = Offset(offset.x, offset.y)
141
+ }
142
+
143
+ private operator fun set(x: Int, y: Int, color: Color) {
144
+ val index = (y * xLength) + x
145
+ colors[index] = color
146
+ }
147
+
148
+ private fun interpolateColor(
149
+ color1: Color,
150
+ color2: Color,
151
+ fraction: Float
152
+ ): Color {
153
+ return if (smoothsColors) {
154
+ cubic(color1, color2, fraction)
155
+ } else {
156
+ lerp(color1, color2, fraction)
157
+ }
158
+ }
159
+ }
160
+
161
+ private fun cubicPathX(point1: Offset, point2: Offset, position: Int): Path {
162
+ val path = Path().apply {
163
+ moveTo(point1.x, point1.y)
164
+ val delta = (point2.x - point1.x) * .5f
165
+ when (position) {
166
+ 0 -> cubicTo(
167
+ point1.x,
168
+ point1.y,
169
+ point2.x - delta,
170
+ point2.y,
171
+ point2.x,
172
+ point2.y
173
+ )
174
+ 2 -> cubicTo(
175
+ point1.x + delta,
176
+ point1.y,
177
+ point2.x,
178
+ point2.y,
179
+ point2.x,
180
+ point2.y
181
+ )
182
+ else -> cubicTo(
183
+ point1.x + delta,
184
+ point1.y,
185
+ point2.x - delta,
186
+ point2.y,
187
+ point2.x,
188
+ point2.y
189
+ )
190
+ }
191
+ lineTo(point2.x, point2.y)
192
+ }
193
+ return path
194
+ }
195
+
196
+ private fun cubicPathY(point1: Offset, point2: Offset, position: Int): Path {
197
+ val path = Path().apply {
198
+ moveTo(point1.x, point1.y)
199
+ val delta = (point2.y - point1.y) * .5f
200
+ when (position) {
201
+ 0 -> cubicTo(
202
+ point1.x,
203
+ point1.y,
204
+ point2.x,
205
+ point2.y - delta,
206
+ point2.x,
207
+ point2.y
208
+ )
209
+ 2 -> cubicTo(
210
+ point1.x,
211
+ point1.y + delta,
212
+ point2.x,
213
+ point2.y,
214
+ point2.x,
215
+ point2.y
216
+ )
217
+ else -> cubicTo(
218
+ point1.x,
219
+ point1.y + delta,
220
+ point2.x,
221
+ point2.y - delta,
222
+ point2.x,
223
+ point2.y
224
+ )
225
+ }
226
+ lineTo(point2.x, point2.y)
227
+ }
228
+ return path
229
+ }
@@ -0,0 +1,105 @@
1
+ package expo.modules.meshgradient
2
+
3
+ import android.annotation.SuppressLint
4
+ import android.content.Context
5
+ import androidx.compose.foundation.Canvas
6
+ import androidx.compose.foundation.layout.fillMaxSize
7
+ import androidx.compose.runtime.Composable
8
+ import expo.modules.kotlin.AppContext
9
+ import expo.modules.kotlin.views.ComposeProps
10
+ import expo.modules.kotlin.views.ExpoComposeView
11
+ import androidx.compose.runtime.MutableState
12
+ import androidx.compose.runtime.State
13
+ import androidx.compose.runtime.derivedStateOf
14
+ import androidx.compose.runtime.mutableIntStateOf
15
+ import androidx.compose.runtime.mutableStateOf
16
+ import androidx.compose.runtime.remember
17
+ import androidx.compose.ui.Modifier
18
+ import androidx.compose.ui.geometry.Offset
19
+ import androidx.compose.ui.graphics.BlendMode
20
+ import androidx.compose.ui.graphics.Canvas
21
+ import androidx.compose.ui.graphics.Color
22
+ import androidx.compose.ui.graphics.Paint
23
+ import androidx.compose.ui.graphics.VertexMode
24
+ import androidx.compose.ui.graphics.Vertices
25
+ import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
26
+ import androidx.compose.ui.graphics.drawscope.scale
27
+ import expo.modules.kotlin.records.Field
28
+ import expo.modules.kotlin.records.Record
29
+
30
+ data class Resolution(
31
+ @Field
32
+ val x: Int = 8,
33
+
34
+ @Field
35
+ val y: Int = 8
36
+ ) : Record
37
+
38
+ data class MeshGradientViewProps(
39
+ val columns: MutableState<Int> = mutableIntStateOf(0),
40
+ val rows: MutableState<Int> = mutableIntStateOf(0),
41
+ val points: MutableState<List<Pair<Float, Float>>> = mutableStateOf(listOf()),
42
+ val colors: MutableState<List<Int>> = mutableStateOf(listOf()),
43
+ val resolution: MutableState<Resolution> = mutableStateOf(Resolution()),
44
+ val smoothsColors: MutableState<Boolean> = mutableStateOf(true)
45
+ ) : ComposeProps
46
+
47
+ @SuppressLint("ViewConstructor")
48
+ class MeshGradientView(context: Context, appContext: AppContext) : ExpoComposeView<MeshGradientViewProps>(context, appContext, withHostingView = true) {
49
+ override val props = MeshGradientViewProps()
50
+ private val paint = Paint()
51
+
52
+ @Composable
53
+ override fun Content() {
54
+ val pointData = pointsFromProps()
55
+
56
+ Canvas(modifier = Modifier.fillMaxSize()) {
57
+ drawIntoCanvas { canvas: Canvas ->
58
+ scale(
59
+ scaleX = size.width,
60
+ scaleY = size.height,
61
+ pivot = Offset.Zero
62
+ ) {
63
+ canvas.drawVertices(
64
+ vertices = Vertices(
65
+ vertexMode = VertexMode.Triangles,
66
+ positions = pointData.value.offsets,
67
+ textureCoordinates = pointData.value.offsets,
68
+ colors = pointData.value.colors,
69
+ indices = pointData.value.indices
70
+ ),
71
+ blendMode = BlendMode.Dst,
72
+ paint = paint
73
+ )
74
+ }
75
+ }
76
+ }
77
+ }
78
+
79
+ @Composable
80
+ private fun pointsFromProps(): State<PointData> =
81
+ remember {
82
+ derivedStateOf {
83
+ val points = buildList {
84
+ val numRows = props.rows.value
85
+ val numCols = props.columns.value
86
+ val colors = props.colors.value
87
+ val definedPoints = props.points.value
88
+ for (row in 0 until numRows) {
89
+ val rowList = buildList {
90
+ for (col in 0 until numCols) {
91
+ val index = row * numCols + col
92
+ if (index < definedPoints.size && index < colors.size) {
93
+ val (x, y) = definedPoints[index]
94
+ val color = Color(colors[index])
95
+ add(Pair(Offset(x, y), color))
96
+ }
97
+ }
98
+ }
99
+ add(rowList)
100
+ }
101
+ }
102
+ return@derivedStateOf PointData(points, props.resolution.value.x, props.resolution.value.y, props.smoothsColors.value)
103
+ }
104
+ }
105
+ }
@@ -1,4 +1,4 @@
1
- import type { ViewProps } from 'react-native';
1
+ import type { ColorValue, ViewProps } from 'react-native';
2
2
  export interface MeshGradientViewProps extends ViewProps {
3
3
  /**
4
4
  * Width of the mesh, i.e. the number of vertices per row.
@@ -19,7 +19,7 @@ export interface MeshGradientViewProps extends ViewProps {
19
19
  * An array of colors. Must contain `columns * rows` elements.
20
20
  * @default []
21
21
  */
22
- colors?: string[];
22
+ colors?: ColorValue[];
23
23
  /**
24
24
  * Whether cubic (smooth) interpolation should be used for the colors in the mesh
25
25
  * rather than only for the shape of the mesh.
@@ -29,13 +29,24 @@ export interface MeshGradientViewProps extends ViewProps {
29
29
  /**
30
30
  * Whether to ignore safe areas when positioning the view.
31
31
  * @default true
32
+ * @platform ios
32
33
  */
33
34
  ignoresSafeArea?: boolean;
34
35
  /**
35
36
  * Masks the gradient using the alpha channel of the given children views.
36
37
  * > **Note**: When this option is enabled, all user interactions (gestures) on children views are ignored.
37
38
  * @default false
39
+ * @platform ios
38
40
  */
39
41
  mask?: boolean;
42
+ /**
43
+ * Specifies how many points to sample on the path between points.
44
+ * @default { x: 1, y: 1 }
45
+ * @platform android
46
+ */
47
+ resolution?: {
48
+ x?: number;
49
+ y?: number;
50
+ };
40
51
  }
41
52
  //# sourceMappingURL=MeshGradient.types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"MeshGradient.types.d.ts","sourceRoot":"","sources":["../src/MeshGradient.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,WAAW,qBAAsB,SAAQ,SAAS;IACtD;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC;IAEpB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAElB;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B;;;;OAIG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB"}
1
+ {"version":3,"file":"MeshGradient.types.d.ts","sourceRoot":"","sources":["../src/MeshGradient.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAE1D,MAAM,WAAW,qBAAsB,SAAQ,SAAS;IACtD;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC;IAEpB;;;OAGG;IACH,MAAM,CAAC,EAAE,UAAU,EAAE,CAAC;IAEtB;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;;;OAIG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAE1B;;;;;OAKG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IAEf;;;;OAIG;IACH,UAAU,CAAC,EAAE;QACX,CAAC,CAAC,EAAE,MAAM,CAAC;QACX,CAAC,CAAC,EAAE,MAAM,CAAC;KACZ,CAAC;CACH"}
@@ -1,4 +1,4 @@
1
1
  import { MeshGradientViewProps } from './MeshGradient.types';
2
- declare const _default: import("react").ComponentType<MeshGradientViewProps>;
3
- export default _default;
2
+ declare const MeshGradientView: (props: MeshGradientViewProps) => import("react").JSX.Element;
3
+ export default MeshGradientView;
4
4
  //# sourceMappingURL=MeshGradientView.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"MeshGradientView.d.ts","sourceRoot":"","sources":["../src/MeshGradientView.tsx"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;;AAE7D,wBAA4E"}
1
+ {"version":3,"file":"MeshGradientView.d.ts","sourceRoot":"","sources":["../src/MeshGradientView.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAQ7D,QAAA,MAAM,gBAAgB,GAAI,OAAO,qBAAqB,gCASrD,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
@@ -1,6 +1,16 @@
1
1
  {
2
- "platforms": ["apple"],
2
+ "platforms": ["apple", "android"],
3
+ "coreFeatures": ["swiftui", "compose"],
3
4
  "apple": {
4
5
  "modules": ["MeshGradientModule"]
6
+ },
7
+ "android": {
8
+ "modules": ["expo.modules.meshgradient.MeshGradientModule"],
9
+ "publication": {
10
+ "groupId": "host.exp.exponent",
11
+ "artifactId": "expo.modules.meshgradient",
12
+ "version": "0.4.0-canary-20250611-f0afe80",
13
+ "repository": "local-maven-repo"
14
+ }
5
15
  }
6
16
  }
@@ -0,0 +1 @@
1
+ 8720b775920bbcf29474c187976f588788735c22da798db873d13985aa6197d51ef4e78baab63d1b4874320bfa555cc2af7963fba6bd0fe4ee100328eb78748b
@@ -0,0 +1 @@
1
+ c8e442d46f64599fd9f99013dc027af15316791bf057818c3d718b947f54e3b2ea9de60fe371e37639482266dbc1129708e5c3e8da25d43f22dc435399c45a5a
@@ -0,0 +1,101 @@
1
+ {
2
+ "formatVersion": "1.1",
3
+ "component": {
4
+ "group": "host.exp.exponent",
5
+ "module": "expo.modules.meshgradient",
6
+ "version": "0.4.0-canary-20250611-f0afe80",
7
+ "attributes": {
8
+ "org.gradle.status": "release"
9
+ }
10
+ },
11
+ "createdBy": {
12
+ "gradle": {
13
+ "version": "8.14"
14
+ }
15
+ },
16
+ "variants": [
17
+ {
18
+ "name": "releaseVariantReleaseApiPublication",
19
+ "attributes": {
20
+ "org.gradle.category": "library",
21
+ "org.gradle.dependency.bundling": "external",
22
+ "org.gradle.libraryelements": "aar",
23
+ "org.gradle.usage": "java-api"
24
+ },
25
+ "files": [
26
+ {
27
+ "name": "expo.modules.meshgradient-0.4.0-canary-20250611-f0afe80.aar",
28
+ "url": "expo.modules.meshgradient-0.4.0-canary-20250611-f0afe80.aar",
29
+ "size": 24200,
30
+ "sha512": "c8e442d46f64599fd9f99013dc027af15316791bf057818c3d718b947f54e3b2ea9de60fe371e37639482266dbc1129708e5c3e8da25d43f22dc435399c45a5a",
31
+ "sha256": "82dfcc8c73fec8f861bf879703fd09f31936d0c9dced0b1a89b1ed03810f51d1",
32
+ "sha1": "2ee4f5948cbb7bfd01d50dd8148b7708975dd725",
33
+ "md5": "a0650e7cf68cce59ce1dfb0fbcd96b16"
34
+ }
35
+ ]
36
+ },
37
+ {
38
+ "name": "releaseVariantReleaseRuntimePublication",
39
+ "attributes": {
40
+ "org.gradle.category": "library",
41
+ "org.gradle.dependency.bundling": "external",
42
+ "org.gradle.libraryelements": "aar",
43
+ "org.gradle.usage": "java-runtime"
44
+ },
45
+ "dependencies": [
46
+ {
47
+ "group": "org.jetbrains.kotlin",
48
+ "module": "kotlin-stdlib-jdk7",
49
+ "version": {
50
+ "requires": "2.1.20"
51
+ }
52
+ },
53
+ {
54
+ "group": "androidx.compose.foundation",
55
+ "module": "foundation-android",
56
+ "version": {
57
+ "requires": "1.7.6"
58
+ }
59
+ },
60
+ {
61
+ "group": "androidx.compose.ui",
62
+ "module": "ui-android",
63
+ "version": {
64
+ "requires": "1.7.6"
65
+ }
66
+ }
67
+ ],
68
+ "files": [
69
+ {
70
+ "name": "expo.modules.meshgradient-0.4.0-canary-20250611-f0afe80.aar",
71
+ "url": "expo.modules.meshgradient-0.4.0-canary-20250611-f0afe80.aar",
72
+ "size": 24200,
73
+ "sha512": "c8e442d46f64599fd9f99013dc027af15316791bf057818c3d718b947f54e3b2ea9de60fe371e37639482266dbc1129708e5c3e8da25d43f22dc435399c45a5a",
74
+ "sha256": "82dfcc8c73fec8f861bf879703fd09f31936d0c9dced0b1a89b1ed03810f51d1",
75
+ "sha1": "2ee4f5948cbb7bfd01d50dd8148b7708975dd725",
76
+ "md5": "a0650e7cf68cce59ce1dfb0fbcd96b16"
77
+ }
78
+ ]
79
+ },
80
+ {
81
+ "name": "releaseVariantReleaseSourcePublication",
82
+ "attributes": {
83
+ "org.gradle.category": "documentation",
84
+ "org.gradle.dependency.bundling": "external",
85
+ "org.gradle.docstype": "sources",
86
+ "org.gradle.usage": "java-runtime"
87
+ },
88
+ "files": [
89
+ {
90
+ "name": "expo.modules.meshgradient-0.4.0-canary-20250611-f0afe80-sources.jar",
91
+ "url": "expo.modules.meshgradient-0.4.0-canary-20250611-f0afe80-sources.jar",
92
+ "size": 4430,
93
+ "sha512": "8720b775920bbcf29474c187976f588788735c22da798db873d13985aa6197d51ef4e78baab63d1b4874320bfa555cc2af7963fba6bd0fe4ee100328eb78748b",
94
+ "sha256": "b80119f206bb91853fde59bdcdda8a93900ba9abf605e745f31b0605a5e7fc3d",
95
+ "sha1": "65c0192f99ad54e44a2b27deb1ffca3dea85e3ff",
96
+ "md5": "ca79fdb6a635597c829ab2557f0dbc3a"
97
+ }
98
+ ]
99
+ }
100
+ ]
101
+ }
@@ -0,0 +1 @@
1
+ 599b8c08c2b09b4c2d240bc796edbf8cbdfdf9bc5dffd88863007ed359d639cf34fe6803567440f4192f7fdd405275909be054646ab44ae56633694647e060a9
@@ -0,0 +1,47 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
3
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
4
+ <!-- This module was also published with a richer model, Gradle metadata, -->
5
+ <!-- which should be used instead. Do not delete the following line which -->
6
+ <!-- is to indicate to Gradle or any Gradle module metadata file consumer -->
7
+ <!-- that they should prefer consuming it instead. -->
8
+ <!-- do_not_remove: published-with-gradle-metadata -->
9
+ <modelVersion>4.0.0</modelVersion>
10
+ <groupId>host.exp.exponent</groupId>
11
+ <artifactId>expo.modules.meshgradient</artifactId>
12
+ <version>0.4.0-canary-20250611-f0afe80</version>
13
+ <packaging>aar</packaging>
14
+ <name>expo.modules.meshgradient</name>
15
+ <url>https://github.com/expo/expo</url>
16
+ <licenses>
17
+ <license>
18
+ <name>MIT License</name>
19
+ <url>https://github.com/expo/expo/blob/main/LICENSE</url>
20
+ </license>
21
+ </licenses>
22
+ <scm>
23
+ <connection>https://github.com/expo/expo.git</connection>
24
+ <developerConnection>https://github.com/expo/expo.git</developerConnection>
25
+ <url>https://github.com/expo/expo</url>
26
+ </scm>
27
+ <dependencies>
28
+ <dependency>
29
+ <groupId>org.jetbrains.kotlin</groupId>
30
+ <artifactId>kotlin-stdlib-jdk7</artifactId>
31
+ <version>2.1.20</version>
32
+ <scope>runtime</scope>
33
+ </dependency>
34
+ <dependency>
35
+ <groupId>androidx.compose.foundation</groupId>
36
+ <artifactId>foundation-android</artifactId>
37
+ <version>1.7.6</version>
38
+ <scope>runtime</scope>
39
+ </dependency>
40
+ <dependency>
41
+ <groupId>androidx.compose.ui</groupId>
42
+ <artifactId>ui-android</artifactId>
43
+ <version>1.7.6</version>
44
+ <scope>runtime</scope>
45
+ </dependency>
46
+ </dependencies>
47
+ </project>
@@ -0,0 +1 @@
1
+ 5ac817f38a399ac2c62e39289e3f94d9b7990c53a99080ba95db43eadc7774c15b97352e3246beed7c20a9775e63a68ec46bc0e01061ae57721daeaa312f552b
@@ -0,0 +1,13 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <metadata>
3
+ <groupId>host.exp.exponent</groupId>
4
+ <artifactId>expo.modules.meshgradient</artifactId>
5
+ <versioning>
6
+ <latest>0.4.0-canary-20250611-f0afe80</latest>
7
+ <release>0.4.0-canary-20250611-f0afe80</release>
8
+ <versions>
9
+ <version>0.4.0-canary-20250611-f0afe80</version>
10
+ </versions>
11
+ <lastUpdated>20250611221441</lastUpdated>
12
+ </versioning>
13
+ </metadata>
@@ -0,0 +1 @@
1
+ c0e25b7708b46eaed5cdcb17b9d02993
@@ -0,0 +1 @@
1
+ e2a461d06563995a771e6161dc5b0ae0fcc9dffc
@@ -0,0 +1 @@
1
+ df879b4f55aca7c75e60f0dc220354746929a0f66bf9aaa5711fa523e097655c
@@ -0,0 +1 @@
1
+ af8a069dd2c4c3f77c18e9f720e51ef7e239525549d07cc0977a305afb5ae6822f8893e7b6021449a96f9e3528c272630a981e74e3ad10c416b6704298a37a0c
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-mesh-gradient",
3
- "version": "0.3.4",
3
+ "version": "0.4.0-canary-20250611-f0afe80",
4
4
  "description": "A module that exposes MeshGradient view from SwiftUI to React Native",
5
5
  "main": "src/index.ts",
6
6
  "types": "build/index.d.ts",
@@ -31,12 +31,11 @@
31
31
  "dependencies": {},
32
32
  "devDependencies": {
33
33
  "@types/react": "~19.0.10",
34
- "expo-module-scripts": "^4.1.6"
34
+ "expo-module-scripts": "4.1.8-canary-20250611-f0afe80"
35
35
  },
36
36
  "peerDependencies": {
37
- "expo": "*",
37
+ "expo": "54.0.0-canary-20250611-f0afe80",
38
38
  "react": "*",
39
39
  "react-native": "*"
40
- },
41
- "gitHead": "84355076bc31a356aa3d23257f387f221885f53d"
40
+ }
42
41
  }
@@ -1,4 +1,4 @@
1
- import type { ViewProps } from 'react-native';
1
+ import type { ColorValue, ViewProps } from 'react-native';
2
2
 
3
3
  export interface MeshGradientViewProps extends ViewProps {
4
4
  /**
@@ -23,7 +23,7 @@ export interface MeshGradientViewProps extends ViewProps {
23
23
  * An array of colors. Must contain `columns * rows` elements.
24
24
  * @default []
25
25
  */
26
- colors?: string[];
26
+ colors?: ColorValue[];
27
27
 
28
28
  /**
29
29
  * Whether cubic (smooth) interpolation should be used for the colors in the mesh
@@ -35,6 +35,7 @@ export interface MeshGradientViewProps extends ViewProps {
35
35
  /**
36
36
  * Whether to ignore safe areas when positioning the view.
37
37
  * @default true
38
+ * @platform ios
38
39
  */
39
40
  ignoresSafeArea?: boolean;
40
41
 
@@ -42,6 +43,17 @@ export interface MeshGradientViewProps extends ViewProps {
42
43
  * Masks the gradient using the alpha channel of the given children views.
43
44
  * > **Note**: When this option is enabled, all user interactions (gestures) on children views are ignored.
44
45
  * @default false
46
+ * @platform ios
45
47
  */
46
48
  mask?: boolean;
49
+
50
+ /**
51
+ * Specifies how many points to sample on the path between points.
52
+ * @default { x: 1, y: 1 }
53
+ * @platform android
54
+ */
55
+ resolution?: {
56
+ x?: number;
57
+ y?: number;
58
+ };
47
59
  }
@@ -1,5 +1,23 @@
1
1
  import { requireNativeView } from 'expo';
2
+ import { Platform, processColor, ProcessedColorValue } from 'react-native';
2
3
 
3
4
  import { MeshGradientViewProps } from './MeshGradient.types';
4
5
 
5
- export default requireNativeView<MeshGradientViewProps>('ExpoMeshGradient');
6
+ const NativeView = requireNativeView<
7
+ Omit<MeshGradientViewProps, 'colors'> & {
8
+ colors?: (ProcessedColorValue | null | undefined)[];
9
+ }
10
+ >('ExpoMeshGradient');
11
+
12
+ const MeshGradientView = (props: MeshGradientViewProps) => {
13
+ const { colors, children, ...restProps } = props;
14
+ return (
15
+ <NativeView
16
+ {...restProps}
17
+ colors={colors?.map((color) => processColor(color))}
18
+ children={Platform.OS !== 'android' ? children : undefined}
19
+ />
20
+ );
21
+ };
22
+
23
+ export default MeshGradientView;