You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: doc/flame/rendering/decorators.md
+57-2Lines changed: 57 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -10,6 +10,38 @@ necessary. We are planning to add shader-based decorators once Flutter fully sup
10
10
web.
11
11
12
12
13
+
## Performance considerations
14
+
15
+
Applying a Decorator to a component can have a significant performance overhead, especially when
16
+
it involves `canvas.saveLayer()`.
17
+
18
+
-**Decorators**: Use `canvas.saveLayer()` by default to isolate rendering and apply
19
+
filters. This requires off-screen buffer allocation and GPU context switches. This is
20
+
computationally expensive but essential for correct visual composition of complex
21
+
objects (see below).
22
+
-**Effects** (e.g., `OpacityEffect`, `ColorEffect`): Modify the component's properties or `Paint` directly. These are extremely fast and hardware-accelerated, but they apply to each child individually.
23
+
24
+
### Decorators vs Effects: Visual Composition
25
+
26
+
The key difference lies in how they handle composite objects (components with multiple
27
+
overlapping children):
28
+
29
+
1.**Effects (Individual Blend)**: If you apply an `OpacityEffect` to a parent component,
30
+
Flame will render each child with that opacity. If children overlap, you will see
31
+
through them to the background and to other children, creating a "double-exposure"
32
+
look.
33
+
2.**Decorators (Group Blend)**: Because decorators use `saveLayer`, they render the
34
+
entire subtree into a flat buffer first, and then apply the effect to that
35
+
buffer. This results in a uniform appearance where overlaps are not visible,
36
+
making the group look like a single solid object.
37
+
38
+
**Recommendation**:
39
+
- Use **Effects** for simple property animations and high-performance color shifts on
40
+
large numbers of units.
41
+
- Use **Decorators** for advanced post-processing (blurs, tints) and when you need
42
+
to treat a group of components as a single visual unit.
43
+
44
+
13
45
## Flame built-in decorators
14
46
15
47
@@ -157,6 +189,29 @@ limitation is that the shadows are flat and cannot interact with the environment
157
189
decorator cannot handle shadows that fall onto walls or other vertical structures.
158
190
159
191
192
+
### HueDecorator
193
+
194
+
```{flutter-app}
195
+
:sources: ../flame/examples
196
+
:page: decorator_hue
197
+
:show: widget code infobox
198
+
:width: 180
199
+
:height: 160
200
+
```
201
+
202
+
This decorator shifts the hue of the underlying component by the specified angle in radians.
203
+
204
+
```dart
205
+
final decorator = HueDecorator(hue: tau / 4);
206
+
```
207
+
208
+
Possible uses:
209
+
210
+
- alternative color schemes for enemies ("palette swapping");
211
+
- environmental changes (e.g., world turning purple/surreal);
212
+
- power-up indicators.
213
+
214
+
160
215
## Using decorators
161
216
162
217
@@ -175,7 +230,7 @@ components the `HasDecorator` mixin is not needed.
175
230
176
231
In fact, the `PositionComponent` uses its decorator in order to properly position the component on
177
232
the screen. Thus, any new decorators that you'd want to apply to the `PositionComponent` will need
178
-
to be chained (see the [](#multiple-decorators) section below).
233
+
to be chained (see the [Multiple decorators](#multiple-decorators) section below).
179
234
180
235
It is also possible to replace the root decorator of the `PositionComponent`, if you want to create
181
236
an alternative logic for how the component shall be positioned on the screen.
@@ -196,5 +251,5 @@ from its root, which usually is `component.decorator`.
0 commit comments