mirror of
https://gitlab.com/veilid/veilidchat.git
synced 2024-12-27 08:39:23 -05:00
99 lines
2.7 KiB
Dart
99 lines
2.7 KiB
Dart
|
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,
|
||
|
),
|
||
|
);
|
||
|
}
|
||
|
}
|