impeller_fx 1.0.0
impeller_fx: ^1.0.0 copied to clipboard
Production-grade, hyper-modern runtime fragment shader effects optimized explicitly for Flutter's Impeller rendering engine.
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:impeller_fx/impeller_fx.dart';
import 'pages/bloom_glow_page.dart';
import 'pages/chromatic_aberration_page.dart';
import 'pages/glassmorphism_page.dart';
import 'pages/holographic_page.dart';
import 'pages/liquid_ripple_page.dart';
import 'pages/mesh_gradient_page.dart';
import 'pages/plasma_flow_page.dart';
import 'pages/vortex_twist_page.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
SystemChrome.setSystemUIOverlayStyle(
const SystemUiOverlayStyle(
statusBarColor: Colors.transparent,
statusBarIconBrightness: Brightness.light,
),
);
// Warm up all 8 Impeller shaders during app startup
await FxShaderRegistry.warmupAll();
runApp(const ImpellerFxShowcaseApp());
}
/// Root showcase application for `impeller_fx` 1.0.0.
class ImpellerFxShowcaseApp extends StatelessWidget {
/// Creates the [ImpellerFxShowcaseApp].
const ImpellerFxShowcaseApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Impeller FX Showcase 1.0.0',
debugShowCheckedModeBanner: false,
theme: ThemeData(
brightness: Brightness.dark,
scaffoldBackgroundColor: const Color(0xFF06080E),
colorScheme: const ColorScheme.dark(
primary: Color(0xFF00F0FF),
secondary: Color(0xFFFF007F),
surface: Color(0xFF0D1117),
),
useMaterial3: true,
),
home: const MainShowcaseScreen(),
);
}
}
/// Main showcase screen with navigation between 8 shader effects.
class MainShowcaseScreen extends StatefulWidget {
/// Creates the [MainShowcaseScreen].
const MainShowcaseScreen({super.key});
@override
State<MainShowcaseScreen> createState() => _MainShowcaseScreenState();
}
class _MainShowcaseScreenState extends State<MainShowcaseScreen> {
int _currentIndex = 0;
final List<Widget> _pages = const [
MeshGradientPage(),
LiquidRipplePage(),
ChromaticAberrationPage(),
GlassmorphismPage(),
VortexTwistPage(),
HolographicPage(),
BloomGlowPage(),
PlasmaFlowPage(),
];
static const List<_EffectTabItem> _tabs = [
_EffectTabItem('Mesh', Icons.gradient_rounded),
_EffectTabItem('Ripple', Icons.water_drop_rounded),
_EffectTabItem('Aberration', Icons.lens_blur_rounded),
_EffectTabItem('Glass', Icons.blur_on_rounded),
_EffectTabItem('Vortex', Icons.all_inclusive_rounded),
_EffectTabItem('Holo', Icons.terminal_rounded),
_EffectTabItem('Bloom', Icons.flash_on_rounded),
_EffectTabItem('Plasma', Icons.grain_rounded),
];
@override
Widget build(BuildContext context) {
return Scaffold(
extendBody: true,
body: IndexedStack(
index: _currentIndex,
children: _pages,
),
bottomNavigationBar: Container(
height: 64.0,
margin: const EdgeInsets.fromLTRB(12.0, 0, 12.0, 16.0),
padding: const EdgeInsets.symmetric(horizontal: 8.0, vertical: 6.0),
decoration: BoxDecoration(
color: const Color(0xEE0D1117),
borderRadius: BorderRadius.circular(24.0),
border: Border.all(
color: Colors.white.withValues(alpha: 0.12),
width: 1.0,
),
boxShadow: [
BoxShadow(
color: Colors.black.withValues(alpha: 0.6),
blurRadius: 20.0,
offset: const Offset(0, 10),
),
],
),
child: ListView.separated(
scrollDirection: Axis.horizontal,
itemCount: _tabs.length,
separatorBuilder: (context, index) => const SizedBox(width: 4.0),
itemBuilder: (context, index) {
final tab = _tabs[index];
final isSelected = _currentIndex == index;
return GestureDetector(
onTap: () => setState(() => _currentIndex = index),
child: AnimatedContainer(
duration: const Duration(milliseconds: 200),
padding: const EdgeInsets.symmetric(horizontal: 14.0, vertical: 6.0),
decoration: BoxDecoration(
color: isSelected
? const Color(0xFF00F0FF).withValues(alpha: 0.2)
: Colors.transparent,
borderRadius: BorderRadius.circular(16.0),
border: isSelected
? Border.all(color: const Color(0xFF00F0FF), width: 1.0)
: null,
),
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(
tab.icon,
size: 18.0,
color: isSelected ? const Color(0xFF00F0FF) : Colors.white60,
),
const SizedBox(width: 6.0),
Text(
tab.label,
style: TextStyle(
color: isSelected ? Colors.white : Colors.white60,
fontSize: 12.0,
fontWeight: isSelected ? FontWeight.w800 : FontWeight.w500,
),
),
],
),
),
);
},
),
),
);
}
}
class _EffectTabItem {
const _EffectTabItem(this.label, this.icon);
final String label;
final IconData icon;
}