flutter开发实战-CustomClipper裁剪长图帧动画效果
在开发过程中,经常遇到帧动画的每一帧图显示在超长图上,需要处理这种帧动画效果。我这里使用的是CustomClipper
一、CustomClipper
CustomClipper继承于Listenable
abstract class CustomClipper extends Listenable
我们实现CustomClipper子类来实现裁剪功能
dart
class PicCustomClipper extends CustomClipper<Rect> {
PicCustomClipper(this.rect);
Rect rect;
// Rect getClip(Size size) => Rect.fromLTWH(0.0, 15.0, 40.0, 30.0);
@override
Rect getClip(Size size) => rect;
@override
bool shouldReclip(CustomClipper<Rect> oldClipper) => true;
}
- getClip()是用于获取剪裁区域的接口,由于图片大小是60×60,
- 我们返回剪裁区域为Rect.fromLTWH(10.0, 15.0, 40.0, 30.0),即图片中部40×30像素的范围。
shouldReclip() 接口决定是否重新剪裁。
如果在应用中,剪裁区域始终不会发生变化时应该返回false,这样就不会触发重新剪裁,避免不必要的性能开销。
如果剪裁区域会发生变化(比如在对剪裁区域执行一个动画),那么变化后应该返回true来重新执行剪裁。
二、实现播放帧动画
CustomClipper裁剪长图后,每隔一段时间展示长图的不同区域,实现帧动画的连贯效果。
dart
class PicFrameAnim extends StatefulWidget {
const PicFrameAnim({required this.size, required this.imageSize, Key? key})
: super(key: key);
final Size size;
final Size imageSize;
@override
_PicFrameAnimState createState() => _PicFrameAnimState();
}
class _PicFrameAnimState extends State<PicFrameAnim>
with TickerProviderStateMixin {
late Duration _duration;
late int _imageIndex;
late int _currentIndex;
// 定义一个裁剪
late PicCustomClipper _clipper = PicCustomClipper(
Rect.fromLTWH(0.0, 0.0, widget.size.width, widget.size.height));
@override
void initState() {
// TODO: implement initState
super.initState();
_duration = Duration(milliseconds: 200);
_imageIndex = 1;
_currentIndex = 0;
if (widget.size.height > 0) {
_imageIndex = (widget.imageSize.height / widget.size.height).floor();
}
if (_imageIndex >= 2) {
updateImage();
}
}
void updateImage() {
if (_currentIndex >= _imageIndex) {
_currentIndex = 0;
}
_clipper = PicCustomClipper(Rect.fromLTWH(
0.0,
_currentIndex * (widget.size.height),
widget.size.width,
widget.size.height));
_currentIndex++;
if (mounted) {
setState(() {});
}
Future.delayed(_duration, () {
if (mounted) {
updateImage();
}
});
}
@override
void dispose() {
// TODO: implement dispose
super.dispose();
}
Matrix4 buildMatrix4() {
double dx = 0;
double dy = 0;
///Y轴方向平移
dy = -_currentIndex * (widget.size.height) + (widget.size.height);
///在XOY平面的平移
return Matrix4.translationValues(dx, dy, 0);
}
@override
Widget build(BuildContext context) {
return Container(
width: widget.imageSize.width,
height: widget.imageSize.height,
child: Transform(
///构建Matrix4
transform: buildMatrix4(),
///中心对齐
alignment: Alignment.center,
child: ClipRect(
clipper: _clipper,
child: buildBGArrow(context),
),
),
);
}
Widget buildBGPicImage(BuildContext context) {
return Image.network(
"https://avatars2.githubusercontent.com/u/20411648?s=460&v=4",
width: 100.0,
height: 300.0,
);
}
}
三、小结
flutter开发实战-CustomClipper裁剪长图帧动画效果。
https://blog.csdn.net/gloryFlow/article/details/132253251
学习记录,每天不停进步。