Skip to content

Commit

Permalink
feat: add face in
Browse files Browse the repository at this point in the history
  • Loading branch information
alextekartik committed Oct 11, 2024
1 parent 6385f44 commit 1eba87c
Show file tree
Hide file tree
Showing 3 changed files with 154 additions and 1 deletion.
6 changes: 5 additions & 1 deletion app_widget/analysis_options.yaml
Original file line number Diff line number Diff line change
@@ -1,2 +1,6 @@
# tekartik flutter recommended lints (extension over google lints and pedantic)
include: package:tekartik_lints_flutter/strict.yaml
include: package:tekartik_lints_flutter/package.yaml

linter:
rules:
public_member_api_docs: false
1 change: 1 addition & 0 deletions app_widget/lib/src/confirm_dialog.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:flutter/material.dart';

/// A simple dialog button
class DialogButton extends StatelessWidget {
final String text;
final VoidCallback onPressed;
Expand Down
148 changes: 148 additions & 0 deletions app_widget/lib/view/fade_in.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
import 'dart:async';

import 'package:flutter/widgets.dart';

class FadeIn extends StatefulWidget {
/// Fade-in controller
final FadeInController? controller;

/// Child widget to fade-in
final Widget? child;

/// Duration of fade-in. Defaults to 250ms
final Duration duration;

/// Fade-in curve. Defaults to [Curves.easeIn]
final Curve curve;

const FadeIn({
super.key,
this.controller,
this.child,
this.duration = const Duration(milliseconds: 250),
this.curve = Curves.easeIn,
});

@override
State<FadeIn> createState() => _FadeInState();
}

enum FadeInAction {
fadeIn,
fadeOut,
}

/// Fade-in controller which dispatches fade-in/fade-out actions
class FadeInController {
final _streamController = StreamController<FadeInAction>();

/// Automatically starts the initial fade-in. Defaults to false
final bool autoStart;

FadeInController({this.autoStart = false});

void dispose() => _streamController.close();

/// Fades-in child
void fadeIn() => run(FadeInAction.fadeIn);

/// Fades-out child
void fadeOut() => run(FadeInAction.fadeOut);

/// Dispatches a [FadeInAction]
void run(FadeInAction action) => _streamController.add(action);

/// Stream of [FadeInAction]s dispatched by this controller
Stream<FadeInAction> get stream => _streamController.stream;
}

class _FadeInState extends State<FadeIn> with TickerProviderStateMixin {
late AnimationController _controller;
StreamSubscription<FadeInAction>? _listener;

@override
void initState() {
super.initState();

_controller = AnimationController(
vsync: this,
duration: widget.duration,
);

_setupCurve();

if (widget.controller?.autoStart != false) {
fadeIn();
}

_listen();
}

void _setupCurve() {
final curve = CurvedAnimation(parent: _controller, curve: widget.curve);

Tween(
begin: 0.0,
end: 1.0,
).animate(curve);
}

void _listen() {
if (_listener != null) {
_listener!.cancel();
_listener = null;
}

if (widget.controller != null) {
_listener = widget.controller!.stream.listen(_onAction);
}
}

void _onAction(FadeInAction action) {
switch (action) {
case FadeInAction.fadeIn:
fadeIn();
break;
case FadeInAction.fadeOut:
fadeOut();
break;
}
}

@override
void didUpdateWidget(FadeIn oldWidget) {
if (oldWidget.controller != widget.controller) {
_listen();
}

if (oldWidget.duration != widget.duration) {
_controller.duration = widget.duration;
}

if (oldWidget.curve != widget.curve) {
_setupCurve();
}

super.didUpdateWidget(oldWidget);
}

@override
void dispose() {
_controller.dispose();
super.dispose();
}

@override
Widget build(BuildContext context) {
return FadeTransition(
opacity: _controller,
child: widget.child,
);
}

/// Fades-in child
void fadeIn() => _controller.forward();

/// Fades-out child
void fadeOut() => _controller.reverse();
}

0 comments on commit 1eba87c

Please sign in to comment.