mirror of
https://github.com/zoriya/react-native-svg.git
synced 2026-05-31 05:51:47 +00:00
feat: use transform parsing code from rn core (#1918)
PR changing the custom transform prop parsing algorithm to the one from RN core (facebook/react-native@2eccd59/React/Views/RCTConvert%2BTransform.m), which the current one was most probably taken from.
This commit is contained in:
@@ -7,139 +7,12 @@
|
||||
*/
|
||||
|
||||
#import "RNSVGNodeManager.h"
|
||||
|
||||
#import "RNSVGNode.h"
|
||||
|
||||
static const NSUInteger kMatrixArrayLength = 4 * 4;
|
||||
#import <React/RCTConvert+Transform.h>
|
||||
|
||||
@implementation RNSVGNodeManager
|
||||
|
||||
+ (CGFloat)convertToRadians:(id)json
|
||||
{
|
||||
if ([json isKindOfClass:[NSString class]]) {
|
||||
NSString *stringValue = (NSString *)json;
|
||||
if ([stringValue hasSuffix:@"deg"]) {
|
||||
CGFloat degrees = [[stringValue substringToIndex:stringValue.length - 3] floatValue];
|
||||
return degrees * (CGFloat)M_PI / 180;
|
||||
}
|
||||
if ([stringValue hasSuffix:@"rad"]) {
|
||||
return [[stringValue substringToIndex:stringValue.length - 3] floatValue];
|
||||
}
|
||||
}
|
||||
return [json floatValue];
|
||||
}
|
||||
|
||||
+ (CATransform3D)CATransform3DFromMatrix:(id)json
|
||||
{
|
||||
CATransform3D transform = CATransform3DIdentity;
|
||||
if (!json) {
|
||||
return transform;
|
||||
}
|
||||
if (![json isKindOfClass:[NSArray class]]) {
|
||||
RCTLogConvertError(json, @"a CATransform3D. Expected array for transform matrix.");
|
||||
return transform;
|
||||
}
|
||||
NSArray *array = json;
|
||||
if ([array count] != kMatrixArrayLength) {
|
||||
RCTLogConvertError(json, @"a CATransform3D. Expected 4x4 matrix array.");
|
||||
return transform;
|
||||
}
|
||||
for (NSUInteger i = 0; i < kMatrixArrayLength; i++) {
|
||||
((CGFloat *)&transform)[i] = [RCTConvert CGFloat:array[i]];
|
||||
}
|
||||
return transform;
|
||||
}
|
||||
|
||||
+ (CATransform3D)CATransform3D:(id)json
|
||||
{
|
||||
CATransform3D transform = CATransform3DIdentity;
|
||||
if (!json) {
|
||||
return transform;
|
||||
}
|
||||
if (![json isKindOfClass:[NSArray class]]) {
|
||||
RCTLogConvertError(json, @"a CATransform3D. Did you pass something other than an array?");
|
||||
return transform;
|
||||
}
|
||||
// legacy matrix support
|
||||
if ([(NSArray *)json count] == kMatrixArrayLength && [json[0] isKindOfClass:[NSNumber class]]) {
|
||||
RCTLogWarn(
|
||||
@"[RCTConvert CATransform3D:] has deprecated a matrix as input. Pass an array of configs (which can contain a matrix key) instead.");
|
||||
return [self CATransform3DFromMatrix:json];
|
||||
}
|
||||
|
||||
CGFloat zeroScaleThreshold = FLT_EPSILON;
|
||||
|
||||
for (NSDictionary *transformConfig in (NSArray<NSDictionary *> *)json) {
|
||||
if (transformConfig.count != 1) {
|
||||
RCTLogConvertError(json, @"a CATransform3D. You must specify exactly one property per transform object.");
|
||||
return transform;
|
||||
}
|
||||
NSString *property = transformConfig.allKeys[0];
|
||||
id value = transformConfig[property];
|
||||
|
||||
if ([property isEqualToString:@"matrix"]) {
|
||||
transform = [self CATransform3DFromMatrix:value];
|
||||
|
||||
} else if ([property isEqualToString:@"perspective"]) {
|
||||
transform.m34 = -1 / [value floatValue];
|
||||
|
||||
} else if ([property isEqualToString:@"rotateX"]) {
|
||||
CGFloat rotate = [self convertToRadians:value];
|
||||
transform = CATransform3DRotate(transform, rotate, 1, 0, 0);
|
||||
|
||||
} else if ([property isEqualToString:@"rotateY"]) {
|
||||
CGFloat rotate = [self convertToRadians:value];
|
||||
transform = CATransform3DRotate(transform, rotate, 0, 1, 0);
|
||||
|
||||
} else if ([property isEqualToString:@"rotate"] || [property isEqualToString:@"rotateZ"]) {
|
||||
CGFloat rotate = [self convertToRadians:value];
|
||||
transform = CATransform3DRotate(transform, rotate, 0, 0, 1);
|
||||
|
||||
} else if ([property isEqualToString:@"scale"]) {
|
||||
CGFloat scale = [value floatValue];
|
||||
scale = ABS(scale) < zeroScaleThreshold ? zeroScaleThreshold : scale;
|
||||
transform = CATransform3DScale(transform, scale, scale, 1);
|
||||
|
||||
} else if ([property isEqualToString:@"scaleX"]) {
|
||||
CGFloat scale = [value floatValue];
|
||||
scale = ABS(scale) < zeroScaleThreshold ? zeroScaleThreshold : scale;
|
||||
transform = CATransform3DScale(transform, scale, 1, 1);
|
||||
|
||||
} else if ([property isEqualToString:@"scaleY"]) {
|
||||
CGFloat scale = [value floatValue];
|
||||
scale = ABS(scale) < zeroScaleThreshold ? zeroScaleThreshold : scale;
|
||||
transform = CATransform3DScale(transform, 1, scale, 1);
|
||||
|
||||
} else if ([property isEqualToString:@"translate"]) {
|
||||
NSArray *array = (NSArray<NSNumber *> *)value;
|
||||
CGFloat translateX = [array[0] floatValue];
|
||||
CGFloat translateY = [array[1] floatValue];
|
||||
CGFloat translateZ = array.count > 2 ? [array[2] floatValue] : 0;
|
||||
transform = CATransform3DTranslate(transform, translateX, translateY, translateZ);
|
||||
|
||||
} else if ([property isEqualToString:@"translateX"]) {
|
||||
CGFloat translate = [value floatValue];
|
||||
transform = CATransform3DTranslate(transform, translate, 0, 0);
|
||||
|
||||
} else if ([property isEqualToString:@"translateY"]) {
|
||||
CGFloat translate = [value floatValue];
|
||||
transform = CATransform3DTranslate(transform, 0, translate, 0);
|
||||
|
||||
} else if ([property isEqualToString:@"skewX"]) {
|
||||
CGFloat skew = [self convertToRadians:value];
|
||||
transform.m21 = tanf((float)skew);
|
||||
|
||||
} else if ([property isEqualToString:@"skewY"]) {
|
||||
CGFloat skew = [self convertToRadians:value];
|
||||
transform.m12 = tanf((float)skew);
|
||||
|
||||
} else {
|
||||
RCTLogError(@"Unsupported transform type for a CATransform3D: %@.", property);
|
||||
}
|
||||
}
|
||||
return transform;
|
||||
}
|
||||
|
||||
RCT_EXPORT_MODULE()
|
||||
|
||||
- (RNSVGNode *)node
|
||||
@@ -157,7 +30,7 @@ RCT_EXPORT_VIEW_PROPERTY(opacity, CGFloat)
|
||||
RCT_EXPORT_VIEW_PROPERTY(matrix, CGAffineTransform)
|
||||
RCT_CUSTOM_VIEW_PROPERTY(transform, CATransform3D, RNSVGNode)
|
||||
{
|
||||
CATransform3D transform3d = json ? [RNSVGNodeManager CATransform3D:json] : defaultView.layer.transform;
|
||||
CATransform3D transform3d = json ? [RCTConvert CATransform3D:json] : defaultView.layer.transform;
|
||||
CGAffineTransform transform = CATransform3DGetAffineTransform(transform3d);
|
||||
view.invTransform = CGAffineTransformInvert(transform);
|
||||
view.transforms = transform;
|
||||
|
||||
Reference in New Issue
Block a user