mirror of
https://github.com/Tencent/Hippy.git
synced 2026-10-22 08:46:09 +08:00
220 lines
8.3 KiB
Objective-C
220 lines
8.3 KiB
Objective-C
/*!
|
|
* iOS SDK
|
|
*
|
|
* Tencent is pleased to support the open source community by making
|
|
* NativeRender available.
|
|
*
|
|
* Copyright (C) 2019 THL A29 Limited, a Tencent company.
|
|
* All rights reserved.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#import "HPConvert+NativeRender.h"
|
|
#import "HPToolUtils.h"
|
|
|
|
@implementation HPConvert (Transform)
|
|
|
|
static const NSUInteger kMatrixArrayLength = 4 * 4;
|
|
|
|
+ (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 * M_PI / 180;
|
|
}
|
|
if ([stringValue hasSuffix:@"rad"]) {
|
|
return [[stringValue substringToIndex:stringValue.length - 3] floatValue];
|
|
}
|
|
}
|
|
return [json floatValue];
|
|
}
|
|
|
|
+ (CGFloat)convertDegToRadians:(CGFloat)deg {
|
|
return deg * M_PI / 180;
|
|
}
|
|
|
|
+ (CATransform3D)CATransform3DFromMatrix:(id)json {
|
|
CATransform3D transform = CATransform3DIdentity;
|
|
if (!json) {
|
|
return transform;
|
|
}
|
|
if (![json isKindOfClass:[NSArray class]]) {
|
|
HPLogError(@"[%@], a CATransform3D. Expected array for transform matrix.", json);
|
|
return transform;
|
|
}
|
|
if ([json count] != kMatrixArrayLength) {
|
|
HPLogError(@"[%@], a CATransform3D. Expected 4x4 matrix array.", json);
|
|
return transform;
|
|
}
|
|
for (NSUInteger i = 0; i < kMatrixArrayLength; i++) {
|
|
((CGFloat *)&transform)[i] = [HPConvert CGFloat:json[i]];
|
|
}
|
|
return transform;
|
|
}
|
|
|
|
+ (CATransform3D)CATransform3D:(id)json {
|
|
CATransform3D transform = CATransform3DIdentity;
|
|
transform.m34 = -1.0 / 500.0;
|
|
if (!json) {
|
|
return transform;
|
|
}
|
|
if (![json isKindOfClass:[NSArray class]]) {
|
|
HPLogError(@"[%@],a CATransform3D. Did you pass something other than an array?", json);
|
|
return transform;
|
|
}
|
|
// legacy matrix support
|
|
if ([(NSArray *)json count] == kMatrixArrayLength && [json[0] isKindOfClass:[NSNumber class]]) {
|
|
HPLogWarn(
|
|
@"[HPConvert 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) {
|
|
HPLogError(@"[%@], a CATransform3D. You must specify exactly one property per transform object.", json);
|
|
return transform;
|
|
}
|
|
NSString *property = transformConfig.allKeys[0];
|
|
id value = HPNilIfNull(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.m34 = 0.f;
|
|
transform = CATransform3DScale(transform, scale, scale, scale);
|
|
} else if ([property isEqualToString:@"scaleX"]) {
|
|
CGFloat scale = [value floatValue];
|
|
scale = ABS(scale) < zeroScaleThreshold ? zeroScaleThreshold : scale;
|
|
transform.m34 = 0.f;
|
|
transform = CATransform3DScale(transform, scale, 1, 1);
|
|
|
|
} else if ([property isEqualToString:@"scaleY"]) {
|
|
CGFloat scale = [value floatValue];
|
|
scale = ABS(scale) < zeroScaleThreshold ? zeroScaleThreshold : scale;
|
|
transform.m34 = 0.f;
|
|
transform = CATransform3DScale(transform, 1, scale, 1);
|
|
|
|
} else if ([property isEqualToString:@"translate"]) {
|
|
NSArray *array = (NSArray<NSNumber *> *)value;
|
|
CGFloat translateX = [HPNilIfNull(array[0]) floatValue];
|
|
CGFloat translateY = [HPNilIfNull(array[1]) floatValue];
|
|
CGFloat translateZ = array.count > 2 ? [HPNilIfNull(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:@"translateZ"]) {
|
|
CGFloat translate = [value floatValue];
|
|
transform = CATransform3DTranslate(transform, 0, 0, translate);
|
|
|
|
} else if ([property isEqualToString:@"skewX"]) {
|
|
CGFloat skew = [self convertToRadians:value];
|
|
transform.m21 = tanf(skew);
|
|
|
|
} else if ([property isEqualToString:@"skewY"]) {
|
|
CGFloat skew = [self convertToRadians:value];
|
|
transform.m12 = tanf(skew);
|
|
|
|
} else {
|
|
HPLogError(@"Unsupported transform type for a CATransform3D: %@.", property);
|
|
}
|
|
}
|
|
return transform;
|
|
}
|
|
|
|
@end
|
|
|
|
@implementation HPConvert (NativeRenderAnimationType)
|
|
|
|
HP_ENUM_CONVERTER(NativeRenderAnimationType, (@{
|
|
@"spring": @(NativeRenderAnimationTypeSpring),
|
|
@"linear": @(NativeRenderAnimationTypeLinear),
|
|
@"easeIn": @(NativeRenderAnimationTypeEaseIn),
|
|
@"easeOut": @(NativeRenderAnimationTypeEaseOut),
|
|
@"easeInEaseOut": @(NativeRenderAnimationTypeEaseInEaseOut),
|
|
@"keyboard": @(NativeRenderAnimationTypeKeyboard),
|
|
}),
|
|
NativeRenderAnimationTypeEaseInEaseOut, integerValue)
|
|
|
|
@end
|
|
|
|
@implementation HPConvert (NativeRenderPointerEvents)
|
|
|
|
HP_ENUM_CONVERTER(NativeRenderPointerEvents, (@{
|
|
@"none": @(NativeRenderPointerEventsNone),
|
|
@"box-only": @(NativeRenderPointerEventsBoxOnly),
|
|
@"box-none": @(NativeRenderPointerEventsBoxNone),
|
|
@"auto": @(NativeRenderPointerEventsUnspecified)
|
|
}),
|
|
NativeRenderPointerEventsUnspecified, integerValue)
|
|
|
|
@end
|
|
|
|
@implementation HPConvert (NativeRenderBorderStyle)
|
|
|
|
HP_ENUM_CONVERTER(NativeRenderBorderStyle, (@{
|
|
@"solid": @(NativeRenderBorderStyleSolid),
|
|
@"dotted": @(NativeRenderBorderStyleDotted),
|
|
@"dashed": @(NativeRenderBorderStyleDashed),
|
|
@"none": @(NativeRenderBorderStyleNone),
|
|
}),
|
|
NativeRenderBorderStyleSolid, integerValue)
|
|
|
|
@end
|
|
|
|
@implementation HPConvert (NativeRenderTextEnumDefines)
|
|
|
|
HP_ENUM_CONVERTER(NativeRenderTextDecorationLineType, (@{
|
|
@"none": @(NativeRenderTextDecorationLineTypeNone),
|
|
@"underline": @(NativeRenderTextDecorationLineTypeUnderline),
|
|
@"line-through": @(NativeRenderTextDecorationLineTypeStrikethrough),
|
|
@"underline line-through": @(NativeRenderTextDecorationLineTypeUnderlineStrikethrough),
|
|
}),
|
|
NativeRenderTextDecorationLineTypeNone, integerValue)
|
|
|
|
HP_ENUM_CONVERTER(NativeRenderTextVerticalAlignType, (@{
|
|
@"middle": @(NativeRenderTextVerticalAlignMiddle),
|
|
@"top": @(NativeRenderTextVerticalAlignTop),
|
|
@"bottom": @(NativeRenderTextVerticalAlignBottom),
|
|
@"baseline": @(NativeRenderTextVerticalAlignBaseline),
|
|
}), NativeRenderTextVerticalAlignUndefined, integerValue)
|
|
|
|
@end
|