mirror of
https://github.com/zoriya/react-native-svg.git
synced 2026-06-01 06:07:41 +00:00
Support PlatformColor (#1561)
Since version 0.63 React Native has supported PlatformColor structs that among other features has dark mode support built in. Using those values with RNSVG today throws a warning "[Object object]" is not a valid color or brush and makes the path have a clear color. This PR adds support for PlatformColor by utilizing the color parsing code shipped with React Native itself. In order to support the dynamic properties I had to retain the reference as a UIColor and convert it to CGColorRef as it's read. This might have a performance penalty. The Android implementation doesn't yet have support for dynamic values (EDIT: react-native itself doesn't support it, so we're good there I think). Since it relies on the ColorPropConverter class, I think it means minimum supported version of RN will be raised to 0.63.
This commit is contained in:
@@ -27,6 +27,7 @@ import com.facebook.react.bridge.JavaOnlyArray;
|
||||
import com.facebook.react.bridge.ReactContext;
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
import com.facebook.react.bridge.ReadableType;
|
||||
import com.facebook.react.bridge.ColorPropConverter;
|
||||
import com.facebook.react.uimanager.PointerEvents;
|
||||
import com.facebook.react.uimanager.annotations.ReactProp;
|
||||
|
||||
@@ -474,7 +475,12 @@ abstract public class RenderableView extends VirtualView {
|
||||
switch (colorType) {
|
||||
case 0:
|
||||
if (colors.size() == 2) {
|
||||
int color = colors.getInt(1);
|
||||
int color;
|
||||
if (colors.getType(1) == ReadableType.Map) {
|
||||
color = ColorPropConverter.getColor(colors.getMap(1), getContext());
|
||||
} else {
|
||||
color = colors.getInt(1);
|
||||
}
|
||||
int alpha = color >>> 24;
|
||||
int combined = Math.round((float)alpha * opacity);
|
||||
paint.setColor(combined << 24 | (color & 0x00ffffff));
|
||||
|
||||
@@ -13,13 +13,13 @@
|
||||
|
||||
@implementation RNSVGSolidColorBrush
|
||||
{
|
||||
CGColorRef _color;
|
||||
UIColor *_color;
|
||||
}
|
||||
|
||||
- (instancetype)initWithArray:(NSArray<RNSVGLength *> *)array
|
||||
{
|
||||
if ((self = [super initWithArray:array])) {
|
||||
_color = CGColorRetain([RCTConvert RNSVGCGColor:array offset:1]);
|
||||
_color = [RCTConvert RNSVGUIColor:array offset:1];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
@@ -27,34 +27,35 @@
|
||||
- (instancetype)initWithNumber:(NSNumber *)number
|
||||
{
|
||||
if ((self = [super init])) {
|
||||
_color = CGColorRetain([RCTConvert CGColor:number]);
|
||||
_color = [RCTConvert UIColor:number];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
CGColorRelease(_color);
|
||||
_color = nil;
|
||||
}
|
||||
|
||||
- (CGColorRef)getColorWithOpacity:(CGFloat)opacity
|
||||
{
|
||||
return CGColorCreateCopyWithAlpha(_color, opacity * CGColorGetAlpha(_color));
|
||||
CGColorRef baseColor = _color.CGColor;
|
||||
CGColorRef color = CGColorCreateCopyWithAlpha(baseColor, opacity * CGColorGetAlpha(baseColor));
|
||||
CGColorRelease(baseColor);
|
||||
return color;
|
||||
}
|
||||
|
||||
- (BOOL)applyFillColor:(CGContextRef)context opacity:(CGFloat)opacity
|
||||
{
|
||||
CGColorRef color = CGColorCreateCopyWithAlpha(_color, opacity * CGColorGetAlpha(_color));
|
||||
CGColorRef color = [self getColorWithOpacity:opacity];
|
||||
CGContextSetFillColorWithColor(context, color);
|
||||
CGColorRelease(color);
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (BOOL)applyStrokeColor:(CGContextRef)context opacity:(CGFloat)opacity
|
||||
{
|
||||
CGColorRef color = CGColorCreateCopyWithAlpha(_color, opacity * CGColorGetAlpha(_color));
|
||||
CGColorRef color = [self getColorWithOpacity:opacity];
|
||||
CGContextSetStrokeColorWithColor(context, color);
|
||||
CGColorRelease(color);
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
+ (RNSVGBrush *)RNSVGBrush:(id)json;
|
||||
+ (RNSVGPathParser *)RNSVGCGPath:(NSString *)d;
|
||||
+ (CGRect)RNSVGCGRect:(id)json offset:(NSUInteger)offset;
|
||||
+ (CGColorRef)RNSVGCGColor:(id)json offset:(NSUInteger)offset;
|
||||
+ (UIColor *)RNSVGUIColor:(id)json offset:(NSUInteger)offset;
|
||||
+ (CGGradientRef)RNSVGCGGradient:(id)json;
|
||||
|
||||
@end
|
||||
|
||||
@@ -130,17 +130,17 @@ RCT_ENUM_CONVERTER(RNSVGUnits, (@{
|
||||
};
|
||||
}
|
||||
|
||||
+ (CGColorRef)RNSVGCGColor:(id)json offset:(NSUInteger)offset
|
||||
+ (UIColor *)RNSVGUIColor:(id)json offset:(NSUInteger)offset
|
||||
{
|
||||
NSArray *arr = [self NSArray:json];
|
||||
if (arr.count == offset + 1) {
|
||||
return [self CGColor:[arr objectAtIndex:offset]];
|
||||
return [self UIColor:[arr objectAtIndex:offset]];
|
||||
}
|
||||
if (arr.count < offset + 4) {
|
||||
RCTLogError(@"Too few elements in array (expected at least %zd): %@", (ssize_t)(4 + offset), arr);
|
||||
return nil;
|
||||
}
|
||||
return [self CGColor:[arr subarrayWithRange:(NSRange){offset, 4}]];
|
||||
return [self UIColor:[arr subarrayWithRange:(NSRange){offset, 4}]];
|
||||
}
|
||||
|
||||
+ (CGGradientRef)RNSVGCGGradient:(id)json
|
||||
|
||||
Vendored
+2
-2
@@ -1,6 +1,6 @@
|
||||
import * as React from 'react';
|
||||
import * as ReactNative from 'react-native';
|
||||
import { GestureResponderEvent, TransformsStyle } from 'react-native';
|
||||
import { GestureResponderEvent, TransformsStyle, OpaqueColorValue } from 'react-native';
|
||||
|
||||
// Common props
|
||||
export type NumberProp = string | number;
|
||||
@@ -101,7 +101,7 @@ export type rgbaArray = ReadonlyArray<number>;
|
||||
// int32ARGBColor = 0xaarrggbb
|
||||
export type int32ARGBColor = number;
|
||||
|
||||
export type Color = int32ARGBColor | rgbaArray | string;
|
||||
export type Color = int32ARGBColor | rgbaArray | OpaqueColorValue | string;
|
||||
|
||||
export interface FillProps {
|
||||
fill?: Color;
|
||||
|
||||
@@ -40,6 +40,16 @@ export default function extractBrush(color?: Color) {
|
||||
return int32ARGBColor;
|
||||
}
|
||||
|
||||
// iOS PlatformColor
|
||||
if ('semantic' in color) {
|
||||
return [0, color];
|
||||
}
|
||||
|
||||
// Android PlatformColor
|
||||
if ('resource_paths' in color) {
|
||||
return [0, color];
|
||||
}
|
||||
|
||||
console.warn(`"${color}" is not a valid color or brush`);
|
||||
return null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user