From f68281a0d8fc6026a5c27675c086090ace19a5eb Mon Sep 17 00:00:00 2001 From: Noam Bartov Date: Sun, 24 Jan 2016 13:59:36 -0800 Subject: [PATCH] added support for overlayColor property for image Summary: In Android, Fresco's default rounding corners support mode is BITMAP_ONLY which doesn't work in all cases (such as animated GIF's, some scale types, etc.). Specifying the new "overlayColor" property on an Image will cause Fresco to switch to the other rounding corners mode, OVERLAY_COLOR, and will draw rounded corners by overlaying the solid color specified. Fresco's behaviour is explained here: http://frescolib.org/docs/rounded-corners-and-circles.html Closes https://github.com/facebook/react-native/pull/5366 Reviewed By: svcscm Differential Revision: D2854696 Pulled By: mkonicek fb-gh-sync-id: 251701ee8a64acbfc22694e9d4661c40eef75725 --- .../View/ReactNativeStyleAttributes.js | 1 + Libraries/Image/ImageStylePropTypes.js | 25 +++++++++++++++++-- .../react/views/image/ReactImageManager.java | 9 +++++++ .../react/views/image/ReactImageView.java | 13 ++++++++++ 4 files changed, 46 insertions(+), 2 deletions(-) diff --git a/Libraries/Components/View/ReactNativeStyleAttributes.js b/Libraries/Components/View/ReactNativeStyleAttributes.js index d26e01615..b9e909a17 100644 --- a/Libraries/Components/View/ReactNativeStyleAttributes.js +++ b/Libraries/Components/View/ReactNativeStyleAttributes.js @@ -47,5 +47,6 @@ ReactNativeStyleAttributes.shadowColor = colorAttributes; ReactNativeStyleAttributes.textDecorationColor = colorAttributes; ReactNativeStyleAttributes.tintColor = colorAttributes; ReactNativeStyleAttributes.textShadowColor = colorAttributes; +ReactNativeStyleAttributes.overlayColor = colorAttributes; module.exports = ReactNativeStyleAttributes; diff --git a/Libraries/Image/ImageStylePropTypes.js b/Libraries/Image/ImageStylePropTypes.js index 5e99a54b0..b1c5e12b1 100644 --- a/Libraries/Image/ImageStylePropTypes.js +++ b/Libraries/Image/ImageStylePropTypes.js @@ -30,10 +30,31 @@ var ImageStylePropTypes = { borderRadius: ReactPropTypes.number, overflow: ReactPropTypes.oneOf(['visible', 'hidden']), - // iOS-Specific style to "tint" an image. - // It changes the color of all the non-transparent pixels to the tintColor + /** + * iOS-Specific style to "tint" an image. + * Changes the color of all the non-transparent pixels to the tintColor. + * @platform ios + */ tintColor: ColorPropType, opacity: ReactPropTypes.number, + /** + * When the image has rounded corners, specifying an overlayColor will + * cause the remaining space in the corners to be filled with a solid color. + * This is useful in cases which are not supported by the Android + * implementation of rounded corners: + * - Certain resize modes, such as 'contain' + * - Animated GIFs + * + * A typical way to use this prop is with images displayed on a solid + * background and setting the `overlayColor` to the same color + * as the background. + * + * For details of how this works under the hood, see + * http://frescolib.org/docs/rounded-corners-and-circles.html + * + * @platform android + */ + overlayColor: ReactPropTypes.string, }; module.exports = ImageStylePropTypes; diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageManager.java index 812fd4118..8b3298647 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageManager.java @@ -88,6 +88,15 @@ public class ReactImageManager extends SimpleViewManager { } } + @ReactProp(name = "overlayColor") + public void setOverlayColor(ReactImageView view, @Nullable Integer overlayColor) { + if (overlayColor == null) { + view.setOverlayColor(Color.TRANSPARENT); + } else { + view.setOverlayColor(overlayColor); + } + } + @ReactProp(name = "borderWidth") public void setBorderWidth(ReactImageView view, float borderWidth) { view.setBorderWidth(borderWidth); diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageView.java b/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageView.java index 58ebb0c80..c627bdc6e 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageView.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageView.java @@ -16,6 +16,7 @@ import android.graphics.Bitmap; import android.graphics.BitmapShader; import android.graphics.Canvas; import android.graphics.drawable.Drawable; +import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Rect; @@ -108,6 +109,7 @@ public class ReactImageView extends GenericDraweeView { private @Nullable Uri mUri; private @Nullable Drawable mLoadingImageDrawable; private int mBorderColor; + private int mOverlayColor; private float mBorderWidth; private float mBorderRadius; private ScalingUtils.ScaleType mScaleType; @@ -186,6 +188,11 @@ public class ReactImageView extends GenericDraweeView { mIsDirty = true; } + public void setOverlayColor(int overlayColor) { + mOverlayColor = overlayColor; + mIsDirty = true; + } + public void setBorderWidth(float borderWidth) { mBorderWidth = PixelUtil.toPixelFromDIP(borderWidth); mIsDirty = true; @@ -266,6 +273,12 @@ public class ReactImageView extends GenericDraweeView { RoundingParams roundingParams = hierarchy.getRoundingParams(); roundingParams.setCornersRadius(hierarchyRadius); roundingParams.setBorder(mBorderColor, mBorderWidth); + if (mOverlayColor != Color.TRANSPARENT) { + roundingParams.setOverlayColor(mOverlayColor); + } else { + // make sure the default rounding method is used. + roundingParams.setRoundingMethod(RoundingParams.RoundingMethod.BITMAP_ONLY); + } hierarchy.setRoundingParams(roundingParams); hierarchy.setFadeDuration( mFadeDurationMs >= 0