Created
September 10, 2022 20:04
-
-
Save Roaa94/1fd3c81c93de4c0b4009debca6b6bd07 to your computer and use it in GitHub Desktop.
Flutter Vikings Talk Animation Demo - MouseRegionEffect widget code
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/gestures.dart'; | |
import 'package:flutter/material.dart'; | |
import 'package:recipes_ui/core/widgets/adaptive_offset_effect.dart'; | |
class MouseRegionEffect extends StatefulWidget { | |
const MouseRegionEffect({ | |
Key? key, | |
required this.width, | |
required this.height, | |
required this.child, | |
this.offsetMultiplier = 1, | |
this.childBuilder, | |
this.maxMovableDistance = 10, | |
}) : assert(child != null && childBuilder == null), | |
super(key: key); | |
const MouseRegionEffect.builder({ | |
Key? key, | |
required this.width, | |
required this.height, | |
this.child, | |
this.offsetMultiplier = 1, | |
required this.childBuilder, | |
this.maxMovableDistance = 10, | |
}) : assert(childBuilder != null), | |
super(key: key); | |
final double width; | |
final double height; | |
final OffsetEffectBuilder? childBuilder; | |
final Widget? child; | |
final double offsetMultiplier; | |
final double maxMovableDistance; | |
@override | |
State<MouseRegionEffect> createState() => _MouseRegionEffectState(); | |
} | |
class _MouseRegionEffectState extends State<MouseRegionEffect> { | |
Offset offset = const Offset(0, 0); | |
Alignment mouseRegionAlignment = Alignment.bottomRight; | |
Alignment alignmentFromOffset(Offset mousePosition) { | |
if (mousePosition.dx > widget.width / 2) { | |
return mousePosition.dy > widget.height / 2 | |
? Alignment.bottomRight | |
: Alignment.topRight; | |
} else { | |
return mousePosition.dy > widget.height / 2 | |
? Alignment.bottomLeft | |
: Alignment.topLeft; | |
} | |
} | |
Offset offsetFromMousePosition(Offset mousePosition) { | |
Alignment alignment = alignmentFromOffset(mousePosition); | |
return Offset( | |
widget.maxMovableDistance * alignment.x * -1, | |
widget.maxMovableDistance * alignment.y * -1, | |
); | |
} | |
@override | |
Widget build(BuildContext context) { | |
return MouseRegion( | |
hitTestBehavior: HitTestBehavior.translucent, | |
onEnter: (PointerEnterEvent event) { | |
setState(() { | |
offset = offsetFromMousePosition(event.localPosition); | |
}); | |
}, | |
onHover: (PointerHoverEvent event) { | |
setState(() { | |
offset = offsetFromMousePosition(event.localPosition); | |
}); | |
}, | |
onExit: (PointerExitEvent event) { | |
setState(() { | |
offset = offsetFromMousePosition(event.localPosition); | |
}); | |
}, | |
child: _buildChild(context, widget.child), | |
); | |
} | |
Widget _buildChild(BuildContext context, Widget? child) { | |
if (widget.childBuilder != null) { | |
return widget.childBuilder!.call(context, offset, child); | |
} else { | |
return TweenAnimationBuilder( | |
tween: Tween<Offset>( | |
begin: Offset.zero, | |
end: offset * widget.offsetMultiplier, | |
), | |
duration: const Duration(milliseconds: 500), | |
curve: Curves.easeOutBack, | |
builder: (context, Offset offset, child) => Transform.translate( | |
offset: offset, | |
child: child, | |
), | |
child: child, | |
); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment