react-native-linear-gradient-fabric 0.1.0
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/README.md +132 -0
- package/android/build.gradle +107 -0
- package/android/gradle.properties +4 -0
- package/android/src/main/AndroidManifest.xml +3 -0
- package/android/src/main/AndroidManifestNew.xml +2 -0
- package/android/src/main/java/com/lineargradientfabric/LinearGradientFabricPackage.kt +17 -0
- package/android/src/main/java/com/lineargradientfabric/LinearGradientView.kt +128 -0
- package/android/src/newarch/LinearGradientViewManager.kt +92 -0
- package/android/src/oldarch/LinearGradientViewManager.kt +82 -0
- package/ios/LinearGradientView.h +13 -0
- package/ios/LinearGradientView.m +145 -0
- package/ios/LinearGradientViewComponentView.h +13 -0
- package/ios/LinearGradientViewComponentView.mm +181 -0
- package/ios/LinearGradientViewManager.h +5 -0
- package/ios/LinearGradientViewManager.m +56 -0
- package/lib/commonjs/LinearGradientNativeComponent.js +10 -0
- package/lib/commonjs/LinearGradientNativeComponent.js.map +1 -0
- package/lib/commonjs/index.js +73 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/module/LinearGradientNativeComponent.js +3 -0
- package/lib/module/LinearGradientNativeComponent.js.map +1 -0
- package/lib/module/index.js +64 -0
- package/lib/module/index.js.map +1 -0
- package/lib/typescript/src/LinearGradientNativeComponent.d.ts +39 -0
- package/lib/typescript/src/LinearGradientNativeComponent.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +54 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/package.json +145 -0
- package/react-native-linear-gradient-fabric.podspec +20 -0
- package/src/LinearGradientNativeComponent.ts +43 -0
- package/src/index.tsx +128 -0
package/README.md
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
# react-native-linear-gradient-fabric
|
|
2
|
+
|
|
3
|
+
A modern replacement for `react-native-linear-gradient` with full New Architecture (Fabric) support.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Full support for React Native New Architecture (Fabric)
|
|
8
|
+
- Backward compatible with Old Architecture via Interop Layer
|
|
9
|
+
- GPU-accelerated gradient rendering
|
|
10
|
+
- All features from the original `react-native-linear-gradient`
|
|
11
|
+
|
|
12
|
+
## Installation
|
|
13
|
+
|
|
14
|
+
```sh
|
|
15
|
+
bun add react-native-linear-gradient-fabric
|
|
16
|
+
# or
|
|
17
|
+
npm install react-native-linear-gradient-fabric
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
### iOS
|
|
21
|
+
|
|
22
|
+
```sh
|
|
23
|
+
cd ios && pod install
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### Android
|
|
27
|
+
|
|
28
|
+
No additional steps required. The library will be automatically linked.
|
|
29
|
+
|
|
30
|
+
## Usage
|
|
31
|
+
|
|
32
|
+
```tsx
|
|
33
|
+
import { LinearGradient } from 'react-native-linear-gradient-fabric';
|
|
34
|
+
|
|
35
|
+
// Basic vertical gradient
|
|
36
|
+
<LinearGradient
|
|
37
|
+
colors={['#4c669f', '#3b5998', '#192f6a']}
|
|
38
|
+
style={{ flex: 1 }}
|
|
39
|
+
/>
|
|
40
|
+
|
|
41
|
+
// Horizontal gradient
|
|
42
|
+
<LinearGradient
|
|
43
|
+
colors={['#ff6b6b', '#feca57', '#48dbfb']}
|
|
44
|
+
start={{ x: 0, y: 0.5 }}
|
|
45
|
+
end={{ x: 1, y: 0.5 }}
|
|
46
|
+
style={{ height: 100 }}
|
|
47
|
+
/>
|
|
48
|
+
|
|
49
|
+
// Diagonal gradient
|
|
50
|
+
<LinearGradient
|
|
51
|
+
colors={['#a55eea', '#45aaf2']}
|
|
52
|
+
start={{ x: 0, y: 0 }}
|
|
53
|
+
end={{ x: 1, y: 1 }}
|
|
54
|
+
style={{ height: 100 }}
|
|
55
|
+
/>
|
|
56
|
+
|
|
57
|
+
// Gradient with custom color stops
|
|
58
|
+
<LinearGradient
|
|
59
|
+
colors={['#ff0000', '#ffff00', '#00ff00']}
|
|
60
|
+
locations={[0, 0.3, 1]}
|
|
61
|
+
style={{ height: 100 }}
|
|
62
|
+
/>
|
|
63
|
+
|
|
64
|
+
// Angle-based gradient
|
|
65
|
+
<LinearGradient
|
|
66
|
+
colors={['#667eea', '#764ba2']}
|
|
67
|
+
useAngle
|
|
68
|
+
angle={45}
|
|
69
|
+
style={{ height: 100 }}
|
|
70
|
+
/>
|
|
71
|
+
|
|
72
|
+
// Gradient as background with children
|
|
73
|
+
<LinearGradient
|
|
74
|
+
colors={['#00c6fb', '#005bea']}
|
|
75
|
+
style={{ padding: 20, borderRadius: 10 }}
|
|
76
|
+
>
|
|
77
|
+
<Text style={{ color: 'white' }}>Hello, Gradient!</Text>
|
|
78
|
+
</LinearGradient>
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Props
|
|
82
|
+
|
|
83
|
+
| Prop | Type | Required | Default | Description |
|
|
84
|
+
|------|------|----------|---------|-------------|
|
|
85
|
+
| `colors` | `ColorValue[]` | Yes | - | An array of at least 2 colors |
|
|
86
|
+
| `start` | `{ x: number, y: number }` | No | `{ x: 0.5, y: 0 }` | Start point of the gradient |
|
|
87
|
+
| `end` | `{ x: number, y: number }` | No | `{ x: 0.5, y: 1 }` | End point of the gradient |
|
|
88
|
+
| `locations` | `number[]` | No | evenly distributed | Color stop positions (0-1) |
|
|
89
|
+
| `useAngle` | `boolean` | No | `false` | Use angle instead of start/end |
|
|
90
|
+
| `angle` | `number` | No | `0` | Gradient angle in degrees |
|
|
91
|
+
| `angleCenter` | `{ x: number, y: number }` | No | `{ x: 0.5, y: 0.5 }` | Center point for angle rotation |
|
|
92
|
+
| `style` | `ViewStyle` | No | - | Style for the gradient view |
|
|
93
|
+
| `children` | `ReactNode` | No | - | Content to render on top |
|
|
94
|
+
|
|
95
|
+
### Coordinate System
|
|
96
|
+
|
|
97
|
+
The `start` and `end` props use a coordinate system where:
|
|
98
|
+
- `x: 0` = left edge, `x: 1` = right edge
|
|
99
|
+
- `y: 0` = top edge, `y: 1` = bottom edge
|
|
100
|
+
|
|
101
|
+
### Angle System
|
|
102
|
+
|
|
103
|
+
When using `useAngle` and `angle`:
|
|
104
|
+
- `0°` = upward (top)
|
|
105
|
+
- `90°` = rightward
|
|
106
|
+
- `180°` = downward (bottom)
|
|
107
|
+
- `270°` = leftward
|
|
108
|
+
|
|
109
|
+
## Testing
|
|
110
|
+
|
|
111
|
+
For testing, you can use the provided mock:
|
|
112
|
+
|
|
113
|
+
```js
|
|
114
|
+
// jest.setup.js
|
|
115
|
+
jest.mock('react-native-linear-gradient-fabric', () =>
|
|
116
|
+
require('react-native-linear-gradient-fabric/jest/linear-gradient-mock')
|
|
117
|
+
);
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## Requirements
|
|
121
|
+
|
|
122
|
+
- React Native 0.72+
|
|
123
|
+
- iOS 13.4+
|
|
124
|
+
- Android SDK 21+
|
|
125
|
+
|
|
126
|
+
## License
|
|
127
|
+
|
|
128
|
+
MIT
|
|
129
|
+
|
|
130
|
+
## Contributing
|
|
131
|
+
|
|
132
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for details.
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
buildscript {
|
|
2
|
+
ext.safeExtGet = {prop, fallback ->
|
|
3
|
+
rootProject.ext.has(prop) ? rootProject.ext.get(prop) : fallback
|
|
4
|
+
}
|
|
5
|
+
repositories {
|
|
6
|
+
google()
|
|
7
|
+
mavenCentral()
|
|
8
|
+
}
|
|
9
|
+
dependencies {
|
|
10
|
+
classpath("com.android.tools.build:gradle:7.4.2")
|
|
11
|
+
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:${safeExtGet('kotlinVersion', '1.8.22')}")
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
def isNewArchitectureEnabled() {
|
|
16
|
+
return rootProject.hasProperty("newArchEnabled") && rootProject.getProperty("newArchEnabled") == "true"
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
apply plugin: "com.android.library"
|
|
20
|
+
apply plugin: "kotlin-android"
|
|
21
|
+
|
|
22
|
+
if (isNewArchitectureEnabled()) {
|
|
23
|
+
apply plugin: "com.facebook.react"
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
def getExtOrDefault(name) {
|
|
27
|
+
return rootProject.ext.has(name) ? rootProject.ext.get(name) : project.properties["LinearGradientFabric_" + name]
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
def getExtOrIntegerDefault(name) {
|
|
31
|
+
return rootProject.ext.has(name) ? rootProject.ext.get(name) : (project.properties["LinearGradientFabric_" + name]).toInteger()
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
def supportsNamespace() {
|
|
35
|
+
def parsed = com.android.Version.ANDROID_GRADLE_PLUGIN_VERSION.tokenize('.')
|
|
36
|
+
def major = parsed[0].toInteger()
|
|
37
|
+
def minor = parsed[1].toInteger()
|
|
38
|
+
return (major == 7 && minor >= 3) || major >= 8
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
android {
|
|
42
|
+
if (supportsNamespace()) {
|
|
43
|
+
namespace "com.lineargradientfabric"
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
compileSdkVersion getExtOrIntegerDefault("compileSdkVersion")
|
|
47
|
+
|
|
48
|
+
defaultConfig {
|
|
49
|
+
minSdkVersion getExtOrIntegerDefault("minSdkVersion")
|
|
50
|
+
targetSdkVersion getExtOrIntegerDefault("targetSdkVersion")
|
|
51
|
+
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
buildFeatures {
|
|
55
|
+
buildConfig true
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
buildTypes {
|
|
59
|
+
release {
|
|
60
|
+
minifyEnabled false
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
lintOptions {
|
|
65
|
+
disable "GradleCompatible"
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
compileOptions {
|
|
69
|
+
sourceCompatibility JavaVersion.VERSION_17
|
|
70
|
+
targetCompatibility JavaVersion.VERSION_17
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
kotlinOptions {
|
|
74
|
+
jvmTarget = "17"
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
sourceSets {
|
|
78
|
+
main {
|
|
79
|
+
if (supportsNamespace()) {
|
|
80
|
+
manifest.srcFile "src/main/AndroidManifestNew.xml"
|
|
81
|
+
}
|
|
82
|
+
if (isNewArchitectureEnabled()) {
|
|
83
|
+
java.srcDirs += ["src/newarch"]
|
|
84
|
+
} else {
|
|
85
|
+
java.srcDirs += ["src/oldarch"]
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
repositories {
|
|
92
|
+
mavenCentral()
|
|
93
|
+
google()
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
dependencies {
|
|
97
|
+
implementation "com.facebook.react:react-android"
|
|
98
|
+
implementation "org.jetbrains.kotlin:kotlin-stdlib:${safeExtGet('kotlinVersion', '1.8.22')}"
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (isNewArchitectureEnabled()) {
|
|
102
|
+
react {
|
|
103
|
+
jsRootDir = file("../src/")
|
|
104
|
+
libraryName = "LinearGradientFabric"
|
|
105
|
+
codegenJavaPackageName = "com.lineargradientfabric"
|
|
106
|
+
}
|
|
107
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
package com.lineargradientfabric
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.ReactPackage
|
|
4
|
+
import com.facebook.react.bridge.NativeModule
|
|
5
|
+
import com.facebook.react.bridge.ReactApplicationContext
|
|
6
|
+
import com.facebook.react.uimanager.ViewManager
|
|
7
|
+
|
|
8
|
+
class LinearGradientFabricPackage : ReactPackage {
|
|
9
|
+
|
|
10
|
+
override fun createNativeModules(reactContext: ReactApplicationContext): List<NativeModule> {
|
|
11
|
+
return emptyList()
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
|
|
15
|
+
return listOf(LinearGradientViewManager())
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
package com.lineargradientfabric
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.graphics.Canvas
|
|
5
|
+
import android.graphics.LinearGradient
|
|
6
|
+
import android.graphics.Paint
|
|
7
|
+
import android.graphics.Shader
|
|
8
|
+
import android.widget.FrameLayout
|
|
9
|
+
import kotlin.math.cos
|
|
10
|
+
import kotlin.math.sin
|
|
11
|
+
|
|
12
|
+
class LinearGradientView(context: Context) : FrameLayout(context) {
|
|
13
|
+
|
|
14
|
+
private val paint = Paint()
|
|
15
|
+
private var colors: IntArray = intArrayOf()
|
|
16
|
+
private var locations: FloatArray? = null
|
|
17
|
+
private var startX: Float = 0.5f
|
|
18
|
+
private var startY: Float = 0f
|
|
19
|
+
private var endX: Float = 0.5f
|
|
20
|
+
private var endY: Float = 1f
|
|
21
|
+
private var useAngle: Boolean = false
|
|
22
|
+
private var angle: Float = 0f
|
|
23
|
+
private var angleCenterX: Float = 0.5f
|
|
24
|
+
private var angleCenterY: Float = 0.5f
|
|
25
|
+
|
|
26
|
+
init {
|
|
27
|
+
// Enable drawing for ViewGroup
|
|
28
|
+
setWillNotDraw(false)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
fun setColors(colors: IntArray) {
|
|
32
|
+
this.colors = colors
|
|
33
|
+
invalidate()
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
fun setLocations(locations: FloatArray?) {
|
|
37
|
+
this.locations = locations
|
|
38
|
+
invalidate()
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
fun setStartPoint(x: Float, y: Float) {
|
|
42
|
+
this.startX = x
|
|
43
|
+
this.startY = y
|
|
44
|
+
invalidate()
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
fun setEndPoint(x: Float, y: Float) {
|
|
48
|
+
this.endX = x
|
|
49
|
+
this.endY = y
|
|
50
|
+
invalidate()
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
fun setUseAngle(useAngle: Boolean) {
|
|
54
|
+
this.useAngle = useAngle
|
|
55
|
+
invalidate()
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
fun setAngle(angle: Float) {
|
|
59
|
+
this.angle = angle
|
|
60
|
+
invalidate()
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
fun setAngleCenter(x: Float, y: Float) {
|
|
64
|
+
this.angleCenterX = x
|
|
65
|
+
this.angleCenterY = y
|
|
66
|
+
invalidate()
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
override fun onDraw(canvas: Canvas) {
|
|
70
|
+
if (colors.size < 2 || width == 0 || height == 0) {
|
|
71
|
+
super.onDraw(canvas)
|
|
72
|
+
return
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
val (x0, y0, x1, y1) = calculateGradientPoints()
|
|
76
|
+
|
|
77
|
+
val gradient = LinearGradient(
|
|
78
|
+
x0, y0, x1, y1,
|
|
79
|
+
colors,
|
|
80
|
+
locations,
|
|
81
|
+
Shader.TileMode.CLAMP
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
paint.shader = gradient
|
|
85
|
+
canvas.drawRect(0f, 0f, width.toFloat(), height.toFloat(), paint)
|
|
86
|
+
|
|
87
|
+
super.onDraw(canvas)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
private fun calculateGradientPoints(): FloatArray {
|
|
91
|
+
return if (useAngle) {
|
|
92
|
+
calculatePointsFromAngle()
|
|
93
|
+
} else {
|
|
94
|
+
floatArrayOf(
|
|
95
|
+
startX * width,
|
|
96
|
+
startY * height,
|
|
97
|
+
endX * width,
|
|
98
|
+
endY * height
|
|
99
|
+
)
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
private fun calculatePointsFromAngle(): FloatArray {
|
|
104
|
+
// Convert angle from degrees to radians
|
|
105
|
+
// Angle 0 = up, 90 = right, 180 = down, 270 = left
|
|
106
|
+
val angleRad = Math.toRadians((angle - 90).toDouble())
|
|
107
|
+
|
|
108
|
+
// Calculate the gradient direction vector
|
|
109
|
+
val dx = cos(angleRad).toFloat()
|
|
110
|
+
val dy = sin(angleRad).toFloat()
|
|
111
|
+
|
|
112
|
+
// Calculate the center point in pixels
|
|
113
|
+
val centerPx = angleCenterX * width
|
|
114
|
+
val centerPy = angleCenterY * height
|
|
115
|
+
|
|
116
|
+
// Calculate the length to cover the view
|
|
117
|
+
// Use half the diagonal for proper coverage
|
|
118
|
+
val halfWidth = width / 2f
|
|
119
|
+
val halfHeight = height / 2f
|
|
120
|
+
|
|
121
|
+
val x0 = centerPx - dx * halfWidth
|
|
122
|
+
val y0 = centerPy - dy * halfHeight
|
|
123
|
+
val x1 = centerPx + dx * halfWidth
|
|
124
|
+
val y1 = centerPy + dy * halfHeight
|
|
125
|
+
|
|
126
|
+
return floatArrayOf(x0, y0, x1, y1)
|
|
127
|
+
}
|
|
128
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
package com.lineargradientfabric
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.ReadableArray
|
|
4
|
+
import com.facebook.react.bridge.ReadableMap
|
|
5
|
+
import com.facebook.react.module.annotations.ReactModule
|
|
6
|
+
import com.facebook.react.uimanager.ThemedReactContext
|
|
7
|
+
import com.facebook.react.uimanager.ViewGroupManager
|
|
8
|
+
import com.facebook.react.uimanager.ViewManagerDelegate
|
|
9
|
+
import com.facebook.react.uimanager.annotations.ReactProp
|
|
10
|
+
import com.facebook.react.viewmanagers.LinearGradientViewManagerDelegate
|
|
11
|
+
import com.facebook.react.viewmanagers.LinearGradientViewManagerInterface
|
|
12
|
+
|
|
13
|
+
@ReactModule(name = LinearGradientViewManager.REACT_CLASS)
|
|
14
|
+
class LinearGradientViewManager : ViewGroupManager<LinearGradientView>(),
|
|
15
|
+
LinearGradientViewManagerInterface<LinearGradientView> {
|
|
16
|
+
|
|
17
|
+
private val delegate: ViewManagerDelegate<LinearGradientView> = LinearGradientViewManagerDelegate(this)
|
|
18
|
+
|
|
19
|
+
override fun getDelegate(): ViewManagerDelegate<LinearGradientView> = delegate
|
|
20
|
+
|
|
21
|
+
override fun getName(): String = REACT_CLASS
|
|
22
|
+
|
|
23
|
+
override fun createViewInstance(reactContext: ThemedReactContext): LinearGradientView {
|
|
24
|
+
return LinearGradientView(reactContext)
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
@ReactProp(name = "colors")
|
|
28
|
+
override fun setColors(view: LinearGradientView, colors: ReadableArray?) {
|
|
29
|
+
if (colors == null) return
|
|
30
|
+
|
|
31
|
+
val colorArray = IntArray(colors.size())
|
|
32
|
+
for (i in 0 until colors.size()) {
|
|
33
|
+
colorArray[i] = colors.getInt(i)
|
|
34
|
+
}
|
|
35
|
+
view.setColors(colorArray)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
@ReactProp(name = "locations")
|
|
39
|
+
override fun setLocations(view: LinearGradientView, locations: ReadableArray?) {
|
|
40
|
+
if (locations == null) {
|
|
41
|
+
view.setLocations(null)
|
|
42
|
+
return
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
val locationArray = FloatArray(locations.size())
|
|
46
|
+
for (i in 0 until locations.size()) {
|
|
47
|
+
locationArray[i] = locations.getDouble(i).toFloat()
|
|
48
|
+
}
|
|
49
|
+
view.setLocations(locationArray)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
@ReactProp(name = "startPoint")
|
|
53
|
+
override fun setStartPoint(view: LinearGradientView, startPoint: ReadableMap?) {
|
|
54
|
+
if (startPoint == null) return
|
|
55
|
+
|
|
56
|
+
val x = startPoint.getDouble("x").toFloat()
|
|
57
|
+
val y = startPoint.getDouble("y").toFloat()
|
|
58
|
+
view.setStartPoint(x, y)
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
@ReactProp(name = "endPoint")
|
|
62
|
+
override fun setEndPoint(view: LinearGradientView, endPoint: ReadableMap?) {
|
|
63
|
+
if (endPoint == null) return
|
|
64
|
+
|
|
65
|
+
val x = endPoint.getDouble("x").toFloat()
|
|
66
|
+
val y = endPoint.getDouble("y").toFloat()
|
|
67
|
+
view.setEndPoint(x, y)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
@ReactProp(name = "useAngle", defaultBoolean = false)
|
|
71
|
+
override fun setUseAngle(view: LinearGradientView, useAngle: Boolean) {
|
|
72
|
+
view.setUseAngle(useAngle)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
@ReactProp(name = "angle", defaultFloat = 0f)
|
|
76
|
+
override fun setAngle(view: LinearGradientView, angle: Float) {
|
|
77
|
+
view.setAngle(angle)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
@ReactProp(name = "angleCenter")
|
|
81
|
+
override fun setAngleCenter(view: LinearGradientView, angleCenter: ReadableMap?) {
|
|
82
|
+
if (angleCenter == null) return
|
|
83
|
+
|
|
84
|
+
val x = angleCenter.getDouble("x").toFloat()
|
|
85
|
+
val y = angleCenter.getDouble("y").toFloat()
|
|
86
|
+
view.setAngleCenter(x, y)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
companion object {
|
|
90
|
+
const val REACT_CLASS = "LinearGradientView"
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
package com.lineargradientfabric
|
|
2
|
+
|
|
3
|
+
import com.facebook.react.bridge.ReadableArray
|
|
4
|
+
import com.facebook.react.bridge.ReadableMap
|
|
5
|
+
import com.facebook.react.uimanager.ThemedReactContext
|
|
6
|
+
import com.facebook.react.uimanager.ViewGroupManager
|
|
7
|
+
import com.facebook.react.uimanager.annotations.ReactProp
|
|
8
|
+
|
|
9
|
+
class LinearGradientViewManager : ViewGroupManager<LinearGradientView>() {
|
|
10
|
+
|
|
11
|
+
override fun getName(): String = REACT_CLASS
|
|
12
|
+
|
|
13
|
+
override fun createViewInstance(reactContext: ThemedReactContext): LinearGradientView {
|
|
14
|
+
return LinearGradientView(reactContext)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
@ReactProp(name = "colors")
|
|
18
|
+
fun setColors(view: LinearGradientView, colors: ReadableArray?) {
|
|
19
|
+
if (colors == null) return
|
|
20
|
+
|
|
21
|
+
val colorArray = IntArray(colors.size())
|
|
22
|
+
for (i in 0 until colors.size()) {
|
|
23
|
+
colorArray[i] = colors.getInt(i)
|
|
24
|
+
}
|
|
25
|
+
view.setColors(colorArray)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
@ReactProp(name = "locations")
|
|
29
|
+
fun setLocations(view: LinearGradientView, locations: ReadableArray?) {
|
|
30
|
+
if (locations == null) {
|
|
31
|
+
view.setLocations(null)
|
|
32
|
+
return
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
val locationArray = FloatArray(locations.size())
|
|
36
|
+
for (i in 0 until locations.size()) {
|
|
37
|
+
locationArray[i] = locations.getDouble(i).toFloat()
|
|
38
|
+
}
|
|
39
|
+
view.setLocations(locationArray)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
@ReactProp(name = "startPoint")
|
|
43
|
+
fun setStartPoint(view: LinearGradientView, startPoint: ReadableMap?) {
|
|
44
|
+
if (startPoint == null) return
|
|
45
|
+
|
|
46
|
+
val x = startPoint.getDouble("x").toFloat()
|
|
47
|
+
val y = startPoint.getDouble("y").toFloat()
|
|
48
|
+
view.setStartPoint(x, y)
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
@ReactProp(name = "endPoint")
|
|
52
|
+
fun setEndPoint(view: LinearGradientView, endPoint: ReadableMap?) {
|
|
53
|
+
if (endPoint == null) return
|
|
54
|
+
|
|
55
|
+
val x = endPoint.getDouble("x").toFloat()
|
|
56
|
+
val y = endPoint.getDouble("y").toFloat()
|
|
57
|
+
view.setEndPoint(x, y)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
@ReactProp(name = "useAngle")
|
|
61
|
+
fun setUseAngle(view: LinearGradientView, useAngle: Boolean) {
|
|
62
|
+
view.setUseAngle(useAngle)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
@ReactProp(name = "angle")
|
|
66
|
+
fun setAngle(view: LinearGradientView, angle: Float) {
|
|
67
|
+
view.setAngle(angle)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
@ReactProp(name = "angleCenter")
|
|
71
|
+
fun setAngleCenter(view: LinearGradientView, angleCenter: ReadableMap?) {
|
|
72
|
+
if (angleCenter == null) return
|
|
73
|
+
|
|
74
|
+
val x = angleCenter.getDouble("x").toFloat()
|
|
75
|
+
val y = angleCenter.getDouble("y").toFloat()
|
|
76
|
+
view.setAngleCenter(x, y)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
companion object {
|
|
80
|
+
const val REACT_CLASS = "LinearGradientView"
|
|
81
|
+
}
|
|
82
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#import <UIKit/UIKit.h>
|
|
2
|
+
|
|
3
|
+
@interface LinearGradientView : UIView
|
|
4
|
+
|
|
5
|
+
@property (nonatomic, copy) NSArray<NSNumber *> *colors;
|
|
6
|
+
@property (nonatomic, copy) NSArray<NSNumber *> *locations;
|
|
7
|
+
@property (nonatomic, assign) CGPoint startPoint;
|
|
8
|
+
@property (nonatomic, assign) CGPoint endPoint;
|
|
9
|
+
@property (nonatomic, assign) BOOL useAngle;
|
|
10
|
+
@property (nonatomic, assign) CGFloat angle;
|
|
11
|
+
@property (nonatomic, assign) CGPoint angleCenter;
|
|
12
|
+
|
|
13
|
+
@end
|