Flutter着色器快照插件flutter_shader_snap的使用
Flutter着色器快照插件 flutter_shader_snap
的使用
flutter_shader_snap
是一个用于创建类似于“灭霸响指”效果的简单Flutter插件。它提供了两种主要的效果:分裂(split)和烟雾(smoke)。下面是该插件的详细使用方法。
插件介绍
开始使用
1. 添加依赖
首先,在你的 pubspec.yaml
文件中添加 flutter_shader_snap
依赖:
dependencies:
flutter_shader_snap: latest version
2. 添加着色器
在 pubspec.yaml
文件中添加相应的着色器文件路径:
flutter:
shaders:
- packages/flutter_shader_snap/shaders/split_snap_effect_shader.glsl # 如果使用 SnapShaderType.split (默认)
- packages/flutter_shader_snap/shaders/split_reversed_snap_effect_shader.glsl # 如果使用 SnapShaderType.splitReversed
- packages/flutter_shader_snap/shaders/smoke_snap_effect_shader.glsl # 如果使用 SnapShaderType.smoke
3. 创建并使用 AnimationController
创建一个 AnimationController
并将其传递给 SnapShader
小部件:
class _MyHomePageState extends State<MyHomePage> with SingleTickerProviderStateMixin {
late final _controller = AnimationController(
vsync: this,
duration: const Duration(seconds: 5),
);
@override
Widget build(BuildContext context) {
return SnapShader(
controller: _controller,
child: AnyWidget(), // 替换为你要应用效果的任何小部件
);
}
}
性能优化
着色器仅在动画运行时应用于子小部件,因此不会影响应用程序的整体性能。为了进一步优化,可以使用 AnimatedSampler
来确保只在需要时应用着色器。
builder: (context, child) => controller.value == 0
? child!
: AnimatedSampler
完整示例 Demo
以下是一个完整的示例,展示了如何使用 flutter_shader_snap
插件来实现分裂和烟雾效果,并允许用户通过按钮控制这些效果。
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_shader_snap/flutter_shader_snap.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Shader Snap DEMO',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with TickerProviderStateMixin {
late final _controller = AnimationController(
vsync: this,
duration: const Duration(seconds: 5),
);
late final _controller2 = AnimationController(
vsync: this,
duration: const Duration(seconds: 5),
);
int _counter = 0;
int _index = 0;
var _snapShaderType = SnapShaderType.split;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
void initState() {
super.initState();
_controller2.addStatusListener((status) async {
if (status != AnimationStatus.completed || _controller2.value == 0) return;
await Future.delayed(const Duration(seconds: 3));
_controller2.animateBack(0, duration: const Duration(seconds: 1));
});
Timer.periodic(const Duration(seconds: 1), (timer) {
setState(() {
_index++;
});
});
}
@override
Widget build(BuildContext context) {
return SnapShader(
controller: _controller2,
child: Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: const Text('Flutter Shader Snap DEMO'),
),
body: SafeArea(
child: Center(
child: Column(
children: [
const Spacer(),
SnapShader(
controller: _controller,
snapShaderType: _snapShaderType,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
'You have pushed the button this many times:',
style: Theme.of(context).textTheme.bodyLarge?.copyWith(color: Colors.green),
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headlineMedium,
),
const SizedBox(height: 8),
AnimatedContainer(
duration: const Duration(seconds: 1),
width: 100,
height: 100,
color: Colors.primaries[_index % Colors.primaries.length],
),
const SizedBox(height: 8),
const Text('Use split (on) or smoke (off) shader'),
...SnapShaderType.values.map(
(e) => GestureDetector(
onTap: () => setState(() => _snapShaderType = e),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
Radio(
groupValue: _snapShaderType,
value: e,
onChanged: (value) => setState(() => _snapShaderType = e),
),
Text(e.toString().split('.').last),
],
),
),
),
),
Align(
alignment: Alignment.centerRight,
child: Container(
width: 100,
height: 100,
margin: const EdgeInsets.only(right: 8, bottom: 50),
decoration: BoxDecoration(
color: Colors.primaries[(_index + 5) % Colors.primaries.length],
shape: BoxShape.circle,
),
),
)
],
),
),
Slider(
value: _controller.value,
onChanged: (value) => _controller.value = value,
),
const Spacer(),
ElevatedButton(
onPressed: () => _controller.forward(),
child: const Text('Snap!'),
),
const SizedBox(height: 8),
ElevatedButton(
onPressed: () => _controller.stop(canceled: false),
child: const Text('Pause'),
),
const SizedBox(height: 8),
ElevatedButton(
onPressed: () => _controller.reset(),
child: const Text('Reset'),
),
const SizedBox(height: 8),
ElevatedButton(
onPressed: () => _controller2.forward(),
child: const Text('Snap EVERYTHING!'),
),
const SizedBox(height: 8),
],
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
),
),
);
}
}
这个示例展示了如何使用 SnapShader
小部件来应用分裂或烟雾效果,并且可以通过按钮控制动画的播放、暂停和重置。此外,还展示了如何动态切换不同的着色器类型。
更多关于Flutter着色器快照插件flutter_shader_snap的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter着色器快照插件flutter_shader_snap的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何在Flutter项目中使用flutter_shader_snap
插件的示例代码。这个插件允许你使用自定义的GLSL着色器并在Flutter应用中实时预览它们。
1. 添加依赖
首先,你需要在你的pubspec.yaml
文件中添加flutter_shader_snap
的依赖:
dependencies:
flutter:
sdk: flutter
flutter_shader_snap: ^最新版本号 # 请替换为最新的版本号
2. 导入插件
在你的Dart文件中导入插件:
import 'package:flutter/material.dart';
import 'package:flutter_shader_snap/flutter_shader_snap.dart';
3. 编写自定义着色器
创建一个GLSL着色器文件,例如simple_shader.glsl
:
// simple_shader.glsl
precision mediump float;
uniform sampler2D u_texture;
uniform vec4 u_color;
varying vec2 v_texCoord;
void main() {
vec4 texColor = texture2D(u_texture, v_texCoord);
gl_FragColor = texColor * u_color;
}
4. 使用ShaderSnapWidget
在你的Flutter应用中,使用ShaderSnapWidget
来加载和显示你的着色器:
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Flutter Shader Snap Demo'),
),
body: ShaderSnapDemo(),
),
);
}
}
class ShaderSnapDemo extends StatefulWidget {
@override
_ShaderSnapDemoState createState() => _ShaderSnapDemoState();
}
class _ShaderSnapDemoState extends State<ShaderSnapDemo> {
@override
Widget build(BuildContext context) {
return Center(
child: ShaderSnapWidget(
shaderSource: {
'vertex': '''
attribute vec4 a_position;
attribute vec2 a_texCoord;
uniform mat4 u_matrix;
varying vec2 v_texCoord;
void main() {
gl_Position = u_matrix * a_position;
v_texCoord = a_texCoord;
}
''',
'fragment': '''
precision mediump float;
uniform sampler2D u_texture;
uniform vec4 u_color;
varying vec2 v_texCoord;
void main() {
vec4 texColor = texture2D(u_texture, v_texCoord);
gl_FragColor = texColor * u_color;
}
'''
}, // 你可以在这里直接写GLSL代码,或者从文件加载
uniforms: {
'u_color': [1.0, 0.5, 0.5, 1.0], // 例如,设置颜色为粉红色
},
texture: NetworkImage('https://example.com/path/to/your/image.jpg'), // 使用网络图片作为纹理
),
);
}
}
5. 运行应用
确保你已经连接了一个Flutter设备或启动了Flutter模拟器,然后运行你的Flutter应用:
flutter run
以上代码演示了如何在Flutter中使用flutter_shader_snap
插件来加载和显示自定义的GLSL着色器。你可以根据需要修改着色器代码和uniforms来实现不同的视觉效果。