0

我有一个奴才的 .flr 动画。是否可以在 Flutter 应用中动态地单独更改他的身体、裤子、眼睛等的颜色?

在此处输入图像描述

PS Minion 只是我在 rive.app 上找到的一个例子。会有另一个角色有很多不同的部分。

PPS 也许有更好的方法来制作一个简单的动画角色?现在,我有一个带有已定位颜色过滤图像的堆栈,但我想使用 rive 应该更容易。

4

2 回答 2

2

正如 Kretin 已经在Flutter rive 包中概述的那样,即使它在编写时是 beta 版也是可能的。

为了让它工作,你必须知道你的动画,例如你想要改变的形状的名字(第一个),和你想要改变的填充颜色。

假设,我有一个名为“Button1”的动画。
这个形状有一种我想改变的填充颜色,然后我的代码如下所示:

artboard.forEachComponent((child) {
      if (child is Shape && child.name == 'Button1') {
        final Shape shape = child;
        shape.fills.first.paint.color = Colors.red;
      }
    });
于 2020-12-05T22:11:08.310 回答
1

是的你可以。Flare github中有一个例子: https ://github.com/2d-inc/Flare-Flutter/tree/master/example/change_color

import 'package:flare_flutter/flare_controller.dart';
import 'package:flare_flutter/flare.dart';
import 'package:flare_dart/math/mat2d.dart';
import 'package:flare_flutter/flare_actor.dart';
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

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

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

List<Color> exampleColors = <Color>[Colors.red, Colors.green, Colors.blue];

class _MyHomePageState extends State<MyHomePage> with FlareController {
  FlutterColorFill _fill;
  void initialize(FlutterActorArtboard artboard) {
    // Find our "Num 2" shape and get its fill so we can change it programmatically.
    FlutterActorShape shape = artboard.getNode("Num 2");
    _fill = shape?.fill as FlutterColorFill;
  }

  void setViewTransform(Mat2D viewTransform) {}

  bool advance(FlutterActorArtboard artboard, double elapsed) {
    // advance is called whenever the flare artboard is about to update (before it draws).
    Color nextColor = exampleColors[_counter % exampleColors.length];
    if (_fill != null) {
      _fill.uiColor = nextColor;
    }
    // Return false as we don't need to be called again. You'd return true if you wanted to manually animate some property.
    return false;
  }

  // We're going to use the counter to iterate the color.
  int _counter = 0;
  void _incrementCounter() {
    setState(() {
      // This call to setState tells the Flutter framework that something has
      // changed in this State, which causes it to rerun the build method below
      // so that the display can reflect the updated values. If we changed
      // _counter without calling setState(), then the build method would not be
      // called again, and so nothing would appear to happen.
      _counter++;
      // advance the controller
      isActive.value = true;
    });
  }

  @override
  Widget build(BuildContext context) {
    // This method is rerun every time setState is called, for instance as done
    // by the _incrementCounter method above.
    //
    // The Flutter framework has been optimized to make rerunning build methods
    // fast, so that you can just rebuild anything that needs updating rather
    // than having to individually change instances of widgets.
    return Scaffold(
      appBar: AppBar(
        // Here we take the value from the MyHomePage object that was created by
        // the App.build method, and use it to set our appbar title.
        title: Text(widget.title),
      ),
      body: FlareActor("assets/change_color_example.flr", // You can find the example project here: https://www.2dimensions.com/a/castor/files/flare/change-color-example
          fit: BoxFit.contain, alignment: Alignment.center, controller: this),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

如果您使用的是 Rive 测试版,情况会有所不同。我不确定这是否是最好的方法,但我正在执行以下操作:

artboard.forEachComponent((child){
    if (child.name == 'Fill') {
      Fill fill = child;
      fill.paint.color = Colors.red.withOpacity(0.25);
    }
    else if (child.name == 'Stroke') {
      Stroke stroke = child;
      stroke.paint.color = Colors.red;
    }
  });
于 2020-10-29T05:32:32.850 回答