From c0eee17ed7739eef2376b19994b3c1885efa9b42 Mon Sep 17 00:00:00 2001 From: Alan Kenyon Date: Thu, 5 Dec 2019 15:54:34 -0800 Subject: [PATCH 1/8] shadows on both android and ios --- .../art/ARTShapeShadowNode.java | 6 +++++ .../art/ARTTextShadowNode.java | 3 +++ .../art/ARTVirtualNode.java | 23 ++++++++++++++++ example/components/CustomText.js | 12 ++++++++- example/components/Heart.js | 8 ++++++ ios/ART.xcodeproj/project.pbxproj | 3 +++ ios/ARTNode.h | 3 ++- ios/ARTNode.m | 22 ++++++++++----- ios/ARTShadow.h | 12 +++++++++ ios/RCTConvert+ART.h | 2 ++ ios/RCTConvert+ART.m | 17 ++++++++++++ ios/ViewManagers/ARTNodeManager.m | 1 + lib/ClippingRectangle.js | 5 ++-- lib/Group.js | 8 +++--- lib/Shape.js | 4 +++ lib/Text.js | 4 +++ lib/helpers.js | 27 +++++++++++++++++++ lib/types.js | 7 +++++ 18 files changed, 154 insertions(+), 13 deletions(-) create mode 100644 ios/ARTShadow.h diff --git a/android/src/main/java/com/reactnativecommunity/art/ARTShapeShadowNode.java b/android/src/main/java/com/reactnativecommunity/art/ARTShapeShadowNode.java index 5da3828..cf57bbb 100644 --- a/android/src/main/java/com/reactnativecommunity/art/ARTShapeShadowNode.java +++ b/android/src/main/java/com/reactnativecommunity/art/ARTShapeShadowNode.java @@ -167,6 +167,9 @@ protected boolean setupStrokePaint(Paint paint, float opacity) { if (mStrokeDash != null && mStrokeDash.length > 0) { paint.setPathEffect(new DashPathEffect(mStrokeDash, 0)); } + if (mShadowOpacity > 0) { + paint.setShadowLayer(mShadowRadius, mShadowOffsetX, mShadowOffsetY, mShadowColor); + } return true; } @@ -231,6 +234,9 @@ protected boolean setupFillPaint(Paint paint, float opacity) { default: FLog.w(ReactConstants.TAG, "ART: Color type " + colorType + " not supported!"); } + if (mShadowOpacity > 0) { + paint.setShadowLayer(mShadowRadius, mShadowOffsetX, mShadowOffsetY, mShadowColor); + } return true; } return false; diff --git a/android/src/main/java/com/reactnativecommunity/art/ARTTextShadowNode.java b/android/src/main/java/com/reactnativecommunity/art/ARTTextShadowNode.java index bd79fb6..55a4b20 100644 --- a/android/src/main/java/com/reactnativecommunity/art/ARTTextShadowNode.java +++ b/android/src/main/java/com/reactnativecommunity/art/ARTTextShadowNode.java @@ -92,6 +92,9 @@ public void draw(Canvas canvas, Paint paint, float opacity) { canvas.drawTextOnPath(text, mPath, 0, 0, paint); } } + if (mShadowOpacity > 0) { + paint.setShadowLayer(mShadowRadius, mShadowOffsetX, mShadowOffsetY, mShadowColor); + } restoreCanvas(canvas); markUpdateSeen(); } diff --git a/android/src/main/java/com/reactnativecommunity/art/ARTVirtualNode.java b/android/src/main/java/com/reactnativecommunity/art/ARTVirtualNode.java index f3cf624..34b7bec 100644 --- a/android/src/main/java/com/reactnativecommunity/art/ARTVirtualNode.java +++ b/android/src/main/java/com/reactnativecommunity/art/ARTVirtualNode.java @@ -30,6 +30,11 @@ public abstract class ARTVirtualNode extends ReactShadowNodeImpl { protected float mOpacity = 1f; private @Nullable Matrix mMatrix = new Matrix(); + protected int mShadowColor = 0; + protected float mShadowOpacity = 1; + protected float mShadowRadius = 0; + protected float mShadowOffsetX = 0; + protected float mShadowOffsetY = 0; protected final float mScale; @@ -91,6 +96,24 @@ public void setTransform(@Nullable ReadableArray transformArray) { markUpdated(); } + @ReactProp(name = "shadow") + public void setShadow(@Nullable ReadableArray shadowArray) { + if (shadowArray != null) { + mShadowColor = shadowArray.getInt(0); + mShadowOpacity = (float)shadowArray.getDouble(1); + mShadowRadius = (float)shadowArray.getDouble(2); + mShadowOffsetX = (float)shadowArray.getDouble(3); + mShadowOffsetY = (float)shadowArray.getDouble(4); + } else { + mShadowColor = 0; + mShadowOpacity = 0; + mShadowRadius = 0; + mShadowOffsetX = 0; + mShadowOffsetY = 0; + } + markUpdated(); + } + protected void setupMatrix() { sRawMatrix[0] = sMatrixData[0]; sRawMatrix[1] = sMatrixData[2]; diff --git a/example/components/CustomText.js b/example/components/CustomText.js index 7d1b6de..78cf264 100644 --- a/example/components/CustomText.js +++ b/example/components/CustomText.js @@ -2,6 +2,13 @@ import React from 'react'; import {Dimensions, StyleSheet} from 'react-native'; import {Surface, Text, Group} from '@react-native-community/art'; +const SHADOW = { + shadowOpacity: 0.5, + shadowColor: 'blue', + shadowRadius: 10, + shadowOffset: {x: 4, y: 4}, +}; + export default function CustomText() { const surfaceWidth = Dimensions.get('window').width; const surfaceHeight = surfaceWidth / 3; @@ -9,7 +16,10 @@ export default function CustomText() { return ( - + React Native Community diff --git a/example/components/Heart.js b/example/components/Heart.js index e9321c3..5e4667c 100644 --- a/example/components/Heart.js +++ b/example/components/Heart.js @@ -11,6 +11,13 @@ import { const HEART_SHAPE = 'M 10,30 A 20,20 0,0,1 50,30 A 20,20 0,0,1 90,30 Q 90,60 50,90 Q 10,60 10,30 z'; +const SHADOW = { + shadowOpacity: 1, + shadowColor: 'red', + shadowRadius: 8, + shadowOffset: {x: 0, y: 0}, +}; + export default function Heart() { const surfaceDimensions = Dimensions.get('window').width; const gradient = new RadialGradient( @@ -42,6 +49,7 @@ export default function Heart() { stroke={'#00ff00'} fill={gradient} visible={true} + {...SHADOW} /> diff --git a/ios/ART.xcodeproj/project.pbxproj b/ios/ART.xcodeproj/project.pbxproj index 2aec17b..732f450 100644 --- a/ios/ART.xcodeproj/project.pbxproj +++ b/ios/ART.xcodeproj/project.pbxproj @@ -67,6 +67,7 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 09966EAF23996E3900E9C452 /* ARTShadow.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ARTShadow.h; sourceTree = ""; }; 0CF68AC11AF0540F00FF9E5C /* libART.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libART.a; sourceTree = BUILT_PRODUCTS_DIR; }; 0CF68ADB1AF0549300FF9E5C /* ARTCGFloatArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTCGFloatArray.h; sourceTree = ""; }; 0CF68ADC1AF0549300FF9E5C /* ARTContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTContainer.h; sourceTree = ""; }; @@ -131,6 +132,7 @@ 0CF68AB81AF0540F00FF9E5C = { isa = PBXGroup; children = ( + 09966EAF23996E3900E9C452 /* ARTShadow.h */, 0CF68AEA1AF0549300FF9E5C /* Brushes */, 0CF68AF81AF0549300FF9E5C /* ViewManagers */, 0CF68ADB1AF0549300FF9E5C /* ARTCGFloatArray.h */, @@ -261,6 +263,7 @@ developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( + English, en, ); mainGroup = 0CF68AB81AF0540F00FF9E5C; diff --git a/ios/ARTNode.h b/ios/ARTNode.h index 9f38111..8c6a7a6 100644 --- a/ios/ARTNode.h +++ b/ios/ARTNode.h @@ -6,7 +6,7 @@ */ #import - +#import "ARTShadow.h" /** * ART nodes are implemented as empty UIViews but this is just an implementation detail to fit * into the existing view management. They should also be shadow views and painted on a background @@ -16,6 +16,7 @@ @interface ARTNode : UIView @property (nonatomic, assign) CGFloat opacity; +@property (nonatomic, assign) ARTShadow shadow; - (void)invalidate; - (void)renderTo:(CGContextRef)context; diff --git a/ios/ARTNode.m b/ios/ARTNode.m index ae1a152..b75a4ee 100644 --- a/ios/ARTNode.m +++ b/ios/ARTNode.m @@ -41,6 +41,12 @@ - (void)setTransform:(CGAffineTransform)transform super.transform = transform; } +- (void)setShadow:(ARTShadow)shadow +{ + [self invalidate]; + _shadow = shadow; +} + - (void)invalidate { id container = (id)self.superview; @@ -55,23 +61,27 @@ - (void)renderTo:(CGContextRef)context } if (self.opacity >= 1) { // Just paint at full opacity - CGContextSaveGState(context); - CGContextConcatCTM(context, self.transform); - CGContextSetAlpha(context, 1); + [self renderContentTo:context]; [self renderLayerTo:context]; CGContextRestoreGState(context); return; } + // This needs to be painted on a layer before being composited. - CGContextSaveGState(context); - CGContextConcatCTM(context, self.transform); - CGContextSetAlpha(context, self.opacity); + [self renderContentTo:context]; CGContextBeginTransparencyLayer(context, NULL); [self renderLayerTo:context]; CGContextEndTransparencyLayer(context); CGContextRestoreGState(context); } +- (void)renderContentTo:(CGContextRef)context { + CGContextSaveGState(context); + CGContextConcatCTM(context, self.transform); + CGContextSetAlpha(context, self.opacity); + CGContextSetShadowWithColor(context, self.shadow.offset, self.shadow.blur, self.shadow.color.CGColor); +} + - (void)renderLayerTo:(CGContextRef)context { // abstract diff --git a/ios/ARTShadow.h b/ios/ARTShadow.h new file mode 100644 index 0000000..d45a554 --- /dev/null +++ b/ios/ARTShadow.h @@ -0,0 +1,12 @@ +// +// ARTShadow.h +// ART +// +// Created by Alan Kenyon on 12/5/19. +// + +typedef struct { + CGSize offset; + CGFloat blur; + UIColor* color; +} ARTShadow; diff --git a/ios/RCTConvert+ART.h b/ios/RCTConvert+ART.h index 5fe3b4e..74b35df 100644 --- a/ios/RCTConvert+ART.h +++ b/ios/RCTConvert+ART.h @@ -10,6 +10,7 @@ #import #import "ARTBrush.h" +#import "ARTShadow.h" #import "ARTCGFloatArray.h" #import "ARTTextFrame.h" @@ -20,6 +21,7 @@ + (ARTTextFrame)ARTTextFrame:(id)json; + (ARTCGFloatArray)ARTCGFloatArray:(id)json; + (ARTBrush *)ARTBrush:(id)json; ++ (ARTShadow)ARTShadow:(id)json; + (CGPoint)CGPoint:(id)json offset:(NSUInteger)offset; + (CGRect)CGRect:(id)json offset:(NSUInteger)offset; diff --git a/ios/RCTConvert+ART.m b/ios/RCTConvert+ART.m index 3312e31..cbcfdcd 100644 --- a/ios/RCTConvert+ART.m +++ b/ios/RCTConvert+ART.m @@ -161,6 +161,23 @@ + (ARTBrush *)ARTBrush:(id)json } } ++ (ARTShadow)ARTShadow:(id)json +{ + NSArray *arr = [self NSArray:json]; + + UIColor *color = [UIColor colorWithCGColor:[self CGColor:[arr objectAtIndex:0]]]; + color = [color colorWithAlphaComponent:[[arr objectAtIndex:1] floatValue]]; + + return (ARTShadow){ + .color = color, + .blur = [[arr objectAtIndex:2] floatValue], + .offset = (CGSize){ + .width = [[arr objectAtIndex:3] floatValue], + .height = [[arr objectAtIndex:4] floatValue] + }, + }; +} + + (CGPoint)CGPoint:(id)json offset:(NSUInteger)offset { NSArray *arr = [self NSArray:json]; diff --git a/ios/ViewManagers/ARTNodeManager.m b/ios/ViewManagers/ARTNodeManager.m index 6268097..c0c745d 100644 --- a/ios/ViewManagers/ARTNodeManager.m +++ b/ios/ViewManagers/ARTNodeManager.m @@ -30,5 +30,6 @@ - (RCTShadowView *)shadowView RCT_EXPORT_VIEW_PROPERTY(opacity, CGFloat) RCT_EXPORT_VIEW_PROPERTY(transform, CGAffineTransform) +RCT_EXPORT_VIEW_PROPERTY(shadow, ARTShadow) @end diff --git a/lib/ClippingRectangle.js b/lib/ClippingRectangle.js index 9f6b090..ef9acad 100644 --- a/lib/ClippingRectangle.js +++ b/lib/ClippingRectangle.js @@ -9,7 +9,7 @@ import * as React from 'react'; import merge from 'react-native/Libraries/vendor/core/merge'; -import {extractOpacity, extractTransform} from './helpers'; +import {extractOpacity, extractTransform, extractShadow} from './helpers'; import {NativeGroup} from './nativeComponents'; import type {OpacityProps} from './types'; @@ -44,7 +44,8 @@ export default class ClippingRectangle extends React.Component + transform={extractTransform(propsExcludingXAndY)} + shadow={extractShadow(this.props)}> {this.props.children} ); diff --git a/lib/Group.js b/lib/Group.js index 24d32dc..a4bb485 100644 --- a/lib/Group.js +++ b/lib/Group.js @@ -11,10 +11,11 @@ import * as React from 'react'; import PropTypes from 'prop-types'; import invariant from 'invariant'; import {NativeGroup} from './nativeComponents'; -import {extractOpacity, extractTransform} from './helpers'; -import type {OpacityProps, TransformProps} from './types'; +import {extractOpacity, extractTransform, extractShadow} from './helpers'; +import type {OpacityProps, TransformProps, ShadowProps} from './types'; type GroupProps = OpacityProps & + ShadowProps & TransformProps & { children: React.Node, }; @@ -33,7 +34,8 @@ export default class Group extends React.Component { return ( + transform={extractTransform(this.props)} + shadow={extractShadow(this.props)}> {this.props.children} ); diff --git a/lib/Shape.js b/lib/Shape.js index fe2acea..a7c3dc1 100644 --- a/lib/Shape.js +++ b/lib/Shape.js @@ -12,6 +12,7 @@ import {NativeShape} from './nativeComponents'; import Path from './ARTSerializablePath'; import { extractTransform, + extractShadow, extractOpacity, childrenAsString, extractColor, @@ -21,6 +22,7 @@ import { } from './helpers'; import type { TransformProps, + ShadowProps, OpacityProps, StrokeJoin, StrokeCap, @@ -28,6 +30,7 @@ import type { } from './types'; export type ShapeProps = TransformProps & + ShadowProps & OpacityProps & { fill?: string | Brush, stroke?: string, @@ -64,6 +67,7 @@ export default class Shape extends React.Component { strokeJoin={extractStrokeJoin(props.strokeJoin)} strokeWidth={props.strokeWidth} transform={extractTransform(props)} + shadow={extractShadow(this.props)} d={d} /> ); diff --git a/lib/Text.js b/lib/Text.js index 55ee318..5615a71 100644 --- a/lib/Text.js +++ b/lib/Text.js @@ -17,12 +17,14 @@ import { extractStrokeCap, extractStrokeJoin, extractTransform, + extractShadow, extractAlignment, childrenAsString, extractFontAndLines, } from './helpers'; import type { TransformProps, + ShadowProps, OpacityProps, Alignment, Brush, @@ -32,6 +34,7 @@ import type { } from './types'; export type TextProps = TransformProps & + ShadowProps & OpacityProps & { fill?: string | Brush, stroke?: string, @@ -75,6 +78,7 @@ export default class Text extends React.Component { strokeWidth={props.strokeWidth} transform={extractTransform(props)} alignment={extractAlignment(props.alignment)} + shadow={extractShadow(this.props)} frame={textFrame} path={textPath} /> diff --git a/lib/helpers.js b/lib/helpers.js index 8514900..6f5debd 100644 --- a/lib/helpers.js +++ b/lib/helpers.js @@ -7,6 +7,7 @@ * @flow */ +import processColor from 'react-native/Libraries/StyleSheet/processColor'; import Color from 'art/core/color'; import Transform from 'art/core/transform'; import {Platform} from 'react-native'; @@ -20,6 +21,7 @@ import type { StrokeCap, StrokeJoin, TransformProps, + ShadowProps, } from './types'; export function childrenAsString(children?: string | Array) { @@ -89,6 +91,31 @@ function toHex(color: Color) { return '#' + hexValues.join(''); } +export function extractShadow(props: ShadowProps):Array { + if ( + !props.shadowColor && + !props.shadowOpacity && + !props.shadowRadius && + !props.shadowOffset + ) { + return; + } + + let opacity = props.shadowOpacity; + + if (opacity === null || opacity === undefined) { + opacity = 1; + } + + return [ + processColor(props.shadowColor || 'black'), + opacity, + props.shadowRadius || 4, + props.shadowOffset.x || 0, + props.shadowOffset.y || 0, + ]; +} + export function extractColor(color?: ColorType) { if (color == null) { return null; diff --git a/lib/types.js b/lib/types.js index 33692a0..50bae64 100644 --- a/lib/types.js +++ b/lib/types.js @@ -31,6 +31,13 @@ export type TransformProps = { }, }; +export type ShadowProps = { + shadowOpacity?: number, + shadowColor?: ColorType, + shadowRadius?: Number, + shadowOffset: {x: Number, y: Number}, +}; + export type ARTColor = { isColor: true, red: string, From 1d05712e1224b85f8ab4221077521e3cb2e9aae2 Mon Sep 17 00:00:00 2001 From: Alan Kenyon Date: Thu, 5 Dec 2019 15:55:18 -0800 Subject: [PATCH 2/8] update docs --- docs/api.md | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/docs/api.md b/docs/api.md index cd85e3a..85abba0 100644 --- a/docs/api.md +++ b/docs/api.md @@ -31,6 +31,7 @@ Container to combine shapes or other groups into hierarchies that can be transfo | :---------------: | :-----------------------------------: | :-----: | | ...opacityProps | [`OpacityProps`](###OpacityProps) | --- | | ...transformProps | [`TransformProps`](###TransformProps) | --- | +| ...shadowProps | [`ShadowProps`](###ShadowProps) | --- | | children | `React.Node` | --- | ```jsx @@ -53,7 +54,8 @@ Used to draw arbitrary vector shapes from Path. Shape implements Transform as a | :---------------: | :-----------------------------------: | :-------: | | ...opacityProps | [`OpacityProps`](###OpacityProps) | --- | | ...transformProps | [`TransformProps`](###TransformProps) | --- | -| fill | `string \| Brush` | --- | +| ...shadowProps | [`ShadowProps`](###ShadowProps) | --- | +| fill | `string \| Brush` | --- | | stroke | `string` | --- | | strokeCap | `'butt' \| 'square' \| 'round'` | `'round'` | | strokeDash | `Array` | --- | @@ -84,7 +86,8 @@ Text component creates a shape based on text content using native text rendering | :---------------: | :-----------------------------------: | :-------: | | ...opacityProps | [`OpacityProps`](###OpacityProps) | --- | | ...transformProps | [`TransformProps`](###TransformProps) | --- | -| fill | `string \| Brush` | --- | +| ...shadowProps | [`ShadowProps`](###ShadowProps) | --- | +| fill | `string \| Brush` | --- | | stroke | `string` | --- | | strokeCap | `'butt' \| 'square' \| 'round'` | `'round'` | | strokeDash | `Array` | --- | @@ -354,6 +357,22 @@ function Component() { | originY | `number` | --- | | transform | `TransformObject` | --- | +### ShadowProps + +| Prop | Type | Default | +| :-----------: | :------------------: | :------: | +| shadowOpacity | `number` | `1` | +| shadowColor | `string` | `black` | +| shadowRadius | `number` | `0` | +| shadowOffset | `ShadowOffsetObject` | --- | + +### ShadowOffsetObject + +| Prop | Type | Default | +| :--: | :------: | :-----: | +| y | `number` | `0` | +| x | `number` | `0` | + ### Font | Prop | Type | Default | From a1783f2c5b026dbc65e6de152723f008b1c198e8 Mon Sep 17 00:00:00 2001 From: Alan Kenyon Date: Thu, 5 Dec 2019 16:00:36 -0800 Subject: [PATCH 3/8] linter fix --- lib/helpers.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/helpers.js b/lib/helpers.js index 6f5debd..9fe4ce9 100644 --- a/lib/helpers.js +++ b/lib/helpers.js @@ -91,7 +91,9 @@ function toHex(color: Color) { return '#' + hexValues.join(''); } -export function extractShadow(props: ShadowProps):Array { +export function extractShadow( + props: ShadowProps, +): Array { if ( !props.shadowColor && !props.shadowOpacity && From aebb84f99cf1d2a69f47d3c0798a73228a0f361a Mon Sep 17 00:00:00 2001 From: Alan Kenyon Date: Fri, 6 Dec 2019 09:30:15 -0800 Subject: [PATCH 4/8] fix flow typings --- lib/ClippingRectangle.js | 18 ++++++++++-------- lib/helpers.js | 8 +++----- lib/types.js | 6 +++--- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/lib/ClippingRectangle.js b/lib/ClippingRectangle.js index ef9acad..39757ee 100644 --- a/lib/ClippingRectangle.js +++ b/lib/ClippingRectangle.js @@ -11,15 +11,17 @@ import * as React from 'react'; import merge from 'react-native/Libraries/vendor/core/merge'; import {extractOpacity, extractTransform, extractShadow} from './helpers'; import {NativeGroup} from './nativeComponents'; -import type {OpacityProps} from './types'; +import type {OpacityProps, TransformProps, ShadowProps} from './types'; -type ClippingRectangleProps = OpacityProps & { - x: number, - y: number, - width: number, - height: number, - children?: React.Node, -}; +type ClippingRectangleProps = OpacityProps & + TransformProps & + ShadowProps & { + x: number, + y: number, + width: number, + height: number, + children?: React.Node, + }; export default class ClippingRectangle extends React.Component { static defaultProps = { diff --git a/lib/helpers.js b/lib/helpers.js index 9fe4ce9..6e13e96 100644 --- a/lib/helpers.js +++ b/lib/helpers.js @@ -91,9 +91,7 @@ function toHex(color: Color) { return '#' + hexValues.join(''); } -export function extractShadow( - props: ShadowProps, -): Array { +export function extractShadow(props: ShadowProps): Array | void { if ( !props.shadowColor && !props.shadowOpacity && @@ -113,8 +111,8 @@ export function extractShadow( processColor(props.shadowColor || 'black'), opacity, props.shadowRadius || 4, - props.shadowOffset.x || 0, - props.shadowOffset.y || 0, + props.shadowOffset?.x || 0, + props.shadowOffset?.y || 0, ]; } diff --git a/lib/types.js b/lib/types.js index 50bae64..856de81 100644 --- a/lib/types.js +++ b/lib/types.js @@ -33,9 +33,9 @@ export type TransformProps = { export type ShadowProps = { shadowOpacity?: number, - shadowColor?: ColorType, - shadowRadius?: Number, - shadowOffset: {x: Number, y: Number}, + shadowColor?: string | number, + shadowRadius?: number, + shadowOffset?: {x: number, y: number}, }; export type ARTColor = { From e04b4c86d068f2ee8afcba4f4dc0383495c8678a Mon Sep 17 00:00:00 2001 From: Alan Kenyon Date: Fri, 6 Dec 2019 09:30:36 -0800 Subject: [PATCH 5/8] linter fixes --- lib/helpers.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/helpers.js b/lib/helpers.js index 6e13e96..4b30788 100644 --- a/lib/helpers.js +++ b/lib/helpers.js @@ -91,7 +91,9 @@ function toHex(color: Color) { return '#' + hexValues.join(''); } -export function extractShadow(props: ShadowProps): Array | void { +export function extractShadow( + props: ShadowProps, +): Array | void { if ( !props.shadowColor && !props.shadowOpacity && From b4be6e7bc923e27833a6e34f091a9eb54631b4c2 Mon Sep 17 00:00:00 2001 From: Alan Kenyon Date: Fri, 6 Dec 2019 12:24:55 -0800 Subject: [PATCH 6/8] forgot to include opacity --- .../reactnativecommunity/art/ARTVirtualNode.java | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/android/src/main/java/com/reactnativecommunity/art/ARTVirtualNode.java b/android/src/main/java/com/reactnativecommunity/art/ARTVirtualNode.java index 34b7bec..d2b4018 100644 --- a/android/src/main/java/com/reactnativecommunity/art/ARTVirtualNode.java +++ b/android/src/main/java/com/reactnativecommunity/art/ARTVirtualNode.java @@ -8,8 +8,11 @@ package com.reactnativecommunity.art; import android.graphics.Canvas; +import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Paint; +import android.support.v4.graphics.ColorUtils; + import com.facebook.react.bridge.JSApplicationIllegalArgumentException; import com.facebook.react.bridge.ReadableArray; import com.facebook.react.uimanager.DisplayMetricsHolder; @@ -99,11 +102,19 @@ public void setTransform(@Nullable ReadableArray transformArray) { @ReactProp(name = "shadow") public void setShadow(@Nullable ReadableArray shadowArray) { if (shadowArray != null) { - mShadowColor = shadowArray.getInt(0); mShadowOpacity = (float)shadowArray.getDouble(1); mShadowRadius = (float)shadowArray.getDouble(2); mShadowOffsetX = (float)shadowArray.getDouble(3); mShadowOffsetY = (float)shadowArray.getDouble(4); + + int color = shadowArray.getInt(0); + + if (mShadowOpacity < 1) { + color = ColorUtils.setAlphaComponent(color, (int)(mShadowOpacity * 255)); + } + + mShadowColor = color; + } else { mShadowColor = 0; mShadowOpacity = 0; From 8ddbab6e83ec2eb7b80ed849d9119503c97e60cd Mon Sep 17 00:00:00 2001 From: Alan Kenyon Date: Wed, 18 Dec 2019 11:16:43 -0500 Subject: [PATCH 7/8] update comment --- ios/ARTShadow.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/ios/ARTShadow.h b/ios/ARTShadow.h index d45a554..2aa5b48 100644 --- a/ios/ARTShadow.h +++ b/ios/ARTShadow.h @@ -1,9 +1,9 @@ -// -// ARTShadow.h -// ART -// -// Created by Alan Kenyon on 12/5/19. -// +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ typedef struct { CGSize offset; From 7cb460339142fe7ba80e9e6d8d009868af7d3e61 Mon Sep 17 00:00:00 2001 From: Alan Kenyon Date: Wed, 18 Dec 2019 13:11:58 -0500 Subject: [PATCH 8/8] update typscript definitions --- index.d.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/index.d.ts b/index.d.ts index 7811e18..98ed7e0 100644 --- a/index.d.ts +++ b/index.d.ts @@ -13,6 +13,13 @@ declare module '@react-native-community/art' { x?: number; y?: number; visible?: boolean; + shadowOpacity?: number; + shadowColor?: string | number; + shadowRadius?: number; + shadowOffset?: { + x: number, + y: number, + } } export interface ARTGroupProps extends ARTNodeMixin {