我有一个奴才的 .flr 动画。是否可以在 Flutter 应用中动态地单独更改他的身体、裤子、眼睛等的颜色?
PS Minion 只是我在 rive.app 上找到的一个例子。会有另一个角色有很多不同的部分。
PPS 也许有更好的方法来制作一个简单的动画角色?现在,我有一个带有已定位颜色过滤图像的堆栈,但我想使用 rive 应该更容易。
正如 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;
}
});
是的你可以。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;
}
});