Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Added glow effect using maskFilter #2129

Merged
merged 20 commits into from
Oct 29, 2022
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions examples/lib/stories/effects/glow_effect_example.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import 'package:flame/components.dart';
import 'package:flame/effects.dart';
import 'package:flame/game.dart';
import 'package:flame/input.dart';
import 'package:flutter/material.dart';

void main() {
runApp(GameWidget(game: GlowEffectExample()));
}

class GlowEffectExample extends FlameGame with TapDetector {
static const String description = '''
In this example we show how the `GlowEffect` can be used.
''';

@override
Future<void> onLoad() async {
final paint = Paint()
..color = const Color(0xff39FF14)
..style = PaintingStyle.stroke;

add(
CircleComponent(
radius: 50,
position: Vector2(300, 400),
paint: paint,
)..add(
GlowEffect(
10.0,
EffectController(
duration: 3,
// reverseDuration: 1.5,
dipakp2726 marked this conversation as resolved.
Show resolved Hide resolved
infinite: true,
),
),
),
);
}
}
1 change: 1 addition & 0 deletions packages/flame/lib/effects.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export 'src/effects/controllers/speed_effect_controller.dart';
export 'src/effects/controllers/zigzag_effect_controller.dart';
export 'src/effects/effect.dart';
export 'src/effects/effect_target.dart';
export 'src/effects/glow_effect.dart';
export 'src/effects/move_along_path_effect.dart';
export 'src/effects/move_by_effect.dart';
export 'src/effects/move_effect.dart';
Expand Down
14 changes: 12 additions & 2 deletions packages/flame/lib/src/components/mixins/has_paint.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'dart:ui';

import 'package:flame/components.dart';
import 'package:flame/effects.dart';
import 'package:flame/src/effects/provider_interfaces.dart';
import 'package:flame/src/palette.dart';
import 'package:meta/meta.dart';

Expand All @@ -14,9 +15,10 @@ import 'package:meta/meta.dart';
/// [T], that can be omitted if the component only has one paint.
/// [paintLayers] paints should be drawn in list order during the render. The
/// main Paint is the first element.
mixin HasPaint<T extends Object> on Component implements OpacityProvider {
mixin HasPaint<T extends Object> on Component
implements OpacityProvider, PaintProvider {
late final Map<T, Paint> _paints = {};
Paint paint = BasicPalette.white.paint();
Paint _paint = BasicPalette.white.paint();
dipakp2726 marked this conversation as resolved.
Show resolved Hide resolved

@internal
List<Paint>? paintLayersInternal;
Expand Down Expand Up @@ -124,6 +126,14 @@ mixin HasPaint<T extends Object> on Component implements OpacityProvider {
}
}

@override
Paint get paint => _paint;

@override
set paint(Paint value) {
_paint = value;
}

/// Creates an [OpacityProvider] for given [paintId] and can be used as
/// `target` for [OpacityEffect].
OpacityProvider opacityProviderOf(T paintId) {
Expand Down
30 changes: 30 additions & 0 deletions packages/flame/lib/src/effects/glow_effect.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import 'dart:ui';

import 'package:flame/effects.dart';
import 'package:flame/src/effects/provider_interfaces.dart';

/// Change the MaskFilter on Paint of a component over time.
///
/// This effect applies incremental changes to the MaskFilter on Paint of a
/// component and
/// requires that any other effect or update logic applied to the same component
/// also used incremental updates.
dipakp2726 marked this conversation as resolved.
Show resolved Hide resolved
class GlowEffect extends Effect with EffectTarget<PaintProvider> {
GlowEffect(this.strength, super.controller, {this.style = BlurStyle.outer});

final BlurStyle style;
dipakp2726 marked this conversation as resolved.
Show resolved Hide resolved
final double strength;

@override
void apply(double progress) {
final _value = strength * progress;

target.paint.maskFilter = MaskFilter.blur(style, _value);
}

@override
void reset() {
super.reset();
target.paint.maskFilter = null;
}
}
10 changes: 10 additions & 0 deletions packages/flame/lib/src/effects/provider_interfaces.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'dart:ui';

import 'package:flame/components.dart';

/// Interface for a component that can be affected by move effects.
Expand Down Expand Up @@ -64,3 +66,11 @@ abstract class OpacityProvider {
double get opacity;
set opacity(double value);
}

/// Interface for a component that can be affected by Paint effects.
///
/// See [HasPaint] for an example implementation.
abstract class PaintProvider {
Paint get paint;
set paint(Paint value);
}