From 43e71ae64f10f7efa3c8a14e7e241768efda3588 Mon Sep 17 00:00:00 2001
From: Adam Skelton <65806473+Zabadam@users.noreply.github.com>
Date: Thu, 13 Jun 2024 19:31:23 -0500
Subject: [PATCH] Include transform in static Gradient lerp methods (#149624)
*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
Video demonstration
### 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
- Changed no documentation.
- Non-breaking change.
---
.../flutter/lib/src/painting/gradient.dart | 3 +
.../flutter/test/painting/gradient_test.dart | 78 +++++++++++++++++++
2 files changed, 81 insertions(+)
diff --git a/packages/flutter/lib/src/painting/gradient.dart b/packages/flutter/lib/src/painting/gradient.dart
index e1545edecd..8a3931a2ef 100644
--- a/packages/flutter/lib/src/painting/gradient.dart
+++ b/packages/flutter/lib/src/painting/gradient.dart
@@ -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,
);
}
@@ -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,
);
}
@@ -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,
);
}
diff --git a/packages/flutter/test/painting/gradient_test.dart b/packages/flutter/test/painting/gradient_test.dart
index bd4d2b85e0..9accb119ed 100644
--- a/packages/flutter/test/painting/gradient_test.dart
+++ b/packages/flutter/test/painting/gradient_test.dart
@@ -191,6 +191,32 @@ void main() {
));
});
+ test('LinearGradient lerp test with transforms', () {
+ const LinearGradient testGradient1 = LinearGradient(
+ transform: GradientRotation(math.pi/4),
+ colors: [
+ Color(0x33333333),
+ Color(0x66666666),
+ ],
+ stops: [0, 1],
+ );
+ const LinearGradient testGradient2 = LinearGradient(
+ transform: GradientRotation(math.pi/2),
+ colors: [
+ Color(0x33333333),
+ Color(0x66666666),
+ ],
+ stops: [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(
@@ -481,6 +507,32 @@ void main() {
));
});
+ test('RadialGradient lerp test with transforms', () {
+ const RadialGradient testGradient1 = RadialGradient(
+ transform: GradientRotation(math.pi/4),
+ colors: [
+ Color(0x33333333),
+ Color(0x66666666),
+ ],
+ stops: [0, 1],
+ );
+ const RadialGradient testGradient2 = RadialGradient(
+ transform: GradientRotation(math.pi/2),
+ colors: [
+ Color(0x33333333),
+ Color(0x66666666),
+ ],
+ stops: [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,
@@ -706,6 +758,32 @@ void main() {
));
});
+ test('SweepGradient lerp test with transforms', () {
+ const SweepGradient testGradient1 = SweepGradient(
+ transform: GradientRotation(math.pi/4),
+ colors: [
+ Color(0x33333333),
+ Color(0x66666666),
+ ],
+ stops: [0, 1],
+ );
+ const SweepGradient testGradient2 = SweepGradient(
+ transform: GradientRotation(math.pi/2),
+ colors: [
+ Color(0x33333333),
+ Color(0x66666666),
+ ],
+ stops: [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,