Skip to content

Commit

Permalink
Include transform in static Gradient lerp methods (#149624)
Browse files Browse the repository at this point in the history
*Fixes #149534 Gradient subclasses' static lerp methods drop the GradientTransform of both `a` and `b`*

LinearGradient.lerp(), RadialGradient.lerp() and SweepGradient.lerp() no longer drop the GradientTransform of `a` and/or `b`.

The primitive interpolation is performed the same way TileMode is handled:  `transform: t < 0.5 ? a.transform : b.transform`.

## Media

<details>
<summary>Video demonstration</summary>

### Before
https://github.com/flutter/flutter/assets/65806473/de14e201-b1a7-44ba-95ff-e62587c7f6ac

### After
https://github.com/flutter/flutter/assets/65806473/d48f40e2-1b0f-4ac8-a45c-b3c423e3fd64

</details>

  - Changed no documentation.
  - Non-breaking change.
  • Loading branch information
Zabadam authored Jun 14, 2024
1 parent 9ea5b13 commit 43e71ae
Show file tree
Hide file tree
Showing 2 changed files with 81 additions and 0 deletions.
3 changes: 3 additions & 0 deletions packages/flutter/lib/src/painting/gradient.dart
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,7 @@ class LinearGradient extends Gradient {
colors: interpolated.colors,
stops: interpolated.stops,
tileMode: t < 0.5 ? a.tileMode : b.tileMode, // TODO(ianh): interpolate tile mode
transform: t < 0.5 ? a.transform : b.transform,
);
}

Expand Down Expand Up @@ -787,6 +788,7 @@ class RadialGradient extends Gradient {
tileMode: t < 0.5 ? a.tileMode : b.tileMode, // TODO(ianh): interpolate tile mode
focal: AlignmentGeometry.lerp(a.focal, b.focal, t),
focalRadius: math.max(0.0, ui.lerpDouble(a.focalRadius, b.focalRadius, t)!),
transform: t < 0.5 ? a.transform : b.transform,
);
}

Expand Down Expand Up @@ -1052,6 +1054,7 @@ class SweepGradient extends Gradient {
colors: interpolated.colors,
stops: interpolated.stops,
tileMode: t < 0.5 ? a.tileMode : b.tileMode, // TODO(ianh): interpolate tile mode
transform: t < 0.5 ? a.transform : b.transform,
);
}

Expand Down
78 changes: 78 additions & 0 deletions packages/flutter/test/painting/gradient_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,32 @@ void main() {
));
});

test('LinearGradient lerp test with transforms', () {
const LinearGradient testGradient1 = LinearGradient(
transform: GradientRotation(math.pi/4),
colors: <Color>[
Color(0x33333333),
Color(0x66666666),
],
stops: <double>[0, 1],
);
const LinearGradient testGradient2 = LinearGradient(
transform: GradientRotation(math.pi/2),
colors: <Color>[
Color(0x33333333),
Color(0x66666666),
],
stops: <double>[0, 1],
);

final LinearGradient? actual0 = LinearGradient.lerp(testGradient1, testGradient2, 0.0);
final LinearGradient? actual1 = LinearGradient.lerp(testGradient1, testGradient2, 1.0);
final LinearGradient? actual2 = LinearGradient.lerp(testGradient1, testGradient2, 0.5);
expect(testGradient1, equals(actual0));
expect(testGradient2, equals(actual1));
expect(testGradient2, equals(actual2));
});

test('LinearGradient toString', () {
expect(
const LinearGradient(
Expand Down Expand Up @@ -481,6 +507,32 @@ void main() {
));
});

test('RadialGradient lerp test with transforms', () {
const RadialGradient testGradient1 = RadialGradient(
transform: GradientRotation(math.pi/4),
colors: <Color>[
Color(0x33333333),
Color(0x66666666),
],
stops: <double>[0, 1],
);
const RadialGradient testGradient2 = RadialGradient(
transform: GradientRotation(math.pi/2),
colors: <Color>[
Color(0x33333333),
Color(0x66666666),
],
stops: <double>[0, 1],
);

final RadialGradient? actual0 = RadialGradient.lerp(testGradient1, testGradient2, 0.0);
final RadialGradient? actual1 = RadialGradient.lerp(testGradient1, testGradient2, 1.0);
final RadialGradient? actual2 = RadialGradient.lerp(testGradient1, testGradient2, 0.5);
expect(testGradient1, equals(actual0));
expect(testGradient2, equals(actual1));
expect(testGradient2, equals(actual2));
});

test('RadialGradient lerp test with focal', () {
const RadialGradient testGradient1 = RadialGradient(
center: Alignment.topLeft,
Expand Down Expand Up @@ -706,6 +758,32 @@ void main() {
));
});

test('SweepGradient lerp test with transforms', () {
const SweepGradient testGradient1 = SweepGradient(
transform: GradientRotation(math.pi/4),
colors: <Color>[
Color(0x33333333),
Color(0x66666666),
],
stops: <double>[0, 1],
);
const SweepGradient testGradient2 = SweepGradient(
transform: GradientRotation(math.pi/2),
colors: <Color>[
Color(0x33333333),
Color(0x66666666),
],
stops: <double>[0, 1],
);

final SweepGradient? actual0 = SweepGradient.lerp(testGradient1, testGradient2, 0.0);
final SweepGradient? actual1 = SweepGradient.lerp(testGradient1, testGradient2, 1.0);
final SweepGradient? actual2 = SweepGradient.lerp(testGradient1, testGradient2, 0.5);
expect(testGradient1, equals(actual0));
expect(testGradient2, equals(actual1));
expect(testGradient2, equals(actual2));
});

test('SweepGradient scale test)', () {
const SweepGradient testGradient = SweepGradient(
center: Alignment.topLeft,
Expand Down

0 comments on commit 43e71ae

Please sign in to comment.