Skip to content

Commit 31aa641

Browse files
committed
Major groundwork for effects & masking.
1 parent 9ff2b94 commit 31aa641

19 files changed

+609
-117
lines changed

flare_dart/lib/actor.dart

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,14 @@ import 'dart:async';
22
import "dart:convert";
33
import "dart:typed_data";
44

5+
import 'package:flare_dart/actor_layer_effect_renderer.dart';
6+
57
import "actor_artboard.dart";
68
import "actor_color.dart";
9+
import 'actor_drop_shadow.dart';
710
import "actor_ellipse.dart";
811
import "actor_image.dart";
12+
import 'actor_inner_shadow.dart';
913
import "actor_path.dart";
1014
import "actor_polygon.dart";
1115
import "actor_rectangle.dart";
@@ -101,6 +105,12 @@ abstract class Actor {
101105

102106
RadialGradientStroke makeRadialStroke();
103107

108+
ActorDropShadow makeDropShadow();
109+
110+
ActorInnerShadow makeInnerShadow();
111+
112+
ActorLayerEffectRenderer makeLayerEffectRenderer();
113+
104114
Future<bool> loadAtlases(List<Uint8List> rawAtlases);
105115

106116
Future<bool> load(ByteData data, dynamic context) async {
@@ -144,6 +154,17 @@ abstract class Actor {
144154
}
145155
}
146156

157+
// Resolve now.
158+
for (final ActorArtboard artboard in _artboards) {
159+
artboard.resolveHierarchy();
160+
}
161+
for (final ActorArtboard artboard in _artboards) {
162+
artboard.completeResolveHierarchy();
163+
}
164+
165+
// Sort dependencies last.
166+
artboard.sortDependencies();
167+
147168
return success;
148169
}
149170

flare_dart/lib/actor_artboard.dart

Lines changed: 99 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import "dart:math";
22
import "dart:typed_data";
33

4+
import 'package:flare_dart/actor_layer_effect_renderer.dart';
5+
46
import "actor.dart";
7+
import 'actor_blur.dart';
58
import "actor_bone.dart";
69
import "actor_color.dart";
710
import "actor_component.dart";
@@ -13,6 +16,7 @@ import "actor_flags.dart";
1316
import "actor_ik_constraint.dart";
1417
import "actor_image.dart";
1518
import "actor_jelly_bone.dart";
19+
import 'actor_mask.dart';
1620
import "actor_node.dart";
1721
import "actor_node_solo.dart";
1822
import "actor_path.dart";
@@ -21,6 +25,7 @@ import "actor_rectangle.dart";
2125
import "actor_root_bone.dart";
2226
import "actor_rotation_constraint.dart";
2327
import "actor_scale_constraint.dart";
28+
import 'actor_shadow.dart';
2429
import "actor_shape.dart";
2530
import "actor_skin.dart";
2631
import "actor_star.dart";
@@ -43,7 +48,8 @@ class ActorArtboard {
4348
ActorNode _root;
4449
List<ActorComponent> _components;
4550
List<ActorNode> _nodes;
46-
List<ActorDrawable> _drawableNodes;
51+
final List<ActorDrawable> _drawableNodes = [];
52+
final List<ActorLayerEffectRenderer> _effectRenderers = [];
4753
List<ActorAnimation> _animations;
4854
List<ActorComponent> _dependencyOrder;
4955
Actor _actor;
@@ -68,19 +74,15 @@ class ActorArtboard {
6874

6975
set overrideColor(Float32List value) {
7076
_overrideColor = value;
71-
if (_drawableNodes != null) {
72-
for (final ActorDrawable drawable in _drawableNodes) {
73-
addDirt(drawable, DirtyFlags.paintDirty, true);
74-
}
77+
for (final ActorDrawable drawable in _drawableNodes) {
78+
addDirt(drawable, DirtyFlags.paintDirty, true);
7579
}
7680
}
7781

7882
set modulateOpacity(double value) {
79-
if (_drawableNodes != null) {
80-
_modulateOpacity = value;
81-
for (final ActorDrawable drawable in _drawableNodes) {
82-
addDirt(drawable, DirtyFlags.paintDirty, true);
83-
}
83+
_modulateOpacity = value;
84+
for (final ActorDrawable drawable in _drawableNodes) {
85+
addDirt(drawable, DirtyFlags.paintDirty, true);
8486
}
8587
}
8688

@@ -218,14 +220,9 @@ class ActorArtboard {
218220
{
219221
_nodes = List<ActorNode>(_nodeCount);
220222
}
221-
if (_drawableNodeCount != 0) {
222-
_drawableNodes = List<ActorDrawable>(_drawableNodeCount);
223-
}
224223

225224
if (artboard.componentCount != 0) {
226225
int idx = 0;
227-
int drwIdx = 0;
228-
int ndIdx = 0;
229226

230227
for (final ActorComponent component in artboard.components) {
231228
if (component == null) {
@@ -234,39 +231,78 @@ class ActorArtboard {
234231
}
235232
ActorComponent instanceComponent = component.makeInstance(this);
236233
_components[idx++] = instanceComponent;
237-
if (instanceComponent is ActorNode) {
238-
_nodes[ndIdx++] = instanceComponent;
239-
}
234+
}
235+
}
236+
// Copy dependency order.
237+
_dependencyOrder = List<ActorComponent>(artboard._dependencyOrder.length);
238+
for (final ActorComponent component in artboard._dependencyOrder) {
239+
final ActorComponent localComponent = _components[component.idx];
240+
_dependencyOrder[component.graphOrder] = localComponent;
241+
localComponent.dirtMask = 255;
242+
}
243+
_flags |= ActorFlags.isDirty;
244+
_root = _components[0] as ActorNode;
245+
resolveHierarchy();
246+
completeResolveHierarchy();
247+
}
248+
249+
void resolveHierarchy() {
250+
// Resolve nodes.
251+
int anIdx = 0;
252+
253+
_drawableNodes.clear();
254+
int componentCount = this.componentCount;
255+
for (int i = 1; i < componentCount; i++) {
256+
ActorComponent c = _components[i];
257+
258+
/// Nodes can be null if we read from a file version that contained
259+
/// nodes that we don't interpret in this runtime.
260+
if (c != null) {
261+
c.resolveComponentIndices(_components);
262+
}
240263

241-
if (instanceComponent is ActorDrawable) {
242-
_drawableNodes[drwIdx++] = instanceComponent;
264+
if (c is ActorNode) {
265+
ActorNode an = c;
266+
if (an != null) {
267+
_nodes[anIdx++] = an;
243268
}
244269
}
245270
}
271+
}
246272

247-
_root = _components[0] as ActorNode;
273+
void completeResolveHierarchy() {
274+
int componentCount = this.componentCount;
248275

249-
for (final ActorComponent component in _components) {
250-
if (_root == component || component == null) {
251-
continue;
276+
// Complete resolve.
277+
for (int i = 1; i < componentCount; i++) {
278+
ActorComponent c = components[i];
279+
if (c != null) {
280+
c.completeResolve();
252281
}
253-
component.resolveComponentIndices(_components);
254282
}
255283

256-
for (final ActorComponent component in _components) {
257-
if (_root == component || component == null) {
258-
continue;
284+
// Build lists. Important to do this after all components have resolved as
285+
// layers won't be known before this.
286+
for (int i = 1; i < componentCount; i++) {
287+
ActorComponent c = components[i];
288+
if (c is ActorDrawable && c.layerEffectRenderer == null) {
289+
_drawableNodes.add(c);
290+
}
291+
if (c is ActorLayerEffectRenderer && c.layerEffectRenderer == null) {
292+
_effectRenderers.add(c);
259293
}
260-
component.completeResolve();
261294
}
262295

263-
sortDependencies();
296+
sortDrawOrder();
297+
}
264298

265-
if (_drawableNodes != null) {
266-
_drawableNodes.sort((a, b) => a.drawOrder.compareTo(b.drawOrder));
267-
for (int i = 0; i < _drawableNodes.length; i++) {
268-
_drawableNodes[i].drawIndex = i;
269-
}
299+
void sortDrawOrder() {
300+
_drawableNodes.sort((a, b) => a.drawOrder.compareTo(b.drawOrder));
301+
for (int i = 0; i < _drawableNodes.length; i++) {
302+
_drawableNodes[i].drawIndex = i;
303+
}
304+
for (final ActorLayerEffectRenderer layer in _effectRenderers) {
305+
layer.sortDrawables();
270306
}
271307
}
272308

@@ -298,13 +334,7 @@ class ActorArtboard {
298334

299335
if ((_flags & ActorFlags.isDrawOrderDirty) != 0) {
300336
_flags &= ~ActorFlags.isDrawOrderDirty;
301-
302-
if (_drawableNodes != null) {
303-
_drawableNodes.sort((a, b) => a.drawOrder.compareTo(b.drawOrder));
304-
for (int i = 0; i < _drawableNodes.length; i++) {
305-
_drawableNodes[i].drawIndex = i;
306-
}
307-
}
337+
sortDrawOrder();
308338
}
309339
}
310340

@@ -517,9 +547,32 @@ class ActorArtboard {
517547
case BlockTypes.actorPolygon:
518548
component = ActorPolygon.read(this, nodeBlock, actor.makePolygon());
519549
break;
550+
520551
case BlockTypes.actorSkin:
521552
component = ActorComponent.read(this, nodeBlock, ActorSkin());
522553
break;
554+
555+
case BlockTypes.actorLayerEffectRenderer:
556+
component = ActorDrawable.read(
557+
this, nodeBlock, actor.makeLayerEffectRenderer());
558+
break;
559+
560+
case BlockTypes.actorMask:
561+
component = ActorMask.read(this, nodeBlock, ActorMask());
562+
break;
563+
564+
case BlockTypes.actorBlur:
565+
component = ActorBlur.read(this, nodeBlock, null);
566+
break;
567+
568+
case BlockTypes.actorDropShadow:
569+
component = ActorShadow.read(this, nodeBlock, actor.makeDropShadow());
570+
break;
571+
572+
case BlockTypes.actorInnerShadow:
573+
component =
574+
ActorShadow.read(this, nodeBlock, actor.makeInnerShadow());
575+
break;
523576
}
524577
if (component is ActorDrawable) {
525578
_drawableNodeCount++;
@@ -534,49 +587,15 @@ class ActorArtboard {
534587
}
535588
}
536589

537-
_drawableNodes = List<ActorDrawable>(_drawableNodeCount);
538590
_nodes = List<ActorNode>(_nodeCount);
539591
_nodes[0] = _root;
540-
541-
// Resolve nodes.
542-
int drwIdx = 0;
543-
int anIdx = 0;
544-
545-
for (int i = 1; i <= componentCount; i++) {
546-
ActorComponent c = _components[i];
547-
548-
/// Nodes can be null if we read from a file version that contained
549-
/// nodes that we don't interpret in this runtime.
550-
if (c != null) {
551-
c.resolveComponentIndices(_components);
552-
}
553-
554-
if (c is ActorDrawable) {
555-
_drawableNodes[drwIdx++] = c;
556-
}
557-
558-
if (c is ActorNode) {
559-
ActorNode an = c;
560-
if (an != null) {
561-
_nodes[anIdx++] = an;
562-
}
563-
}
564-
}
565-
566-
for (int i = 1; i <= componentCount; i++) {
567-
ActorComponent c = components[i];
568-
if (c != null) {
569-
c.completeResolve();
570-
}
571-
}
572-
573-
sortDependencies();
574592
}
575593

576594
void initializeGraphics() {
577-
if (_drawableNodes != null) {
578-
for (final ActorDrawable drawable in _drawableNodes) {
579-
drawable.initializeGraphics();
595+
// Iterate components as some drawables may end up in other layers.
596+
for (final ActorComponent component in _components) {
597+
if (component is ActorDrawable) {
598+
component.initializeGraphics();
580599
}
581600
}
582601
}

flare_dart/lib/actor_blur.dart

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import 'actor_artboard.dart';
2+
import 'actor_component.dart';
3+
import 'actor_layer_effect.dart';
4+
import 'stream_reader.dart';
5+
6+
class ActorBlur extends ActorLayerEffect {
7+
double _blurX;
8+
double _blurY;
9+
double get blurX => _blurX;
10+
double get blurY => _blurY;
11+
12+
static ActorBlur read(
13+
ActorArtboard artboard, StreamReader reader, ActorBlur component) {
14+
component ??= ActorBlur();
15+
ActorLayerEffect.read(artboard, reader, component);
16+
component._blurX = reader.readFloat32("blurX");
17+
component._blurY = reader.readFloat32("blurY");
18+
19+
return component;
20+
}
21+
22+
void copyBlur(ActorBlur from, ActorArtboard resetArtboard) {
23+
copyLayerEffect(from, resetArtboard);
24+
_blurX = from._blurX;
25+
_blurY = from._blurY;
26+
}
27+
28+
@override
29+
void completeResolve() {
30+
// intentionally empty, no logic to complete.
31+
}
32+
33+
@override
34+
ActorComponent makeInstance(ActorArtboard resetArtboard) {
35+
ActorBlur instanceNode = ActorBlur();
36+
instanceNode.copyBlur(this, resetArtboard);
37+
return instanceNode;
38+
}
39+
40+
@override
41+
void onDirty(int dirt) {
42+
// intentionally empty
43+
}
44+
45+
@override
46+
void update(int dirt) {
47+
// intentionally empty
48+
}
49+
}

flare_dart/lib/actor_bone.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,9 @@ class ActorBone extends ActorBoneBase {
2626
if (children == null) {
2727
return;
2828
}
29-
for (final ActorNode node in children) {
30-
if (node is ActorBone) {
31-
_firstBone = node;
29+
for (final ActorComponent component in children) {
30+
if (component is ActorBone) {
31+
_firstBone = component;
3232
return;
3333
}
3434
}

0 commit comments

Comments
 (0)