Skip to content

Instantly share code, notes, and snippets.

@jcdang
Created February 25, 2022 23:28
Show Gist options
  • Save jcdang/884b5bddaffd03939b30d63ba84c34b7 to your computer and use it in GitHub Desktop.
Save jcdang/884b5bddaffd03939b30d63ba84c34b7 to your computer and use it in GitHub Desktop.
Should go in flutter/lib/src/widgets/implicit_animations.dart
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
class AnimatedTransform extends ImplicitlyAnimatedWidget {
const AnimatedTransform({
Key? key,
this.child,
required this.transform,
this.alignment = Alignment.center,
this.filterQuality,
Curve curve = Curves.linear,
required Duration duration,
VoidCallback? onEnd,
this.alwaysIncludeSemantics = false,
}) : super(key: key, curve: curve, duration: duration, onEnd: onEnd);
/// The widget below this widget in the tree.
///
/// {@macro flutter.widgets.ProxyWidget.child}
final Widget? child;
final Matrix4? transform;
/// The alignment of the origin of the coordinate system in which the scale
/// takes place, relative to the size of the box.
///
/// For example, to set the origin of the scale to bottom middle, you can use
/// an alignment of (0.0, 1.0).
final Alignment alignment;
/// The filter quality with which to apply the transform as a bitmap operation.
///
/// {@macro flutter.widgets.Transform.optional.FilterQuality}
final FilterQuality? filterQuality;
/// Whether the semantic information of the children is always included.
///
/// Defaults to false.
final bool alwaysIncludeSemantics;
@override
ImplicitlyAnimatedWidgetState<AnimatedTransform> createState() =>
_AnimatedTransformState();
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty('transform', transform,
defaultValue: Matrix4.identity()));
properties.add(DiagnosticsProperty<Alignment>('alignment', alignment,
defaultValue: Alignment.center));
properties.add(EnumProperty<FilterQuality>('filterQuality', filterQuality,
defaultValue: null));
}
}
class _AnimatedTransformState
extends ImplicitlyAnimatedWidgetState<AnimatedTransform> {
Tween<Matrix4>? _transform;
late Animation<Matrix4> _animationTransform;
@override
void forEachTween(TweenVisitor<dynamic> visitor) {
_transform = visitor(_transform, widget.transform,
(dynamic value) => Tween<Matrix4>(begin: value as Matrix4))
as Tween<Matrix4>?;
}
@override
void didUpdateTweens() {
_animationTransform = animation.drive(_transform!);
}
@override
Widget build(BuildContext context) {
return TransformTransition(
transform: _animationTransform,
alignment: widget.alignment,
child: widget.child,
);
}
}
class TransformTransition extends AnimatedWidget {
const TransformTransition({
Key? key,
required Animation<Matrix4> transform,
this.alignment = Alignment.center,
this.filterQuality,
this.child,
}) : super(key: key, listenable: transform);
Animation<Matrix4> get transform => listenable as Animation<Matrix4>;
/// The alignment of the origin of the coordinate system in which the scale
/// takes place, relative to the size of the box.
///
/// For example, to set the origin of the scale to bottom middle, you can use
/// an alignment of (0.0, 1.0).
final Alignment alignment;
/// The filter quality with which to apply the transform as a bitmap operation.
///
/// {@macro flutter.widgets.Transform.optional.FilterQuality}
final FilterQuality? filterQuality;
/// The widget below this widget in the tree.
///
/// {@macro flutter.widgets.ProxyWidget.child}
final Widget? child;
@override
Widget build(BuildContext context) {
return Transform(
transform: transform.value,
alignment: alignment,
filterQuality: filterQuality,
child: child,
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment