-
Notifications
You must be signed in to change notification settings - Fork 24.7k
[iOS][backgroundImage] - Use CAGradientLayer for linear gradient #52096
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[iOS][backgroundImage] - Use CAGradientLayer for linear gradient #52096
Conversation
@@ -16,6 +16,9 @@ NS_ASSUME_NONNULL_BEGIN | |||
+ (std::vector<facebook::react::ProcessedColorStop>)getFixedColorStops: | |||
(const std::vector<facebook::react::ColorStop> &)colorStops | |||
gradientLineLength:(CGFloat)gradientLineLength; | |||
+ (std::pair<CGPoint, CGPoint>)fixGradientPoints:(CGPoint)startPoint |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does fix mean here? Can you make the method name more meaningful or add a docblock?
if (std::isinf(slope)) { | ||
return 0.0; | ||
} | ||
if (facebook::react::floatEquality(slope, 0.0f)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (facebook::react::floatEquality(slope, 0.0f)) { | |
if (floatEquality(slope, 0.0f)) { |
CGFloat gradientLineLength = sqrt(dx * dx + dy * dy); | ||
const auto colorStops = [RCTGradientUtils getFixedColorStops:gradient.colorStops | ||
gradientLineLength:gradientLineLength]; | ||
NSMutableArray *colors = [NSMutableArray array]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add generic arg to type
CGColorRef cgColor = RCTCreateCGColorRefFromSharedColor(colorStop.color); | ||
[colors addObject:(__bridge id)cgColor]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use RCTUIColorFromSharedColor
instead, so we don't need to call CGColorRelease
// CAGradientLayer linear gradient squishes the non-square gradient to square gradient. | ||
// This function fixes the "squished" effect. | ||
// See https://stackoverflow.com/a/43176174 for more information. | ||
+ (std::pair<CGPoint, CGPoint>)fixGradientPoints:(CGPoint)startPoint |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add a unit test for this method?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, I should add one in the rn-tester/RNTesterUnitTests
directory, correct?
CGFloat gradientLineLength = sqrt(dx * dx + dy * dy); | ||
const auto colorStops = [RCTGradientUtils getFixedColorStops:gradient.colorStops | ||
gradientLineLength:gradientLineLength]; | ||
NSMutableArray<id> *colors = [NSMutableArray array]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can this be NSMutableArray<UIColor *>
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
no, actually the gradientLayer.colors require it to be CGColors 😕
@javache has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator. |
@javache has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator. |
Summary:
This PR replaces Core Graphics implementation with Core Animation for linear gradients. I came across a great solution that makes the
CAGradientLayer
's start and end point behaviour CSS spec compliant. This will make gradients much more performant.Changelog:
[IOS] [CHANGED] - Optimised Linear Gradients.
Test Plan:
Non breaking change. Test Linear gradient example from RNTester. Compare results with web, android and iOS. Each platform should render the gradients identically.
Note:
I will be doing a PR to use
CAGradientLayer
for radial gradients as well. The next properties that I have locally working arebackground-size
,background-position
andbackground-repeat
. These will be addressed in small PRs.