holographic_card_flutter 0.1.4
holographic_card_flutter: ^0.1.4 copied to clipboard
A Flutter library for creating beautiful holographic ID cards with interactive effects
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:holographic_card_flutter/holographic_card_flutter.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Holographic Card Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue),
useMaterial3: true,
),
darkTheme: ThemeData(
colorScheme: ColorScheme.fromSeed(
seedColor: Colors.blue,
brightness: Brightness.dark,
),
useMaterial3: true,
),
themeMode: ThemeMode.system,
home: const DemoPage(),
);
}
}
class DemoPage extends StatefulWidget {
const DemoPage({super.key});
@override
State<DemoPage> createState() => _DemoPageState();
}
class _DemoPageState extends State<DemoPage> {
// Interactive feature toggles
bool _enableGyro = true;
bool _enableShader = true;
bool _enableFlip = true;
bool _enableGestures = true;
bool _enableHolographicEffects = true;
bool _enableShadows = true;
// Sensitivity controls
double _gestureSensitivity = 0.3;
double _gyroSensitivity = 0.3;
double _gyroSmoothing = 0.85;
double _hologramCenterMovement = 0.3;
// Shadow properties
double _shadowOpacity = 0.4;
double _shadowBlur = 30.0;
double _shadowYOffset = 8.0;
// Shader parameters
double _shaderWaveFrequency = 5.0;
double _shaderColorAmplitude = 0.03;
double _shaderBaseAlpha = 0.5;
// Card dimensions
double _cardWidth = 350;
double _cardHeight = 220;
double _borderRadius = 15;
double _borderWidth = 2.0;
// Theme mode
ThemeMode _themeMode = ThemeMode.system;
void _handleCopy(String value) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Copied: $value')),
);
}
@override
Widget build(BuildContext context) {
final isDark = Theme.of(context).brightness == Brightness.dark;
final defaultCardColor =
isDark ? const Color(0xFF424242) : const Color(0xFFBEBEBE);
final defaultTextColor = isDark ? Colors.white : Colors.black;
return Scaffold(
appBar: AppBar(
title: const Text('Holographic Card Demo'),
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
actions: [
IconButton(
icon: Icon(isDark ? Icons.light_mode : Icons.dark_mode),
onPressed: () {
setState(() {
_themeMode = isDark ? ThemeMode.light : ThemeMode.dark;
});
},
),
],
),
body: SingleChildScrollView(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Interactive Student ID Card',
style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold),
),
const SizedBox(height: 20),
Center(
child: HolographicCard(
// User data (anonymized)
name: 'John Doe',
email: 'john.doe@example.com',
validUntil: 'Valid until 31.12.2025',
matrikelnr: '12345678',
lrzKennung: 'doe123',
braille: '⠑⠭⠁',
// Card dimensions
width: _cardWidth,
height: _cardHeight,
borderRadius: _borderRadius,
borderWidth: _borderWidth,
// Card colors
cardColor: defaultCardColor,
textColor: defaultTextColor,
secondaryTextColor: defaultTextColor.withOpacity(0.7),
logoColor: defaultTextColor,
hologramColor: Colors.white70,
borderCardColor: defaultTextColor,
// Shadow properties
ambientShadowOpacity: _shadowOpacity,
ambientShadowBlur: _shadowBlur,
ambientShadowYOffset: _shadowYOffset,
primaryShadowOpacity: 0.30,
midShadowOpacity: 0.15,
distantShadowOpacity: 0.05,
shadowOffsetMultiplier: 25,
shadowIntensityMultiplier: 2.5,
// Movement sensitivity
gestureSensitivity: _gestureSensitivity,
gyroSensitivity: _gyroSensitivity,
gyroSmoothing: _gyroSmoothing,
hologramCenterMovement: _hologramCenterMovement,
// Assets
logoAsset: null,
hologramAsset: 'assets/holograms/test.svg',
hologramAsset2: 'assets/holograms/test.svg',
// Feature toggles
enableFlip: _enableFlip,
enableGyro: _enableGyro,
enableGestures: _enableGestures,
enableShader: false,
enableHolographicEffects: _enableHolographicEffects,
enableShadows: _enableShadows,
// Logo properties
logoWidth: 62,
logoHeight: 32,
logoPosition: const Offset(20, 20),
// Hologram properties
hologram1Width: 150,
hologram1Height: 150,
hologram1Position: const Offset(180, 150),
hologram2Width: 350,
hologram2Height: 40,
hologram2Position: const Offset(0, 160),
// Shader parameters
shaderWaveFrequency: _shaderWaveFrequency,
shaderPointerInfluence: 5.0,
shaderColorAmplitude: _shaderColorAmplitude,
shaderBaseAlpha: _shaderBaseAlpha,
// Axis inversion
invertGyroX: false,
invertGyroY: false,
invertGestureX: false,
invertGestureY: false,
// Callbacks
onMatrikelnrCopy: _handleCopy,
onLrzKennungCopy: _handleCopy,
onCardTap: () => ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Card tapped!')),
),
onCardDoubleTap: () =>
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Card flipped!')),
),
),
),
const SizedBox(height: 32),
_buildControlsSection(),
],
),
),
),
);
}
Widget _buildControlsSection() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
'Feature Controls',
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
),
const SizedBox(height: 16),
_buildFeatureToggles(),
const Divider(),
_buildSensitivityControls(),
const Divider(),
_buildShadowControls(),
const Divider(),
_buildShaderControls(),
const Divider(),
_buildDimensionControls(),
const SizedBox(height: 16),
_buildInteractionGuide(),
],
);
}
Widget _buildFeatureToggles() {
return Column(
children: [
SwitchListTile(
title: const Text('Gyroscope'),
subtitle: const Text('Use device motion for effects'),
value: _enableGyro,
onChanged: (value) => setState(() => _enableGyro = value),
),
SwitchListTile(
title: const Text('Shader Effects'),
subtitle: const Text('Advanced holographic patterns'),
value: _enableShader,
onChanged: (value) => setState(() => _enableShader = value),
),
SwitchListTile(
title: const Text('Flip Animation'),
subtitle: const Text('Enable card flip on double tap'),
value: _enableFlip,
onChanged: (value) => setState(() => _enableFlip = value),
),
SwitchListTile(
title: const Text('Touch Gestures'),
subtitle: const Text('Enable touch interaction'),
value: _enableGestures,
onChanged: (value) => setState(() => _enableGestures = value),
),
SwitchListTile(
title: const Text('Holographic Effects'),
subtitle: const Text('Enable hologram animations'),
value: _enableHolographicEffects,
onChanged: (value) =>
setState(() => _enableHolographicEffects = value),
),
SwitchListTile(
title: const Text('Shadows'),
subtitle: const Text('Enable dynamic shadows'),
value: _enableShadows,
onChanged: (value) => setState(() => _enableShadows = value),
),
],
);
}
Widget _buildSensitivityControls() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Padding(
padding: EdgeInsets.all(16),
child: Text('Sensitivity Controls',
style: TextStyle(fontWeight: FontWeight.bold)),
),
ListTile(
title: const Text('Gesture Sensitivity'),
subtitle: Slider(
value: _gestureSensitivity,
min: 0.1,
max: 1.0,
divisions: 9,
label: _gestureSensitivity.toStringAsFixed(1),
onChanged: (value) => setState(() => _gestureSensitivity = value),
),
),
ListTile(
title: const Text('Gyroscope Sensitivity'),
subtitle: Slider(
value: _gyroSensitivity,
min: 0.1,
max: 1.0,
divisions: 9,
label: _gyroSensitivity.toStringAsFixed(1),
onChanged: (value) => setState(() => _gyroSensitivity = value),
),
),
],
);
}
Widget _buildShadowControls() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Padding(
padding: EdgeInsets.all(16),
child: Text('Shadow Properties',
style: TextStyle(fontWeight: FontWeight.bold)),
),
ListTile(
title: const Text('Shadow Opacity'),
subtitle: Slider(
value: _shadowOpacity,
min: 0.0,
max: 1.0,
divisions: 10,
label: _shadowOpacity.toStringAsFixed(1),
onChanged: (value) => setState(() => _shadowOpacity = value),
),
),
ListTile(
title: const Text('Shadow Blur'),
subtitle: Slider(
value: _shadowBlur,
min: 0.0,
max: 50.0,
divisions: 50,
label: _shadowBlur.toStringAsFixed(1),
onChanged: (value) => setState(() => _shadowBlur = value),
),
),
],
);
}
Widget _buildShaderControls() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Padding(
padding: EdgeInsets.all(16),
child: Text('Shader Properties',
style: TextStyle(fontWeight: FontWeight.bold)),
),
ListTile(
title: const Text('Wave Frequency'),
subtitle: Slider(
value: _shaderWaveFrequency,
min: 1.0,
max: 10.0,
divisions: 18,
label: _shaderWaveFrequency.toStringAsFixed(1),
onChanged: (value) => setState(() => _shaderWaveFrequency = value),
),
),
ListTile(
title: const Text('Color Amplitude'),
subtitle: Slider(
value: _shaderColorAmplitude,
min: 0.01,
max: 0.1,
divisions: 9,
label: _shaderColorAmplitude.toStringAsFixed(2),
onChanged: (value) => setState(() => _shaderColorAmplitude = value),
),
),
],
);
}
Widget _buildDimensionControls() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Padding(
padding: EdgeInsets.all(16),
child: Text('Card Dimensions',
style: TextStyle(fontWeight: FontWeight.bold)),
),
ListTile(
title: const Text('Width'),
subtitle: Slider(
value: _cardWidth,
min: 250,
max: 450,
divisions: 20,
label: _cardWidth.toStringAsFixed(0),
onChanged: (value) => setState(() => _cardWidth = value),
),
),
ListTile(
title: const Text('Height'),
subtitle: Slider(
value: _cardHeight,
min: 150,
max: 300,
divisions: 15,
label: _cardHeight.toStringAsFixed(0),
onChanged: (value) => setState(() => _cardHeight = value),
),
),
ListTile(
title: const Text('Border Radius'),
subtitle: Slider(
value: _borderRadius,
min: 0,
max: 30,
divisions: 30,
label: _borderRadius.toStringAsFixed(0),
onChanged: (value) => setState(() => _borderRadius = value),
),
),
],
);
}
Widget _buildInteractionGuide() {
return Card(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: const [
Text(
'Available Interactions:',
style: TextStyle(fontWeight: FontWeight.bold),
),
SizedBox(height: 8),
Text('• Tap to trigger animation'),
Text('• Double tap to flip card (when enabled)'),
Text('• Touch and drag to control effects (when enabled)'),
Text('• Move device to see gyroscope effects (when enabled)'),
Text('• Tap on ID number or LRZ-Kennung to copy'),
Text('• Toggle light/dark theme using the app bar button'),
],
),
),
);
}
}