Flutter数学计算插件remaths的使用

发布于 1周前 作者 wuwangju 来自 Flutter

Flutter数学计算插件remaths的使用

Remaths

remaths 是一个用于简化动画和其他计算的 Flutter 包。该包主要受到了 React Native 的 reanimated 包的启发。

Tweenable

Tweenable 是 remaths 包的基本组件之一。Tweenable 携带可动画的数据。这些数据可以通过时间或弹簧进行动画处理。Tweenable 在底层使用了默认的 Flutter AnimationController 来渲染动画(可执行)。在开始使用 Tweenable 进行动画之前,我们先了解一下 Tweenable 函数。

Tweenable 函数

withSpring

启动一个弹簧动画。

x = withSpring(toValue, {
  int duration,
  double damping,
  double stiffness,
  double mass,
  double velocity,
  int? delay,
  void Function()? onComplete,
})
参数 默认值 描述
toValue * 必须 动画的目标值
duration 300 动画持续时间(毫秒)
damping 20 弹簧阻尼
stiffness 180.0 弹簧刚度
mass 1.0 质量
velocity 0.0 初始速度
delay 0.0 动画延迟时间(毫秒)
onComplete null 动画完成后的回调函数

withTiming

启动一个定时动画。

x = withTiming(double toValue, {
  int duration = _kDuration,
  Curve curve = Curves.easeIn,
  int? delay,
  void Function()? onComplete,
})
参数 默认值 描述
toValue * 必须 动画的目标值
duration 300 动画持续时间(毫秒)
curve Curves.easeIn 动画曲线
delay 0.0 动画延迟时间(毫秒)
onComplete null 动画完成后的回调函数

withSequence

按顺序运行一系列动画。

x = withSequence([withTiming(...), 6.0, withSpring(...)])

withSequence 接受一个包含 Tweenable 函数或 double 的列表,并按顺序执行它们。当提供一个 double 时,该值将直接设置为目标值,不进行任何动画。

使用 Tweenables

让我们以 Tweenable 作为可以被 Tweenable 函数动画化的双精度值为例。

var x = Tweenable<double>(value, vsync: this);

Tweenable 也可以使用数字扩展初始化:

var x = 12.asTweenable(this);
// 在这种情况下,12 用作初始值
参数 默认值 描述
value 必须 动画位置
vsync 必须 TickerProvider

你必须使用你的状态对象作为 vsync,通过添加 SingleTickerProviderStateMixinTickerProviderStateMixin 到类定义中。

动画可以在 Tweenable 上进行,通过将 Tweenable 值设置为动画函数。

如果任何动画在初始化另一个动画之前没有结束,则前一个动画将停止,当前动画将继续从旧动画停止的地方开始,以带来平滑的动画体验。

示例:

x = withTiming(...)
x = withSpring(...)
x = withSequence(...)
x = 45.0 // 这里没有动画

注意:如果使用 double 设置 Tweenable 的值,则不会触发动画。值会直接跳到目标值。

使用 Tweenables

Tweenable 可以与 AnimatedBuilder 一起使用。

要将 TweenableAnimatedBuilder 一起使用,你需要一个辅助函数 mergeTweenables,你可以传递 Tweenable,当其值发生变化时,小部件将重建。

例如:

// 初始化
var x = 10.asTweenable();
var y = 12.asTweenable();

// 使用
AnimatedBuilder(
  animation: mergeTweenables([x, y]),
  child: ...,
  builder: ...,
)
// 小部件将在 `x` 和 `y` 的值发生变化时重新构建

插值

映射输入值在一个范围内到输出值在另一个范围内。还支持不同类型的外推,当值落在范围之外时,以及字符串映射。 插值作为 numTweenable 的扩展。

var val = 50;
// 或者
var val = 50.asTweenable(this);
// 使用
var opacity = val.interpolate<double>(
  [20, 100], // 输入范围
  [0, 1], // 输出范围
  Extrapolate.EXTEND, // 外推
  Extrapolate.EXTEND, // 左外推
);

// 颜色插值
var color = val.interpolate<Color>(
  [20, 10],
  [Colors.red, Colors.green],
)
// 颜色插值的外推固定为 Extrapolate.CLAMP,即使指定也是如此

第三个参数是右外推,最后一个参数是左外推。如果指定了左外推,那么右外推将用于左外推。如果没有指定任何外推,则默认的 Extrapolate.EXTEND 将用于左右两边。在颜色插值中,外推固定为 Extrapolate.CLAMP,即使指定了也是如此。

辅助节点

/// 返回两个值的和。
double add(dynamic a, dynamic b);

/// 返回两个值的乘积。
double multiply(dynamic a, dynamic b);

/// 返回两个值相除的结果。
double divide(dynamic a, dynamic b);

/// 返回两个值相减的结果。
double sub(dynamic a, dynamic b);

/// 返回第一个值的第二个值次幂的结果。
double pow(dynamic a, dynamic b);

/// 返回数字的平方根。
double sqrt(dynamic a);

/// 返回第一个值除以第二个值的余数。
double modulo(dynamic a, dynamic b);

/// 等同于 `math.log` 函数。
double log(dynamic a);

/// 等同于 `math.sin` 函数。
double sin(dynamic a);

/// 等同于 `math.tan` 函数。
double tan(dynamic a);

/// 等同于 `math.asin` 函数。
double asin(dynamic a);

/// 等同于 `math.exp` 函数。
double exp(dynamic a);

/// 等同于 `num.round` 函数。
int round(dynamic a);

/// 等同于 `num.floor` 函数。
int floor(dynamic a);

/// 等同于 `num.ceil` 函数。
int ceil(dynamic a);

/// 等同于 `math.atan` 函数。
double atan(dynamic a);

/// 返回最小值。
T min<T extends num>(T a, T b);

/// 返回最大值。
T max<T extends num>(T a, T b);

/// 返回绝对值。
num abs(dynamic a);

/// 将角度转换为弧度。
double toRad(dynamic a);

/// 将弧度转换为角度。
double toDeg(dynamic a);

/// 如果给定的节点评估为“已定义”的值(即非空、非未定义且非 NaN),则返回 true,否则返回 false。
bool defined(dynamic a);

/// 返回两个布尔值的逻辑或。
bool or(bool a, bool b);

/// 如果值有效,则返回 true。
bool truthy(dynamic val);

/// 如果条件为真,则评估并返回 ifBlock 的值;否则评估并返回 elseBlock 的值。elseBlock 是可选的。
dynamic cond(bool condition, dynamic ifBlock, [dynamic elseBlock]);

/// 小于 `<` 比较。
bool lessThan(dynamic a, dynamic b);

/// 大于 `>` 比较。
bool greaterThan(dynamic a, dynamic b);

/// 检查两个值是否相等 `==`。
bool eq(dynamic a, dynamic b);

/// 检查两个值是否不相等 `!=`。
bool neq(dynamic a, dynamic b);

/// 小于等于 `<=` 比较。
bool lessOrEq(dynamic a, dynamic b);

/// 大于等于 `>=` 比较。
bool greaterOrEq(dynamic a, dynamic b);

/// 评估 Tweenable 并返回上次评估时的值与当前值之间的差值。
/// 当第一次评估时,它返回 Tweenable 的值。
double diff(_InternalShared tweenable, [double initial = 0.0]);

/// 四舍五入指定的小数位数。
/// ```dart
/// decimalRound(1.34343, 2) // 1.34
/// ````
double decimalRound(dynamic a, dynamic dec);

/// 生成从 [start] 到 [end] 的随机数。
///
/// 如果指定了 [decimal],则生成一个指定的小数位数的随机数。
/// ```dart
/// random() // 返回 0 到 1 的随机数
/// random(5) // 返回 0 到 5 的随机数
/// random(5,9) // 返回 5 到 9 的随机数
/// random(5,10,2) // 返回 5 到 10 保留两位小数的随机数
/// ```
double random([int start = 0, int end = 1, int decimal = 1]);

/// 生成整数列表。
/// ```dart
/// range(3) // [0,1,2]
/// range(10, start: 5) // [5,6,7,8,9]
/// range(10, step: 2) // [0,2,4,6,8]
/// ```
List<int> range(int stop, {int start: 0, int step: 1});

示例代码

以下是使用 remaths 插件的一个完整示例代码:

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

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'remaths example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const HomePage(),
      routes: {
        "/spring": (_) => const SpringAnimation(),
        "/timing": (_) => const TimingAnimation(),
        "/node": (_) => const NodeTesting(),
        "/offset": (_) => const OffsetTest(),
        "/apple_bedtime": (_) => const AppleBedtime(),
      },
    );
  }
}

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

  [@override](/user/override)
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  [@override](/user/override)
  Widget build(BuildContext context) {
    var screens = [
      ["Carousel", "/carousel"],
      ["Spring Animation", "/spring"],
      ["Timing Animation", "/timing"],
      ['New Node API', '/node'],
      ["Offset Text", '/offset'],
      ["Apple Bedtime", '/apple_bedtime'],
    ];
    return Scaffold(
      appBar: AppBar(
        title: const Text("Remaths Example"),
      ),
      body: ListView.builder(
        itemCount: screens.length,
        itemBuilder: (context, index) {
          return ListTile(
            onTap: () {
              Navigator.of(context).pushNamed(screens[index][1]);
            },
            title: Text(screens[index][0]),
          );
        },
      ),
    );
  }
}

更多关于Flutter数学计算插件remaths的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter数学计算插件remaths的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter项目中使用remaths插件进行数学计算的示例代码。remaths是一个用于数学和科学计算的Flutter插件,提供了丰富的数学函数和操作。

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

dependencies:
  flutter:
    sdk: flutter
  remaths: ^latest_version  # 替换为最新的版本号

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

接下来,在你的Flutter项目中,你可以这样使用remaths插件:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter ReMaths Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  String result = '';

  void calculate() {
    // 创建ReMaths对象
    final reMaths = ReMaths();

    // 示例:计算平方根
    double sqrtValue = reMaths.sqrt(16);
    setState(() {
      result = 'Square root of 16 is: $sqrtValue';
    });

    // 示例:计算对数
    double logValue = reMaths.log(Math.E); // 自然对数
    setState(() {
      result += '\nNatural logarithm of e is: $logValue';
    });

    // 示例:计算三角函数
    double sinValue = reMaths.sin(Math.PI / 2);
    setState(() {
      result += '\nSine of π/2 is: $sinValue';
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('ReMaths Example'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text(
              result,
              style: TextStyle(fontSize: 20),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: calculate,
              child: Text('Calculate'),
            ),
          ],
        ),
      ),
    );
  }
}

在这个示例中,我们创建了一个简单的Flutter应用,包含一个按钮和一个文本显示区域。当点击按钮时,应用会执行几个数学计算,包括平方根、自然对数和三角函数,并将结果显示在文本区域中。

注意:

  • ReMaths类的方法如sqrtlogsin等,都是基于数学公式进行计算的。
  • 你可能需要导入dart:math库来使用Math.PIMath.E等常量。
  • 确保remaths插件的版本是最新的,以获取最新的功能和修复。

这个示例展示了如何使用remaths插件进行基本的数学计算。根据项目的需求,你可以进一步探索和使用remaths提供的更多数学函数。

回到顶部