mirror of
https://github.com/zoriya/react-native-svg.git
synced 2026-06-09 09:27:20 +00:00
Refactor extractGradient, simplify RNSVGCGGradient conversion, prettier
This commit is contained in:
+1
-1
@@ -6,7 +6,7 @@ class Shape extends Component {
|
||||
super(...arguments);
|
||||
for (let key of Object.keys(SvgTouchableMixin)) {
|
||||
const method = SvgTouchableMixin[key];
|
||||
if (typeof method === 'function') {
|
||||
if (typeof method === "function") {
|
||||
this[key] = method.bind(this);
|
||||
} else {
|
||||
this[key] = method;
|
||||
|
||||
+5
-2
@@ -89,7 +89,10 @@ class Svg extends Shape {
|
||||
onLayout,
|
||||
...props
|
||||
} = this.props;
|
||||
const stylesAndProps = { ...(style && style.length ? Object.assign({}, ...style) : style), ...props };
|
||||
const stylesAndProps = {
|
||||
...(style && style.length ? Object.assign({}, ...style) : style),
|
||||
...props,
|
||||
};
|
||||
const { color, width, height } = stylesAndProps;
|
||||
|
||||
let dimensions;
|
||||
@@ -125,7 +128,7 @@ class Svg extends Shape {
|
||||
dimensions,
|
||||
]}
|
||||
>
|
||||
<G style={style} {...(pick(stylesAndProps, gProps))}>
|
||||
<G style={style} {...pick(stylesAndProps, gProps)}>
|
||||
{children}
|
||||
</G>
|
||||
</NativeSvgView>
|
||||
|
||||
@@ -176,7 +176,7 @@ void PatternFunction(void* info, CGContextRef context)
|
||||
- (void)paintLinearGradient:(CGContextRef)context bounds:(CGRect)bounds
|
||||
{
|
||||
|
||||
CGGradientRef gradient = CGGradientRetain([RCTConvert RNSVGCGGradient:_colors offset:0]);
|
||||
CGGradientRef gradient = CGGradientRetain([RCTConvert RNSVGCGGradient:_colors]);
|
||||
CGGradientDrawingOptions extendOptions = kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation;
|
||||
|
||||
CGRect rect = [self getPaintRect:context bounds:bounds];
|
||||
@@ -206,7 +206,7 @@ void PatternFunction(void* info, CGContextRef context)
|
||||
|
||||
- (void)paintRadialGradient:(CGContextRef)context bounds:(CGRect)bounds
|
||||
{
|
||||
CGGradientRef gradient = CGGradientRetain([RCTConvert RNSVGCGGradient:_colors offset:0]);
|
||||
CGGradientRef gradient = CGGradientRetain([RCTConvert RNSVGCGGradient:_colors]);
|
||||
CGGradientDrawingOptions extendOptions = kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation;
|
||||
|
||||
CGRect rect = [self getPaintRect:context bounds:bounds];
|
||||
|
||||
@@ -29,6 +29,6 @@
|
||||
+ (RNSVGPathParser *)RNSVGCGPath:(NSString *)d;
|
||||
+ (CGRect)RNSVGCGRect:(id)json offset:(NSUInteger)offset;
|
||||
+ (CGColorRef)RNSVGCGColor:(id)json offset:(NSUInteger)offset;
|
||||
+ (CGGradientRef)RNSVGCGGradient:(id)json offset:(NSUInteger)offset;
|
||||
+ (CGGradientRef)RNSVGCGGradient:(id)json;
|
||||
|
||||
@end
|
||||
|
||||
@@ -33,25 +33,6 @@ RCT_ENUM_CONVERTER(RNSVGUnits, (@{
|
||||
@"userSpaceOnUse": @(kRNSVGUnitsUserSpaceOnUse),
|
||||
}), kRNSVGUnitsObjectBoundingBox, intValue)
|
||||
|
||||
+ (CGFloat*)RNSVGCGFloatArray:(id)json
|
||||
{
|
||||
NSArray *arr = [self NSNumberArray:json];
|
||||
NSUInteger count = arr.count;
|
||||
|
||||
CGFloat* array = nil;
|
||||
|
||||
if (count) {
|
||||
// Ideally, these arrays should already use the same memory layout.
|
||||
// In that case we shouldn't need this new malloc.
|
||||
array = malloc(sizeof(CGFloat) * count);
|
||||
for (NSUInteger i = 0; i < count; i++) {
|
||||
array[i] = (CGFloat)[arr[i] doubleValue];
|
||||
}
|
||||
}
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
+ (RNSVGBrush *)RNSVGBrush:(id)json
|
||||
{
|
||||
if ([json isKindOfClass:[NSString class]]) {
|
||||
@@ -151,28 +132,29 @@ RCT_ENUM_CONVERTER(RNSVGUnits, (@{
|
||||
return [self CGColor:[arr subarrayWithRange:(NSRange){offset, 4}]];
|
||||
}
|
||||
|
||||
+ (CGGradientRef)RNSVGCGGradient:(id)json offset:(NSUInteger)offset
|
||||
+ (CGGradientRef)RNSVGCGGradient:(id)json
|
||||
{
|
||||
NSArray *arr = [self NSArray:json];
|
||||
if (arr.count < offset) {
|
||||
NSArray *arr = [self NSNumberArray:json];
|
||||
NSUInteger count = arr.count;
|
||||
if (count < 5) {
|
||||
RCTLogError(@"Too few elements in array (expected at least %zd): %@", (unsigned long)offset, arr);
|
||||
return nil;
|
||||
}
|
||||
arr = [arr subarrayWithRange:(NSRange){offset, arr.count - offset}];
|
||||
CGFloat* colorsAndOffsets = [self RNSVGCGFloatArray:arr];
|
||||
size_t stops = arr.count / 5;
|
||||
|
||||
CGFloat colorsAndOffsets[count];
|
||||
for (NSUInteger i = 0; i < count; i++) {
|
||||
colorsAndOffsets[i] = (CGFloat)[arr[i] doubleValue];
|
||||
}
|
||||
|
||||
size_t stops = count / 5;
|
||||
CGColorSpaceRef rgb = CGColorSpaceCreateDeviceRGB();
|
||||
|
||||
|
||||
CGGradientRef gradient = CGGradientCreateWithColorComponents(
|
||||
rgb,
|
||||
colorsAndOffsets,
|
||||
colorsAndOffsets + stops * 4,
|
||||
stops
|
||||
);
|
||||
|
||||
CGColorSpaceRelease(rgb);
|
||||
free(colorsAndOffsets);
|
||||
return (CGGradientRef)CFAutorelease(gradient);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ export default {
|
||||
} else {
|
||||
return Touchable.Mixin.touchableHandleStartShouldSetResponder.call(
|
||||
this,
|
||||
e
|
||||
e,
|
||||
);
|
||||
}
|
||||
},
|
||||
@@ -22,7 +22,7 @@ export default {
|
||||
} else {
|
||||
return Touchable.Mixin.touchableHandleResponderTerminationRequest.call(
|
||||
this,
|
||||
e
|
||||
e,
|
||||
);
|
||||
}
|
||||
},
|
||||
@@ -49,7 +49,7 @@ export default {
|
||||
} else {
|
||||
return Touchable.Mixin.touchableHandleResponderRelease.call(
|
||||
this,
|
||||
e
|
||||
e,
|
||||
);
|
||||
}
|
||||
},
|
||||
@@ -60,7 +60,7 @@ export default {
|
||||
} else {
|
||||
return Touchable.Mixin.touchableHandleResponderTerminate.call(
|
||||
this,
|
||||
e
|
||||
e,
|
||||
);
|
||||
}
|
||||
},
|
||||
@@ -101,5 +101,5 @@ export default {
|
||||
|
||||
touchableGetPressOutDelayMS: function() {
|
||||
return this.props.delayPressOut || 0;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
@@ -22,66 +22,41 @@ function percentToFloat(percent) {
|
||||
return matched[2] ? matched[1] / 100 : +matched[1];
|
||||
}
|
||||
|
||||
function compareAscending(value, other) {
|
||||
if (value !== other) {
|
||||
if (value > other) {
|
||||
return 1;
|
||||
}
|
||||
if (value < other) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
const offsetComparator = (object, other) => compareAscending(object.offset, other.offset);
|
||||
const offsetComparator = (object, other) => object[0] - other[0];
|
||||
|
||||
export default function(props) {
|
||||
if (!props.id) {
|
||||
const { id, children, gradientTransform, transform, gradientUnits } = props;
|
||||
if (!id) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const stops = [];
|
||||
Children.forEach(
|
||||
props.children,
|
||||
({ props: { offset, stopColor, stopOpacity } }) => {
|
||||
offset = percentToFloat(offset);
|
||||
if (stopColor && !isNaN(offset)) {
|
||||
//noinspection JSUnresolvedFunction
|
||||
stops.push({
|
||||
stop: Color(stopColor).alpha(extractOpacity(stopOpacity)),
|
||||
offset,
|
||||
});
|
||||
}
|
||||
},
|
||||
);
|
||||
for (let child of Children.toArray(children)) {
|
||||
const { props: { offset, stopColor, stopOpacity } } = child;
|
||||
const offsetNumber = percentToFloat(offset);
|
||||
if (stopColor && !isNaN(offsetNumber)) {
|
||||
//noinspection JSUnresolvedFunction
|
||||
const color = Color(stopColor).alpha(extractOpacity(stopOpacity));
|
||||
const [r, g, b, a = 1] = color.rgb().array();
|
||||
stops.push([offsetNumber, [r / 255, g / 255, b / 255, a]]);
|
||||
}
|
||||
}
|
||||
stops.sort(offsetComparator);
|
||||
|
||||
const gradient = [];
|
||||
|
||||
stops.forEach(({ stop }) => {
|
||||
const [r, g, b, a = 1] = stop.rgb().array();
|
||||
gradient.push(r / 255);
|
||||
gradient.push(g / 255);
|
||||
gradient.push(b / 255);
|
||||
gradient.push(a);
|
||||
});
|
||||
|
||||
gradient.push(...stops.map(({ offset }) => offset));
|
||||
|
||||
let gradientTransform;
|
||||
if (props.gradientTransform) {
|
||||
gradientTransform = extractTransform(props.gradientTransform);
|
||||
} else if (props.transform) {
|
||||
gradientTransform = extractTransform(props.transform);
|
||||
} else {
|
||||
gradientTransform = extractTransform(props);
|
||||
for (let stop of stops) {
|
||||
gradient.push(...stop[1]);
|
||||
}
|
||||
for (let stop of stops) {
|
||||
gradient.push(stop[0]);
|
||||
}
|
||||
|
||||
const gt = extractTransform(gradientTransform || transform || props);
|
||||
|
||||
return {
|
||||
gradient,
|
||||
name: props.id,
|
||||
gradientTransform,
|
||||
gradientUnits: units[props.gradientUnits] || 0,
|
||||
name: id,
|
||||
gradientTransform: gt,
|
||||
gradientUnits: units[gradientUnits] || 0,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import { PanResponder } from "react-native";
|
||||
|
||||
const responderProps = [
|
||||
...Object.keys(PanResponder.create({}).panHandlers),
|
||||
"pointerEvents"
|
||||
"pointerEvents",
|
||||
];
|
||||
|
||||
const touchableProps = [
|
||||
|
||||
@@ -86,8 +86,12 @@ export function props2transform(props) {
|
||||
const [skewX, skewY] = universal2axis(props.skew, props.skewX, props.skewY);
|
||||
const [translateX, translateY] = universal2axis(
|
||||
props.translate,
|
||||
props.translateX === undefined || props.translateX === null ? props.x || 0 : props.translateX,
|
||||
props.translateY === undefined || props.translateY === null ? props.y || 0 : props.translateY,
|
||||
props.translateX === undefined || props.translateX === null
|
||||
? props.x || 0
|
||||
: props.translateX,
|
||||
props.translateY === undefined || props.translateY === null
|
||||
? props.y || 0
|
||||
: props.translateY,
|
||||
);
|
||||
|
||||
return {
|
||||
|
||||
@@ -29,9 +29,12 @@ export default function(props) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const params = viewBox.trim().split(spacesRegExp);
|
||||
const params = viewBox
|
||||
.trim()
|
||||
.split(spacesRegExp)
|
||||
.map(Number);
|
||||
|
||||
if (params.length === 4 && params.some(param => isNaN(+param))) {
|
||||
if (params.length === 4 && params.some(isNaN)) {
|
||||
console.warn("Invalid `viewBox` prop:" + viewBox);
|
||||
return null;
|
||||
}
|
||||
@@ -42,12 +45,13 @@ export default function(props) {
|
||||
|
||||
const meetOrSlice = meetOrSliceTypes[modes[1]] || 0;
|
||||
const align = alignEnum[modes[0]] || "xMidYMid";
|
||||
const [minX, minY, vbWidth, vbHeight] = params;
|
||||
|
||||
return {
|
||||
minX: +params[0],
|
||||
minY: +params[1],
|
||||
vbWidth: +params[2],
|
||||
vbHeight: +params[3],
|
||||
minX,
|
||||
minY,
|
||||
vbWidth,
|
||||
vbHeight,
|
||||
align,
|
||||
meetOrSlice,
|
||||
};
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
export default {
|
||||
objectBoundingBox: 0,
|
||||
userSpaceOnUse: 1
|
||||
userSpaceOnUse: 1,
|
||||
};
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
|
||||
// eslint-disable-next-line eqeqeq
|
||||
export const notNil = a => a != null;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user