mcpField
L
lightweight-flutter-animations

lightweight-flutter-animations

github.com/rodydavis开发6075 次安装2 周前更新
代码仓库

关于 lightweight-flutter-animations

一种 Flutter 动画实现方法,通过使用 ticker 的 AnimationWidget 替代 State 基类。指南展示了用 CustomPainter 绘制,以及无需调用 setState 即可重建界面。

主要功能

  1. 01基于 ticker 的动画组件
  2. 02跟踪经过时间与时间差
  3. 03访问布局约束
  4. 04CustomPainter 画布示例

适用场景

  1. 01构建 ticker 驱动的动画
  2. 02在画布上绘制动画内容

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/rodydavis/skills --skill lightweight-flutter-animations

安装后在 Claude Code 中输入/lightweight-flutter-animations确认已加载。

详细介绍

轻量级 Flutter 动画

概述

首先,我们需要创建抽象类:

abstract class AnimationWidget<T extends StatefulWidget> extends State<T>
    with SingleTickerProviderStateMixin {
  Duration elapsed = Duration.zero;
  Duration delta = Duration.zero;
  late final Ticker ticker;
  BoxConstraints constraints = const BoxConstraints.tightFor();

  @override
  void initState() {
    super.initState();
    ticker = createTicker((elapsed) {
      delta = elapsed - this.elapsed;
      this.elapsed = elapsed;
      update(elapsed);
      if (mounted) setState(() {});
    });
    ticker.start();
    WidgetsBinding.instance.addPostFrameCallback(start);
  }

  @override
  void dispose() {
    ticker.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return LayoutBuilder(builder: (context, dimens) {
      constraints = dimens;
      return paint(context, dimens);
    });
  }

  void start(Duration time) {}

  void update(Duration time);

  Widget paint(BuildContext context, BoxConstraints constraints);
}

这样我们就可以用 AnimationWidget 替换 State,无需调用 setState 即可重建 UI。

示例

此示例需要一个内联画布绘制器:

class InlinePainter extends CustomPainter {
  InlinePainter({
    required this.draw,
    super.repaint,
  });

  final void Function(Canvas canvas, Size size) draw;

  @override
  void paint(Canvas canvas, Size size) {
    draw(canvas, size);
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) => true;
}

以下是使用新组件类的示例:

import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';

class SimpleExample extends StatefulWidget {
  const SimpleExample({Key? key}) : super(key: key);

  @override
  State<SimpleExample> createState() => _SimpleExampleState();
}

class _SimpleExampleState extends AnimationWidget<SimpleExample> {
  var x = 0.0;
  var y = 0.0;
  var z = 0.0;

  @override
  void update(Duration time) {
    final t = delta.inMilliseconds / 1000;
    x += t;
    y += t;
    z += t;
  }

  @override
  Widget paint(BuildContext context, BoxConstraints constraints) {
    return Material(
      child: Center(
        child: Container(
          width: 100,
          height: 100,
          transform: Matrix4.identity()
            ..rotateX(x)
            ..rotateY(y)
            ..rotateZ(z),
          child: const Text(
            'Hello World',
            style: TextStyle(
              fontSize: 30,
              fontWeight: FontWeight.bold,
            ),
          ),
        ),
      ),
    );
  }
}

演示

评论

支持 Markdown