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

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

相关推荐
厦门辰迈智慧科技有限公司36 分钟前
城市排水管网流量监测系统解决方案
运维·服务器
qq_339282231 小时前
centos中libc.so.6No such file的解决方式
linux·运维·centos
leoufung1 小时前
ECPF 简介
linux·网络·kernel
在肯德基吃麻辣烫2 小时前
Netdata在Ubuntu环境下的安装与配置:构建实时系统监控与性能分析平台
linux·运维·ubuntu
只可远观3 小时前
Flutter目录结构介绍、入口、Widget、Center组件、Text组件、MaterialApp组件、Scaffold组件
前端·flutter
周胡杰3 小时前
组件导航 (HMRouter)+flutter项目搭建-混合开发+分栏效果
前端·flutter·华为·harmonyos·鸿蒙·鸿蒙系统
国际云,接待3 小时前
云服务器的运用自如
服务器·架构·云计算·腾讯云·量子计算
肥肥呀呀呀3 小时前
flutter Stream 有哪两种订阅模式。
flutter
愚戏师3 小时前
Linux复习笔记(六)shell编程
linux·笔记·shell
大胆飞猪4 小时前
Linux操作系统--进程间通信(system V共享内存)
linux