Skip to content

Commit df6a228

Browse files
erickzanardospydon
authored andcommitted
feat: Adding paint attribute to SpriteWidget and SpriteAnimationWidget (#3298)
Adds a `Paint` attribute to the `SpriteWidget` and `SpriteAnimationWidget` for an improved API. --------- Co-authored-by: Lukas Klingsbo <me@lukas.fyi>
1 parent 0c0e8f2 commit df6a228

File tree

6 files changed

+76
-5
lines changed

6 files changed

+76
-5
lines changed
+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import 'dart:ui';
2+
3+
final paintChoices = [
4+
'none',
5+
'transparent',
6+
'red tinted',
7+
'green tinted',
8+
'blue tinted',
9+
];
10+
final paintList = [
11+
null,
12+
Paint()..color = const Color(0x22FFFFFF),
13+
Paint()
14+
..colorFilter = const ColorFilter.mode(
15+
Color(0x88FF0000),
16+
BlendMode.srcATop,
17+
),
18+
Paint()
19+
..colorFilter = const ColorFilter.mode(
20+
Color(0x8800FF00),
21+
BlendMode.srcATop,
22+
),
23+
Paint()
24+
..colorFilter = const ColorFilter.mode(
25+
Color(0x880000FF),
26+
BlendMode.srcATop,
27+
),
28+
];

examples/lib/stories/widgets/sprite_animation_widget_example.dart

+8
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import 'package:dashbook/dashbook.dart';
2+
import 'package:examples/stories/widgets/paints.dart';
23
import 'package:flame/extensions.dart';
34
import 'package:flame/widgets.dart';
45
import 'package:flutter/widgets.dart';
@@ -20,6 +21,13 @@ Widget spriteAnimationWidgetBuilder(DashbookContext ctx) {
2021
anchor: Anchor.valueOf(
2122
ctx.listProperty('anchor', 'center', anchorOptions),
2223
),
24+
paint: paintList[paintChoices.indexOf(
25+
ctx.listProperty(
26+
'paint',
27+
'none',
28+
paintChoices,
29+
),
30+
)],
2331
),
2432
);
2533
}

examples/lib/stories/widgets/sprite_widget_example.dart

+8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import 'dart:math';
22

33
import 'package:dashbook/dashbook.dart';
4+
import 'package:examples/stories/widgets/paints.dart';
45
import 'package:flame/widgets.dart';
56
import 'package:flutter/material.dart';
67

@@ -17,6 +18,13 @@ Widget spriteWidgetBuilder(DashbookContext ctx) {
1718
anchor: Anchor.valueOf(
1819
ctx.listProperty('anchor', 'center', anchorOptions),
1920
),
21+
paint: paintList[paintChoices.indexOf(
22+
ctx.listProperty(
23+
'paint',
24+
'none',
25+
paintChoices,
26+
),
27+
)],
2028
),
2129
);
2230
}

packages/flame/lib/src/widgets/animation_widget.dart

+11
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ class SpriteAnimationWidget extends StatelessWidget {
3030
/// A callback that is called when the animation completes.
3131
final VoidCallback? onComplete;
3232

33+
/// A custom [Paint] to be used when rendering the sprite.
34+
/// When omitted the default paint from the [Sprite] class will be used.
35+
final Paint? paint;
36+
3337
const SpriteAnimationWidget({
3438
required SpriteAnimation animation,
3539
required SpriteAnimationTicker animationTicker,
@@ -38,6 +42,7 @@ class SpriteAnimationWidget extends StatelessWidget {
3842
this.errorBuilder,
3943
this.loadingBuilder,
4044
this.onComplete,
45+
this.paint,
4146
super.key,
4247
}) : _animationFuture = animation,
4348
_animationTicker = animationTicker;
@@ -57,6 +62,7 @@ class SpriteAnimationWidget extends StatelessWidget {
5762
this.errorBuilder,
5863
this.loadingBuilder,
5964
this.onComplete,
65+
this.paint,
6066
super.key,
6167
}) : _animationFuture = SpriteAnimation.load(path, data, images: images),
6268
_animationTicker = null;
@@ -74,6 +80,7 @@ class SpriteAnimationWidget extends StatelessWidget {
7480
animationTicker: ticker,
7581
anchor: anchor,
7682
playing: playing,
83+
paint: paint,
7784
);
7885
},
7986
errorBuilder: errorBuilder,
@@ -97,11 +104,14 @@ class InternalSpriteAnimationWidget extends StatefulWidget {
97104
/// Should the [animation] be playing or not
98105
final bool playing;
99106

107+
final Paint? paint;
108+
100109
const InternalSpriteAnimationWidget({
101110
required this.animation,
102111
required this.animationTicker,
103112
this.playing = true,
104113
this.anchor = Anchor.topLeft,
114+
this.paint,
105115
super.key,
106116
});
107117

@@ -193,6 +203,7 @@ class _InternalSpriteAnimationWidgetState
193203
painter: SpritePainter(
194204
widget.animationTicker.getSprite(),
195205
widget.anchor,
206+
widget.paint,
196207
),
197208
);
198209
}

packages/flame/lib/src/widgets/sprite_painter.dart

+10-4
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,18 @@ import 'package:flutter/widgets.dart';
88
class SpritePainter extends CustomPainter {
99
final Sprite _sprite;
1010
final Anchor _anchor;
11+
final Paint? _paint;
1112
final double _angle;
1213

13-
SpritePainter(this._sprite, this._anchor, {double angle = 0})
14+
SpritePainter(this._sprite, this._anchor, this._paint, {double angle = 0})
1415
: _angle = angle;
1516

1617
@override
1718
bool shouldRepaint(SpritePainter oldDelegate) {
1819
return oldDelegate._sprite != _sprite ||
1920
oldDelegate._anchor != _anchor ||
20-
oldDelegate._angle != _angle;
21+
oldDelegate._angle != _angle ||
22+
oldDelegate._paint != _paint;
2123
}
2224

2325
@override
@@ -33,12 +35,16 @@ class SpritePainter extends CustomPainter {
3335
canvas.translateVector(boxAnchorPosition..sub(spriteAnchorPosition));
3436

3537
if (_angle == 0) {
36-
_sprite.render(canvas, size: paintSize);
38+
_sprite.render(canvas, size: paintSize, overridePaint: _paint);
3739
} else {
3840
canvas.renderRotated(
3941
_angle,
4042
spriteAnchorPosition,
41-
(canvas) => _sprite.render(canvas, size: paintSize),
43+
(canvas) => _sprite.render(
44+
canvas,
45+
size: paintSize,
46+
overridePaint: _paint,
47+
),
4248
);
4349
}
4450
}

packages/flame/lib/src/widgets/sprite_widget.dart

+11-1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ class SpriteWidget extends StatelessWidget {
2525
/// A builder function that is called while the loading is on the way
2626
final WidgetBuilder? loadingBuilder;
2727

28+
/// A custom [Paint] to be used when rendering the sprite.
29+
/// When omitted the default paint from the [Sprite] class will be used.
30+
final Paint? paint;
31+
2832
final FutureOr<Sprite> _spriteFuture;
2933

3034
/// renders the [sprite] as a Widget.
@@ -36,6 +40,7 @@ class SpriteWidget extends StatelessWidget {
3640
this.angle = 0,
3741
this.errorBuilder,
3842
this.loadingBuilder,
43+
this.paint,
3944
super.key,
4045
}) : _spriteFuture = sprite;
4146

@@ -54,6 +59,7 @@ class SpriteWidget extends StatelessWidget {
5459
Vector2? srcSize,
5560
this.errorBuilder,
5661
this.loadingBuilder,
62+
this.paint,
5763
super.key,
5864
}) : _spriteFuture = Sprite.load(
5965
path,
@@ -71,6 +77,7 @@ class SpriteWidget extends StatelessWidget {
7177
sprite: sprite,
7278
anchor: anchor,
7379
angle: angle,
80+
paint: paint,
7481
);
7582
},
7683
errorBuilder: errorBuilder,
@@ -91,17 +98,20 @@ class InternalSpriteWidget extends StatelessWidget {
9198
/// The angle to rotate this [sprite], in rad. (default = 0)
9299
final double angle;
93100

101+
final Paint? paint;
102+
94103
const InternalSpriteWidget({
95104
required this.sprite,
96105
this.anchor = Anchor.topLeft,
97106
this.angle = 0,
107+
this.paint,
98108
super.key,
99109
});
100110

101111
@override
102112
Widget build(BuildContext context) {
103113
return CustomPaint(
104-
painter: SpritePainter(sprite, anchor, angle: angle),
114+
painter: SpritePainter(sprite, anchor, paint, angle: angle),
105115
size: sprite.srcSize.toSize(),
106116
);
107117
}

0 commit comments

Comments
 (0)