veilidchat/lib/tools/animations.dart

99 lines
2.7 KiB
Dart
Raw Normal View History

2023-07-26 22:38:09 -04:00
import 'package:flutter/material.dart';
import 'package:flutter_animate/flutter_animate.dart';
enum AnimationTrigger {
onPageLoad,
onActionTrigger,
}
class AnimationInfo {
AnimationInfo({
required this.trigger,
required this.effects,
this.loop = false,
this.reverse = false,
this.applyInitialState = true,
});
final AnimationTrigger trigger;
final List<Effect<dynamic>> effects;
final bool applyInitialState;
final bool loop;
final bool reverse;
late Adapter adapter;
late AnimationController controller;
}
void createAnimation(AnimationInfo animation, TickerProvider vsync) {
final newController = AnimationController(vsync: vsync);
animation
..controller = newController
..adapter = (ValueAdapter(0)..attach(newController));
}
void setupAnimations(Iterable<AnimationInfo> animations, TickerProvider vsync) {
for (final animation in animations) {
createAnimation(animation, vsync);
}
}
extension AnimatedWidgetExtension on Widget {
Widget animateOnPageLoad(AnimationInfo animationInfo) => Animate(
controller:
animationInfo.applyInitialState ? null : animationInfo.controller,
adapter: animationInfo.applyInitialState ? null : animationInfo.adapter,
effects: animationInfo.effects,
child: this,
onPlay: (controller) => animationInfo.loop
? controller.repeat(reverse: animationInfo.reverse)
: null,
onComplete: (controller) => !animationInfo.loop && animationInfo.reverse
? controller.reverse()
: null);
Widget animateOnActionTrigger(
AnimationInfo animationInfo, {
bool hasBeenTriggered = false,
}) =>
hasBeenTriggered || animationInfo.applyInitialState
? Animate(
controller: animationInfo.controller,
adapter: animationInfo.adapter,
effects: animationInfo.effects,
child: this)
: this;
}
class TiltEffect extends Effect<Offset> {
const TiltEffect({
super.delay,
super.duration,
super.curve,
Offset? begin,
Offset? end,
}) : super(
begin: begin ?? Offset.zero,
end: end ?? Offset.zero,
);
@override
Widget build(
BuildContext context,
Widget child,
AnimationController controller,
EffectEntry entry,
) {
final animation = buildAnimation(controller, entry);
return getOptimizedBuilder<Offset>(
animation: animation,
builder: (_, __) => Transform(
transform: Matrix4.identity()
..setEntry(3, 2, 0.001)
..rotateX(animation.value.dx)
..rotateY(animation.value.dy),
alignment: Alignment.center,
child: child,
),
);
}
}