Flutter图像合成插件montage的使用
Flutter图像合成插件montage的使用
montage
组织你的动画。
快速开始

// 1. 定义你的动画
const entrance = MontageAnimation(
key: 'entrance',
duration: Duration(seconds: 2),
);
const exit = MontageAnimation(
key: 'exit',
duration: Duration(seconds: 2),
);
class Home extends StatefulWidget {
const Home({
Key? key,
}) : super(key: key);
@override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> with TickerProviderStateMixin {
MontageController? controller;
@override
void initState() {
controller = MontageController(
vsync: this,
initialAnimation: entrance,
);
super.initState();
}
@override
void dispose() {
controller?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: ValueListenableBuilder<MontageAnimation?>(
valueListenable: controller!.current,
builder: (context, current, child) => Text(current?.key ?? 'none'),
),
),
// 2. 将你的动画组件包裹在带有控制器的Montage中。
body: Montage(
controller: controller!,
child: BasicScene(),
),
floatingActionButton: FloatingActionButton.extended(
onPressed: () {
/// 播放这些动画序列
controller!.play([
entrance,
exit,
]);
},
label: Text('播放'),
icon: Icon(Icons.video_call),
),
);
}
}
class BasicScene extends StatelessWidget {
const BasicScene({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
// 3. 使用定义了每个动画运动的motion组件
Motion(
motion: {
// 你可以使用提供的motion或自定义的motion
entrance: Motions.combine([
Motions.rotate(startTurns: -1, endTurns: 0),
Motions.fadeIn,
]),
exit: Motions.combine([
Motions.rotate(startTurns: 0, endTurns: 1),
Motions.fadeOut,
]),
},
child: FlutterLogo(
size: 50,
),
),
MotionText(
text: 'Hello world',
style: TextStyle(
fontSize: 64,
color: Colors.black,
fontWeight: FontWeight.bold,
),
characterMotion: {
entrance: Motions.fadeFromTop(),
exit: Motions.fadeToTop(),
},
reversedCharacterAnimation: [exit],
wordMotion: {
entrance: Motions.fadeIn,
exit: Motions.fadeOut,
},
),
],
);
}
}
组件
声明动画引用
首先,你需要声明场景中的各种动画序列作为全局对象。
const entrance = MontageAnimation(
duration: Duration(seconds: 2),
);
const idle = MontageAnimation(
duration: Duration(seconds: 3),
);
const exit = MontageAnimation(
duration: Duration(seconds: 2),
);
Montage
蒙太奇作为运动组件的根配置。它接受一个专用控制器,用于触发动画。
class _HomeState extends State<Home> with TickerProviderStateMixin {
MontageController? controller;
@override
void initState() {
controller = MontageController(
vsync: this,
initialAnimation: entrance,
);
super.initState();
}
@override
void dispose() {
controller?.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Montage(
controller: controller!,
child: Scene(),
),
floatingActionButton: FloatingActionButton(
icon: Icon(Icons.video_call),
onPressed: () {
/// 播放这些动画序列
controller!.play([
entrance,
exit,
entrance,
idle,
exit,
]);
},
),
);
}
}
Motion
核心组件,可以为每个从根Montage控制器播放的动画序列以不同的方式动画化子组件。
Motion(
motion: {
entrance: Motions.fadeIn,
exit: Motions.fadeOut,
},
child: FlutterLogo(
size: 50,
),
)
分段动画
如果你想逐步动画一组组件,可以使用Motion.staggered辅助方法。
Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
...Motion.staggered(
children: [
Text("FL"),
Text("UT"),
Text("TER"),
],
motion: (child, i, forward, backward) {
return {
entrance: Motions.curved(
forward,
Motions.combine([
Motions.rotate(startTurns: -1, endTurns: 0),
Motions.fadeIn,
Motions.scale(begin: 3, end: 1)
]),
),
exit: Motions.curved(
backward,
Motions.combine([
Motions.rotate(startTurns: 0, endTurns: -1),
Motions.fadeOut,
Motions.scale(begin: 1, end: 3)
]),
),
};
},
)
],
),
动画
内置动画
一系列内置动画可以在motions.dart
文件中找到。
自定义动画
动画只是一个基于当前Animation<double>
和应被动画化的子组件的构建器。
Widget fadeIn(
BuildContext context,
MontageAnimation current,
Animation<double> animation,
Widget? child,
) {
return FadeTransition(
opacity: animation,
child: child,
);
}
更多关于Flutter图像合成插件montage的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html
1 回复
更多关于Flutter图像合成插件montage的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
montage
是一个用于图像合成的 Flutter 插件,它允许你将多张图片合并成一张图片。这个插件通常用于创建图片拼贴、缩略图网格等场景。以下是如何在 Flutter 项目中使用 montage
插件的基本步骤。
1. 添加依赖
首先,你需要在 pubspec.yaml
文件中添加 montage
插件的依赖。
dependencies:
flutter:
sdk: flutter
montage: ^0.0.1 # 请检查最新版本
然后运行 flutter pub get
来获取依赖。
2. 导入插件
在你的 Dart 文件中导入 montage
插件。
import 'package:montage/montage.dart';
3. 使用 montage
进行图像合成
以下是一个简单的示例,展示如何使用 montage
插件将多张图片合成一张图片。
import 'package:flutter/material.dart';
import 'package:montage/montage.dart';
import 'dart:typed_data';
import 'dart:ui' as ui;
class ImageMontageExample extends StatefulWidget {
@override
_ImageMontageExampleState createState() => _ImageMontageExampleState();
}
class _ImageMontageExampleState extends State<ImageMontageExample> {
ui.Image? _montageImage;
@override
void initState() {
super.initState();
_createMontage();
}
Future<void> _createMontage() async {
// 加载图片
final image1 = await _loadImage('assets/image1.jpg');
final image2 = await _loadImage('assets/image2.jpg');
final image3 = await _loadImage('assets/image3.jpg');
// 使用 montage 合成图片
final montage = Montage();
final Uint8List? result = await montage.createMontage(
images: [image1, image2, image3],
grid: [2, 2], // 2行2列的网格
backgroundColor: Colors.white, // 背景颜色
padding: 10.0, // 图片之间的间距
);
if (result != null) {
final codec = await ui.instantiateImageCodec(result);
final frame = await codec.getNextFrame();
setState(() {
_montageImage = frame.image;
});
}
}
Future<Uint8List> _loadImage(String assetPath) async {
final ByteData data = await rootBundle.load(assetPath);
return data.buffer.asUint8List();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Image Montage Example'),
),
body: Center(
child: _montageImage != null
? RawImage(
image: _montageImage,
fit: BoxFit.cover,
)
: CircularProgressIndicator(),
),
);
}
}
void main() => runApp(MaterialApp(
home: ImageMontageExample(),
));
4. 解释代码
- 加载图片:我们使用
_loadImage
方法从 assets 中加载图片,并将其转换为Uint8List
。 - 使用
montage
合成图片:我们创建了一个Montage
实例,并调用createMontage
方法,传入图片列表、网格布局、背景颜色和间距等参数。 - 显示合成后的图片:合成后的图片被转换为
ui.Image
,并在RawImage
中显示。
5. 运行项目
确保你的 pubspec.yaml
文件中已经正确配置了 assets:
flutter:
assets:
- assets/image1.jpg
- assets/image2.jpg
- assets/image3.jpg