这篇“Flutter怎么利用Hero组件实现自定义路径动画效果”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Flutter怎么利用Hero组件实现自定义路径动画效果”文章吧。
Hero 的定义
Hero 组件是一个 StatefulWidget,构造方法如下:
const Hero({ Key? key, required this.tag, this.createRectTween, this.flightShuttleBuilder, this.placeholderBuilder, this.transitionOnUserGestures = false, required this.child,})
其中 createRectTween
就是一个矩形插值,用于控制 Hero 组件的路径。实际上,和普通动画一样,也是有一个时间曲线,取值范围是0-1.0,然后createRectTween
保证 Hero 组件动画前后能够达到矩形指定位置和大小。下面一张图是官网的说明图:
RectTween
RectTween 和 Tween类似,实际上就是矩阵在动画过程中的变化。我们来看 RectTween 的定义:
class RectTween extends Tween<Rect?> { RectTween({ Rect? begin, Rect? end }) : super(begin: begin, end: end); /// 通过给定的动画时间值构建新的插值矩形 @override Rect? lerp(double t) => Rect.lerp(begin, end, t);}
这个类很简单,其实就是每次动画时间点上调用 Rect.lerp
构建一个插值的矩形。Rect.lerp 方法如下:
static Rect? lerp(Rect? a, Rect? b, double t) { assert(t != null); if (b == null) { if (a == null) { return null; } else { final double k = 1.0 - t; return Rect.fromLTRB(a.left * k, a.top * k, a.right * k, a.bottom * k); } } else { if (a == null) { return Rect.fromLTRB(b.left * t, b.top * t, b.right * t, b.bottom * t); } else { return Rect.fromLTRB( _lerpDouble(a.left, b.left, t), _lerpDouble(a.top, b.top, t), _lerpDouble(a.right, b.right, t), _lerpDouble(a.bottom, b.bottom, t), ); } } }
在矩形 a 和矩形 b 都不为空的时候,返回的就是一个通过定点定义的新的矩形。这里的关键是_lerpDouble 方法,其实最终就是根据动画时间完成顶点的移动。
double? lerpDouble(num? a, num? b, double t) { /// ... return a * (1.0 - t) + b * t;}
也就是从矩形 a 的顶点逐步移动到矩形 b的顶点,从而完成了两个矩形的动画过渡。有了这个基础我们就可以构建自定义的 RectTween 了。和我们的之前说过的动画曲线(动画曲线天天用,你能自己整一个吗?看完这篇你就会了!)是类似的。
自定义RectTween
我们来一个自定义 RectTween
,然后保证起始点是矩形 a,结束点是矩形 b,然后中间沿曲线变动就可以了。下面是我们利用曲线将时间转换后得到的一个自定义 RectTween
。其中使用曲线转换后的transformT
取值还是从0-1.0,然后使用_rectMove
方法就能实现从开始的矩形过渡到结束的矩形了。
class CustomRectTween extends RectTween { final Rect begin; final Rect end; CustomRectTween({required this.begin, required this.end}) : super(begin: begin, end: end); @override Rect lerp(double t) { double transformT = Curves.easeInOutBack.transform(t); var rect = Rect.fromLTRB( _rectMove(begin.left, end.left, transformT), _rectMove(begin.top, end.top, transformT), _rectMove(end.right, end.right, transformT), _rectMove(begin.bottom, end.bottom, transformT)); return rect; } double _rectMove(double begin, double end, double t) { return begin * (1 - t) + end * t; }}
以上就是关于“Flutter怎么利用Hero组件实现自定义路径动画效果”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注编程网行业资讯频道。