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

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

相关推荐
码出钞能力41 分钟前
更换libc.so导致linux变砖,通过LD_PRELOAD挽救
linux·服务器
小马学嵌入式~42 分钟前
嵌入式 SQLite 数据库开发笔记
linux·c语言·数据库·笔记·sql·学习·sqlite
小猪咪piggy1 小时前
【JavaEE】(24) Linux 基础使用和程序部署
linux·运维·服务器
Haven-1 小时前
Linux常见命令
linux·基本指令
IT 小阿姨(数据库)2 小时前
PgSQL中pg_stat_user_tables 和 pg_stat_user_objects参数详解
linux·运维·数据库·sql·postgresql·oracle
MChine慕青2 小时前
顺序表与单链表:核心原理与实战应用
linux·c语言·开发语言·数据结构·c++·算法·链表
卢叁2 小时前
Flutter之自定义TabIndicator
前端·flutter
虎头金猫2 小时前
如何在Linux上使用Docker在本地部署开源PDF工具Stirling PDF:StirlingPDF+cpolar让专业操作像在线文档一样简单
linux·运维·ubuntu·docker·pdf·开源·centos
努力学习的小廉3 小时前
深入了解linux系统—— 线程同步
linux·服务器·数据库·算法
sinat_602035363 小时前
模块与包的导入
运维·服务器·开发语言·python