Flutter利用Hero组件实现自定义路径效果的动画
作者:岛上码农 发布时间:2023-06-25 13:46:29
前言
我们在 页面切换转场动画,英雄救场更有趣!介绍了 Hero 动画效果,使用 Hero 用于转场能够提供非常不错的体验。既然称之为英雄,肯定还有其他技能,本篇我们就来探索一下 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 组件动画前后能够达到矩形指定位置和大小。下面一张图是官网的说明图:
image.png
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;
}
}
运行效果
可以看到结束的时候,有个回弹效果,那是因为使用了Curves.easeInOutBack
这个曲线。源码已上传至:动画相关源码。
运行效果
来源:https://mp.weixin.qq.com/s/irXxttIRDFyGkPJyUTnp8w
猜你喜欢
- 1.返回ModelAndView对象(.jsp)controller代码:package controller;import java.ut
- 你知道String、StringBuilder、Stringbuffer的区别吗?当你创建字符串的时候,有考虑过该使用哪个吗?别急,这篇文章
- 对于大文件的处理,无论是用户端还是服务端,如果一次性进行读取发送、接收都是不可取,很容易导致内存问题。所以对于大文件上传,采用切块分段上传,
- activity A和BA 获取数据的activity B返回数据的activity点击A上的按钮,在A的textview上显示
- 接触过Android开发的同学们都知道在Android中访问程序资源基本都是通过资源ID来访问。这样开发起来很简单,并且可以不去考虑各种分辨
- 在本博客中,可以找到一篇《c#实现输出的字符靠右对齐的示例》它有教大家怎样实现字符串输出进行左齐或者是右对齐。本篇的方法,超简单,是使用st
- 简介官方API文档Scaffold的of方法说明有说明调用Scaffold.of方法是在Scallfold的子组件的Build方法中,也就是
- UI 妹纸又给了个图叫我做,我一看是这样的:我们首先把这个控件划分成 几个部分:1.底下部分的直线 :2.左右两边的半圆
- Note:这篇文章是基于Android Studio 3.01版本的,NDK是R16。step1:创建一个包含C++的项目其他默认就可以了。
- 前言当系统的并发比较高的时候,日志的处理输出也是一种性能的开销负担,所以,选择一个中间件来处理消费日志必不可少!下面是spring boot
- 前言本篇文章 中写到的是 flutter 调用了Android 原生的 TextView 案例添加原生组件的流程基本上可以描述为:1 and
- 1. 前言现在很多应用都有小悬浮窗的功能,比如看直播的时候,通过Home键返回桌面,直播的小窗口仍可以在屏幕上显示。下面将介绍下悬浮窗的的一
- 无论哪种界面框架输入文本框都是非常重要的控件, 但是发现flutter中的输入框TextField介绍的虽然多,但是各个属性怎么组合满足需要
- Android ListView的Item点击效果的定制
- 前言最近看插件库上少有的取色器大都是圆形的或者奇奇怪的的亚子,所以今天做两个矩形的颜色取色器提示:以下是本篇文章正文内容,下面案例可供参考一
- 背景在接口请求过程中,传递json对象,springboot转换为实体VO对象后,所有属性都为null。post请求:后台接收请求:当时就懵
- 本文实例为大家分享了java简单实现斗地主发牌的具体代码,供大家参考,具体内容如下问题:参考斗地主的游戏规则,完成一个发牌的功能(54张牌,
- SharedPreferences是Android中最容易理解的数据存储技术,实际上SharedPreferences处理的就是一个key-
- 一、获取android工程里面的各种资源的id; 1.1 string型 比如下面: << string name=”OK”&g
- 1、volley 项目地址 https://github.com/smanikandan14/Volley-demo (1)&nb