Skip to content
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

feat: radial gradient #50209

Conversation

intergalacticspacehighway
Copy link
Contributor

@intergalacticspacehighway intergalacticspacehighway commented Mar 24, 2025

Summary:

  • Adds CSS spec compliant radial gradient support
  • Also adds object styling for the same to support JS syntax animations.

Changelog:

[GENERAL] [ADDED] - Radial gradient

Test Plan:

Added testcases in processBackgroundImage-test.js and examples in RadientGradientExample.js

Screenshot 2025-03-24 at 10 12 32 AM

@facebook-github-bot facebook-github-bot added CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team. labels Mar 24, 2025
Copy link
Contributor

@jorge-cab jorge-cab left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only a few things on initial review! Thank you for working on this!

I will import to test the "meat" of the algorithm more thoroughly and for it to go through internal review. I will try to make it so it doesn't take as much time to land this as the other times.

#include <react/renderer/graphics/ColorStop.h>
#import <vector>

using namespace facebook::react;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't use using namespace on header files since anything that might include the header will also get the using namespace so lets remove it from here

Comment on lines 81 to 87
public fun resolveToPixel(referenceLength: Float): Float {
if (type == LengthPercentageType.PERCENT) {
return (value / 100) * referenceLength
}
return PixelUtil.toPixelFromDIP(value)
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is needed, we have .dpToPx() method added to Floats so I think we should just do that when using the resolved value. Specially since this would be adding yet another public API

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

very cool. updated!

var centerY: Float = height / 2f

if (position.top != null) {
centerY = position.top.resolveToPixel(height)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this and all other usages of resolveToPixel

Suggested change
centerY = position.top.resolveToPixel(height)
centerY = position.top.resolve(height).dpToPx()

@facebook-github-bot
Copy link
Contributor

@jorge-cab has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

Comment on lines 17 to 25
internal class Gradient(gradient: ReadableMap?, context: Context) {
private enum class GradientType {
LINEAR_GRADIENT
LINEAR_GRADIENT,
RADIAL_GRADIENT
}

private val type: GradientType
private val linearGradient: LinearGradient
private val linearGradient: LinearGradient?
private val radialGradient: RadialGradient?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It feels like there should be a better way to do this. Maybe have Gradient be a super class for LinearGradient and RadialGradient? Or maybe have it be an interface where we implement getShader and do the parsing of LinearGradient/RadialGradient on their own class?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

true, interface with getShader makes most sense, will add it 👍

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated, will split the PR as Nick mentioned.

Copy link
Contributor

@NickGerleman NickGerleman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is really exciting! But also a pretty huge change. Could we split this up a bit?

const DIRECTION_KEYWORD_REGEX =

// Linear Gradient
const LINEAR_GRADIENT_DIRECTION_REGEX =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Heads up, that we are starting soon on iOS to experiment with the native parser which replaced ViewConfig processors. I didn't port this for backgroundImage yet, but the other processors should all be there with tests. https://github.com/facebook/react-native/blob/main/packages/react-native/ReactCommon/react/renderer/css/CSSTransformOrigin.h

This is building in OSS now, but IDK the story for GTest. @cortinico would know better.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@NickGerleman yes! i saw this one. i didn't spend much time to try running it as currently the flag was off. But i will try to write a native parser for gradients 😄.

For now, i can split this PR into three (iOS, android and JS changes)

@intergalacticspacehighway
Copy link
Contributor Author

intergalacticspacehighway commented Mar 25, 2025

@NickGerleman @jorge-cab i have split the PRs into three parts. Feel free to close this one.

  1. JS prop drilling - feat: radial gradient js prop passing #50268
  2. Android changes - feat: radial gradient android changes #50269
  3. iOS changes - feat: radial gradient iOS #50266

To test on a platform, merge JS and that platform's PR. Sorry for the PR spam 😅

@jorge-cab jorge-cab closed this Mar 26, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants