refactor!: Replace Offset with opacityFrom and opacityTo in ColorEffect (#2876)

`ColorEffect`'s API was a bit confusing because it used `Offset` for
getting values of opacity start and end from user. This PR changes that
to use optional `opacityFrom` and `opacityTo` double parameters. It also
adds validate checks on these value to make sure that are between 0 and
1.
This commit is contained in:
DevKage
2023-11-27 18:51:18 +05:30
committed by GitHub
parent f4ff31174a
commit 0fd2662d4b
7 changed files with 69 additions and 16 deletions

View File

@ -535,13 +535,14 @@ Usage example:
```dart ```dart
final effect = ColorEffect( final effect = ColorEffect(
const Color(0xFF00FF00), const Color(0xFF00FF00),
const Offset(0.0, 0.8),
EffectController(duration: 1.5), EffectController(duration: 1.5),
opacityFrom = 0.2,
opacityTo: 0.8,
); );
``` ```
The `Offset` argument will determine "how much" of the color that will be applied to the component, The `opacityFrom` and `opacityTo` arguments will determine "how much" of the color that will be
in this example the effect will start with 0% and will go up to 80%. applied to the component. In this example the effect will start with 20% and will go up to 80%.
**Note:** Due to how this effect is implemented, and how Flutter's `ColorFilter` class works, this **Note:** Due to how this effect is implemented, and how Flutter's `ColorFilter` class works, this
effect can't be mixed with other `ColorEffect`s, when more than one is added to the component, only effect can't be mixed with other `ColorEffect`s, when more than one is added to the component, only

View File

@ -18,16 +18,16 @@ class ColorEffectExample extends FlameGame {
ember.add( ember.add(
ColorEffect( ColorEffect(
const Color(0xFF00FF00), const Color(0xFF00FF00),
const Offset(0.0, 0.6),
EffectController(duration: 1.5), EffectController(duration: 1.5),
opacityTo: 0.6,
), ),
); );
} else { } else {
ember.add( ember.add(
ColorEffect( ColorEffect(
const Color(0xFF1039DB), const Color(0xFF1039DB),
const Offset(0.0, 0.6),
EffectController(duration: 1.5), EffectController(duration: 1.5),
opacityTo: 0.6,
), ),
); );
} }

View File

@ -69,11 +69,11 @@ class CollidableEmber extends Ember with CollisionCallbacks {
add( add(
ColorEffect( ColorEffect(
index < 2 ? Colors.red : Colors.green, index < 2 ? Colors.red : Colors.green,
const Offset(0, 0.9),
EffectController( EffectController(
duration: 0.2, duration: 0.2,
alternate: true, alternate: true,
), ),
opacityTo: 0.9,
), ),
); );
} }

View File

@ -22,15 +22,13 @@ class ColorEffectExample extends FlameGame with TapDetector {
)..add( )..add(
ColorEffect( ColorEffect(
Colors.blue, Colors.blue,
const Offset(
0.0,
0.8,
), // Means, applies from 0% to 80% of the color
EffectController( EffectController(
duration: 1.5, duration: 1.5,
reverseDuration: 1.5, reverseDuration: 1.5,
infinite: true, infinite: true,
), ),
// Means, applies from 0% to 80% of the color
opacityTo: 0.8,
), ),
), ),
); );

View File

@ -33,8 +33,8 @@ class DualEffectRemovalExample extends FlameGame with TapDetector {
); );
colorEffect = ColorEffect( colorEffect = ColorEffect(
Colors.blue, Colors.blue,
const Offset(0.0, 0.8),
colorController, colorController,
opacityTo: 0.8,
); );
mySprite.add(colorEffect); mySprite.add(colorEffect);

View File

@ -18,11 +18,19 @@ class ColorEffect extends ComponentEffect<HasPaint> {
ColorEffect( ColorEffect(
this.color, this.color,
Offset offset,
EffectController controller, { EffectController controller, {
double opacityFrom = 0,
double opacityTo = 1,
this.paintId, this.paintId,
void Function()? onComplete, void Function()? onComplete,
}) : _tween = Tween(begin: offset.dx, end: offset.dy), }) : assert(
opacityFrom >= 0 &&
opacityFrom <= 1 &&
opacityTo >= 0 &&
opacityTo <= 1,
'Opacity value should be between 0 and 1',
),
_tween = Tween(begin: opacityFrom, end: opacityTo),
super(controller, onComplete: onComplete); super(controller, onComplete: onComplete);
@override @override

View File

@ -13,7 +13,7 @@ void main() {
await game.ensureAdd(component); await game.ensureAdd(component);
const color = Colors.red; const color = Colors.red;
await component.add( await component.add(
ColorEffect(color, const Offset(0, 1), EffectController(duration: 1)), ColorEffect(color, EffectController(duration: 1)),
); );
game.update(0); game.update(0);
expect( expect(
@ -43,7 +43,6 @@ void main() {
final effect = ColorEffect( final effect = ColorEffect(
color, color,
const Offset(0, 1),
EffectController(duration: 1), EffectController(duration: 1),
); );
await component.add(effect); await component.add(effect);
@ -71,7 +70,6 @@ void main() {
final effect = ColorEffect( final effect = ColorEffect(
Colors.red, Colors.red,
const Offset(0, 1),
EffectController(duration: 1), EffectController(duration: 1),
); );
await component.ensureAdd(effect); await component.ensureAdd(effect);
@ -85,5 +83,53 @@ void main() {
); );
}, },
); );
test('Validates opacity values', () {
expect(
() => ColorEffect(
Colors.blue,
EffectController(duration: 1),
opacityTo: 1.1,
),
throwsAssertionError,
);
expect(
() => ColorEffect(
Colors.blue,
EffectController(duration: 1),
opacityFrom: 255,
),
throwsAssertionError,
);
expect(
() => ColorEffect(
Colors.blue,
EffectController(duration: 1),
opacityTo: -254,
),
throwsAssertionError,
);
expect(
() => ColorEffect(
Colors.blue,
EffectController(duration: 1),
opacityFrom: -0.5,
),
throwsAssertionError,
);
expect(
() => ColorEffect(
Colors.blue,
EffectController(duration: 1),
opacityFrom: 0.1,
opacityTo: 0.9,
),
returnsNormally,
);
});
}); });
} }