flutter开发实战-CustomClipper裁剪长图帧动画效果

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

学习记录,每天不停进步。

相关推荐
了一li1 小时前
Qt中的QProcess与Boost.Interprocess:实现多进程编程
服务器·数据库·qt
日记跟新中1 小时前
Ubuntu20.04 修改root密码
linux·运维·服务器
唐小旭1 小时前
服务器建立-错误:pyenv环境建立后python版本不对
运维·服务器·python
码农君莫笑1 小时前
信管通低代码信息管理系统应用平台
linux·数据库·windows·低代码·c#·.net·visual studio
明 庭1 小时前
Ubuntu下通过Docker部署NGINX服务器
服务器·ubuntu·docker
BUG 4041 小时前
Linux——Shell
linux·运维·服务器
007php0071 小时前
Go语言zero项目部署后启动失败问题分析与解决
java·服务器·网络·python·golang·php·ai编程
yang_shengy1 小时前
【JavaEE】网络(6)
服务器·网络·http·https
大霞上仙2 小时前
Linux 多命令执行
linux·运维·服务器