Flutter动态动画插件dynamic_animation的使用

Flutter 动态动画插件 dynamic_animation 的使用

dynamicTo 函数是 AnimationController 的扩展方法。它启动一个基于弹簧的动画,从当前状态(由 fromvelocity 确定)过渡到指定的 target 值。

参数

  • target (double, 必需): 定义目标值。
  • from (double, 可选): 表示起始值。如果未提供,则默认为 AnimationController 的当前值。
  • velocity (double, 可选): 表示起始速度。默认为 AnimationController 的当前速度。
  • springDescription (SpringDescription, 可选): 描述弹簧行为。默认为 defaultSpringDescription
  • tolerance (Tolerance, 可选): 确定可接受的偏差。默认为 Tolerance.defaultTolerance

总之,dynamicTo 提供了一种方便的方法来在 AnimationController 上创建弹簧动画,允许轻松指定目标值,并可选地自定义起始状态和弹簧行为参数。

示例代码

import 'package:example/spring_controller_panel.dart';
import 'package:flutter/material.dart';
import 'package:dynamic_animation/dynamic_animation.dart';

void main() {
  runApp(const MaterialApp(home: DynamicAnimationDemo()));
}

const _logoSize = 128.0;

class DynamicAnimationDemo extends StatefulWidget {
  const DynamicAnimationDemo({super.key});

  [@override](/user/override)
  State<DynamicAnimationDemo> createState() => _DynamicAnimationDemoState();
}

class _DynamicAnimationDemoState extends State<DynamicAnimationDemo> with TickerProviderStateMixin {
  var _mass = 30.0;
  var _stiffness = 1.0;
  var _damping = 1.0;
  late final _controllerX = AnimationController.unbounded(vsync: this);
  late final _controllerY = AnimationController.unbounded(vsync: this);

  // 获取弹簧描述
  SpringDescription get _spring {
    return SpringDescription(
      mass: _mass,
      stiffness: _stiffness,
      damping: _damping,
    );
  }

  // 动画到指定位置
  void _animateTo(Offset target) {
    _controllerX.dynamicTo(
      target.dx,
      springDescription: _spring,
    );
    _controllerY.dynamicTo(
      target.dy,
      springDescription: _spring,
    );
  }

  // 更新弹簧属性
  void _updateSpringProps({
    double? mass,
    double? stiffness,
    double? damping,
  }) {
    setState(() {
      _mass = mass ?? _mass;
      _stiffness = stiffness ?? _stiffness;
      _damping = damping ?? _damping;
    });
  }

  [@override](/user/override)
  void dispose() {
    _controllerX.dispose();
    _controllerY.dispose();
    super.dispose();
  }

  [@override](/user/override)
  void didChangeDependencies() {
    final size = MediaQuery.of(context).size;
    _controllerX.value = size.width / 2;
    _controllerY.value = size.height / 2;
    super.didChangeDependencies();
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      body: SafeArea(
        child: Container(
          color: Colors.white,
          child: Stack(
            children: [
              // 手势识别器
              GestureDetector(
                onTapDown: (details) {
                  _animateTo(details.localPosition);
                },
              ),
              // 动画构建器
              AnimatedBuilder(
                animation: Listenable.merge([_controllerX, _controllerY]),
                child: const FlutterLogo(size: _logoSize),
                builder: (context, child) => Positioned(
                  left: _controllerX.value - _logoSize / 2,
                  top: _controllerY.value - _logoSize / 2,
                  child: child!,
                ),
              ),
              // 弹簧控制器面板
              SpringControllerPanel(
                mass: _mass,
                stiffness: _stiffness,
                damping: _damping,
                onChange: _updateSpringProps,
              ),
            ],
          ),
        ),
      ),
    );
  }
}

更多关于Flutter动态动画插件dynamic_animation的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter动态动画插件dynamic_animation的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何使用Flutter的dynamic_animation插件来实现动态动画的示例代码。dynamic_animation插件允许你创建和控制复杂的动画,例如弹簧动画、缓动动画等。

首先,确保你的pubspec.yaml文件中已经添加了dynamic_animation依赖:

dependencies:
  flutter:
    sdk: flutter
  dynamic_animation: ^3.0.1  # 请检查最新版本号

然后,运行flutter pub get来安装依赖。

以下是一个简单的示例,展示如何使用dynamic_animation来创建一个弹簧动画:

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

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Dynamic Animation Example'),
        ),
        body: Center(
          child: SpringAnimationExample(),
        ),
      ),
    );
  }
}

class SpringAnimationExample extends StatefulWidget {
  @override
  _SpringAnimationExampleState createState() => _SpringAnimationExampleState();
}

class _SpringAnimationExampleState extends State<SpringAnimationExample> with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late SpringSimulation _simulation;
  late Animation<double> _animation;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: const Duration(seconds: 2),
      vsync: this,
    )..repeat(reverse: true);

    // 创建一个弹簧模拟对象
    _simulation = SpringSimulation(
      SpringDescription(
        mass: 1.0,
        stiffness: 100.0,
        damping: 10.0,
      ),
      0.0, // 初始位置
      1.0, // 目标位置
      0.0, // 初始速度
    );

    // 使用模拟对象创建动画
    _animation = _simulation.animate(
      _controller,
      builder: (context, value) {
        return Tween<double>(begin: 0.0, end: 1.0).animate(_controller);
      },
    )..addListener(() {
        // 每当动画值改变时,这里可以执行一些UI更新
        setState(() {});
      });
  }

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

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: _animation,
      child: Container(
        width: 100,
        height: 100,
        color: Colors.blue,
      ),
      builder: (context, child) {
        // 使用动画值来更新UI,例如改变位置或大小
        return Transform.translate(
          offset: Offset(0, _animation.value * 200 - 100), // 根据动画值移动容器
          child: child,
        );
      },
    );
  }
}

在这个示例中,我们创建了一个SpringAnimationExample组件,它使用SpringSimulation来模拟弹簧动画。动画的值用于通过Transform.translate移动一个容器。

关键步骤包括:

  1. 创建AnimationController来控制动画的时长和循环。
  2. 使用SpringSimulation来定义弹簧动画的属性,如质量、刚度和阻尼。
  3. 使用_simulation.animate方法将模拟对象与动画控制器绑定,并创建一个动画。
  4. 使用AnimatedBuilder来监听动画值的变化,并根据动画值更新UI。

你可以根据需要调整弹簧动画的参数,以及动画如何影响UI的具体实现。

回到顶部