Skip to content

Commit

Permalink
fix multiple transition hint
Browse files Browse the repository at this point in the history
  • Loading branch information
intergalacticspacehighway committed Jan 5, 2025
1 parent 3f93439 commit d7a560c
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 22 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -856,6 +856,12 @@ describe('processBackgroundImage', () => {
`;
const result1 = processBackgroundImage(input1);
expect(result1).toEqual([]);

const input2 = `
linear-gradient(20%, red, green)
`;
const result2 = processBackgroundImage(input2);
expect(result2).toEqual([]);
});

it('should process gradient with % and px color stop positions', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -249,12 +249,13 @@ function parseCSSLinearGradient(
else if (colorStopParts.length === 1) {
const position = getPositionFromCSSValue(colorStopParts[0]);
if (position != null) {
// invalid transition hint syntax. transition hint syntax must have color before and after the position. e.g. red, 20%, blue
// handle invalid transition hint syntax. transition hint syntax must have color before and after the position. e.g. red, 20%, blue
if (
(prevStop != null &&
prevStop.length === 1 &&
getPositionFromCSSValue(prevStop[0]) != null) ||
i === stops.length - 1
i === stops.length - 1 ||
i === 0
) {
// If the last stop is a transition hint syntax, return an empty array and do not apply any gradient. Same as web.
return [];
Expand Down
13 changes: 6 additions & 7 deletions packages/react-native/React/Fabric/Utils/RCTLinearGradient.mm
Original file line number Diff line number Diff line change
Expand Up @@ -143,13 +143,12 @@ static CGFloat getAngleForKeyword(GradientKeyword keyword, CGSize size)
// Algorithm is referred from Blink engine [source](https://github.com/chromium/chromium/blob/a296b1bad6dc1ed9d751b7528f7ca2134227b828/third_party/blink/renderer/core/css/css_gradient_value.cc#L240).
static std::vector<ColorStop> processColorTransitionHints(const std::vector<ColorStop>& originalStops)
{
std::vector<ColorStop> colorStops = originalStops;
std::vector<ColorStop> colorStops = std::vector<ColorStop>(originalStops);
int indexOffset = 0;

for (size_t i = 1; i < colorStops.size() - 1; i++) {
auto &colorStop = colorStops[i];
for (size_t i = 1; i < originalStops.size() - 1; ++i) {
// Skip if not a color hint
if (colorStop.color) {
if (originalStops[i].color) {
continue;
}

Expand All @@ -160,7 +159,7 @@ static CGFloat getAngleForKeyword(GradientKeyword keyword, CGSize size)

Float offsetLeft = colorStops[x - 1].position.resolve(0.0f);
Float offsetRight = colorStops[x + 1].position.resolve(0.0f);
Float offset = colorStop.position.resolve(0.0f);
Float offset = colorStops[x].position.resolve(0.0f);
Float leftDist = offset - offsetLeft;
Float rightDist = offsetRight - offset;
Float totalDist = offsetRight - offsetLeft;
Expand All @@ -174,12 +173,12 @@ static CGFloat getAngleForKeyword(GradientKeyword keyword, CGSize size)
}

if (facebook::react::floatEquality(leftDist, .0f)) {
colorStop.color = rightSharedColor;
colorStops[x].color = rightSharedColor;
continue;
}

if (facebook::react::floatEquality(rightDist, .0f)) {
colorStop.color = leftSharedColor;
colorStops[x].color = leftSharedColor;
continue;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -283,24 +283,20 @@ internal class LinearGradient(
val colorStops = originalStops.toMutableList()
var indexOffset = 0

var i = 1
while (i < colorStops.size - 1) {
val colorStop = colorStops[i]
for (i in 1 until originalStops.size - 1) {
// Skip if not a color hint
if (colorStop.color != null) {
i++
if (originalStops[i].color != null) {
continue
}

val x = i + indexOffset
if (x < 1) {
i++
continue
}

val offsetLeft = colorStops[x - 1].position.value
val offsetRight = colorStops[x + 1].position.value
val offset = colorStop.position.value
val offset = colorStops[x].position.value
val leftDist = offset - offsetLeft
val rightDist = offsetRight - offset
val totalDist = offsetRight - offsetLeft
Expand All @@ -309,19 +305,17 @@ internal class LinearGradient(

if (FloatUtil.floatsEqual(leftDist, rightDist)) {
colorStops.removeAt(x)
indexOffset--
--indexOffset
continue
}

if (FloatUtil.floatsEqual(leftDist, 0f)) {
colorStops[x] = ColorStop(rightColor, colorStop.position)
i++
colorStops[x].color = rightColor
continue
}

if (FloatUtil.floatsEqual(rightDist, 0f)) {
colorStops[x] = ColorStop(leftColor, colorStop.position)
i++
colorStops[x].color = leftColor
continue
}

Expand Down Expand Up @@ -396,7 +390,6 @@ internal class LinearGradient(
colorStops.removeAt(x)
colorStops.addAll(x, newStops)
indexOffset += 8
i += 9
}

return colorStops
Expand Down

0 comments on commit d7a560c

Please sign in to comment.