Skip to content

Commit 36405d1

Browse files
tepamidfacebook-github-bot
authored andcommitted
Implemented linear gradient fill in Android
Summary: Partial implementation of "TODO(6352048): Support gradients etc.": linear gradient fill implemented. We implemented a custom Color Picker based on ReactART. <img width="268" alt="screen shot 2016-12-19 at 12 27 09 pm" src="https://cloud.githubusercontent.com/assets/18415611/21309512/5033b5a4-c5e7-11e6-9558-5571d18210e9.png"> Closes facebook#11541 Differential Revision: D5061836 Pulled By: ericvicenti fbshipit-source-id: ec8b7a0a6f3d2d1a2c1b394d4960d3365ad6fb44
1 parent dc339f7 commit 36405d1

File tree

1 file changed

+59
-10
lines changed

1 file changed

+59
-10
lines changed

ReactAndroid/src/main/java/com/facebook/react/views/art/ARTShapeShadowNode.java

Lines changed: 59 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
import android.graphics.Path;
1717
import android.graphics.RectF;
1818
import android.graphics.DashPathEffect;
19+
import android.graphics.LinearGradient;
20+
import android.graphics.Shader;
21+
import android.graphics.Color;
1922

2023
import com.facebook.common.logging.FLog;
2124
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
@@ -42,9 +45,16 @@ public class ARTShapeShadowNode extends ARTVirtualNode {
4245
private static final int PATH_TYPE_LINETO = 2;
4346
private static final int PATH_TYPE_MOVETO = 0;
4447

48+
// For color type JS and ObjectiveC definitions counterparts
49+
// refer to ReactNativeART.js and RCTConvert+ART.m
50+
private static final int COLOR_TYPE_SOLID_COLOR = 0;
51+
private static final int COLOR_TYPE_LINEAR_GRADIENT = 1;
52+
private static final int COLOR_TYPE_RADIAL_GRADIENT = 2;
53+
private static final int COLOR_TYPE_PATTERN = 3;
54+
4555
protected @Nullable Path mPath;
4656
private @Nullable float[] mStrokeColor;
47-
private @Nullable float[] mFillColor;
57+
private @Nullable float[] mBrushData;
4858
private @Nullable float[] mStrokeDash;
4959
private float mStrokeWidth = 1;
5060
private int mStrokeCap = CAP_ROUND;
@@ -71,7 +81,7 @@ public void setStrokeDash(@Nullable ReadableArray strokeDash) {
7181

7282
@ReactProp(name = "fill")
7383
public void setFill(@Nullable ReadableArray fillColors) {
74-
mFillColor = PropHelper.toFloatArray(fillColors);
84+
mBrushData = PropHelper.toFloatArray(fillColors);
7585
markUpdated();
7686
}
7787

@@ -169,21 +179,60 @@ protected boolean setupStrokePaint(Paint paint, float opacity) {
169179
* if the fill should be drawn, {@code false} if not.
170180
*/
171181
protected boolean setupFillPaint(Paint paint, float opacity) {
172-
if (mFillColor != null && mFillColor.length > 0) {
182+
if (mBrushData != null && mBrushData.length > 0) {
173183
paint.reset();
174184
paint.setFlags(Paint.ANTI_ALIAS_FLAG);
175185
paint.setStyle(Paint.Style.FILL);
176-
int colorType = (int) mFillColor[0];
186+
int colorType = (int) mBrushData[0];
177187
switch (colorType) {
178-
case 0:
188+
case COLOR_TYPE_SOLID_COLOR:
179189
paint.setARGB(
180-
(int) (mFillColor.length > 4 ? mFillColor[4] * opacity * 255 : opacity * 255),
181-
(int) (mFillColor[1] * 255),
182-
(int) (mFillColor[2] * 255),
183-
(int) (mFillColor[3] * 255));
190+
(int) (mBrushData.length > 4 ? mBrushData[4] * opacity * 255 : opacity * 255),
191+
(int) (mBrushData[1] * 255),
192+
(int) (mBrushData[2] * 255),
193+
(int) (mBrushData[3] * 255));
194+
break;
195+
case COLOR_TYPE_LINEAR_GRADIENT:
196+
// For mBrushData format refer to LinearGradient and insertColorStopsIntoArray functions in ReactNativeART.js
197+
if (mBrushData.length < 5) {
198+
FLog.w(ReactConstants.TAG,
199+
"[ARTShapeShadowNode setupFillPaint] expects 5 elements, received "
200+
+ mBrushData.length);
201+
return false;
202+
}
203+
float gradientStartX = mBrushData[1] * mScale;
204+
float gradientStartY = mBrushData[2] * mScale;
205+
float gradientEndX = mBrushData[3] * mScale;
206+
float gradientEndY = mBrushData[4] * mScale;
207+
int stops = (mBrushData.length - 5) / 5;
208+
int[] colors = null;
209+
float[] positions = null;
210+
if (stops > 0) {
211+
colors = new int[stops];
212+
positions = new float[stops];
213+
for (int i=0; i<stops; i++) {
214+
positions[i] = mBrushData[5 + 4*stops + i];
215+
int r = (int) (255 * mBrushData[5 + 4*i + 0]);
216+
int g = (int) (255 * mBrushData[5 + 4*i + 1]);
217+
int b = (int) (255 * mBrushData[5 + 4*i + 2]);
218+
int a = (int) (255 * mBrushData[5 + 4*i + 3]);
219+
colors[i] = Color.argb(a, r, g, b);
220+
}
221+
}
222+
paint.setShader(
223+
new LinearGradient(
224+
gradientStartX, gradientStartY,
225+
gradientEndX, gradientEndY,
226+
colors, positions,
227+
Shader.TileMode.CLAMP
228+
)
229+
);
184230
break;
231+
case COLOR_TYPE_RADIAL_GRADIENT:
232+
// TODO(6352048): Support radial gradient etc.
233+
case COLOR_TYPE_PATTERN:
234+
// TODO(6352048): Support patterns etc.
185235
default:
186-
// TODO(6352048): Support gradients etc.
187236
FLog.w(ReactConstants.TAG, "ART: Color type " + colorType + " not supported!");
188237
}
189238
return true;

0 commit comments

Comments
 (0)