Files
mixbox_flutter/example/lib/main.dart
Robert Felker d199344d5d init
2026-02-10 17:07:13 +01:00

234 lines
6.6 KiB
Dart

import 'package:flutter/material.dart';
import 'package:mixbox/mixbox.dart';
import 'package:mixbox/mixbox_loader.dart';
/// Mixbox Flutter
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await MixboxLoader.initializeFromAsset('../assets/mixbox_lut.dat');
runApp(const MixboxDemoApp());
}
class MixboxDemoApp extends StatelessWidget {
const MixboxDemoApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Mixbox Demo',
theme: ThemeData(primarySwatch: Colors.blue),
home: const MixboxDemo(),
);
}
}
class MixboxDemo extends StatefulWidget {
const MixboxDemo({super.key});
@override
State<MixboxDemo> createState() => _MixboxDemoState();
}
class _MixboxDemoState extends State<MixboxDemo> {
double _mixAmount = 0.5;
// Couleurs pigments prédéfinies
final Color cadmiumYellow = const Color(0xFFFEEC00);
final Color ultrammarineBlue = const Color(0xFF190059);
@override
Widget build(BuildContext context) {
// Mélange avec Mixbox
final mixedColor = cadmiumYellow.mixWith(ultrammarineBlue, _mixAmount);
return Scaffold(
appBar: AppBar(title: const Text('Mixbox - Mélange Physique')),
body: Padding(
padding: const EdgeInsets.all(20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
// Couleurs source
Row(
children: [
Expanded(
child: _ColorBox(color: cadmiumYellow, label: 'Cadmium Yellow'),
),
const SizedBox(width: 10),
Expanded(
child: _ColorBox(color: ultrammarineBlue, label: 'Ultramarine Blue'),
),
],
),
const SizedBox(height: 30),
// Résultat du mélange
_ColorBox(color: mixedColor, label: 'Mélange Mixbox', height: 150),
const SizedBox(height: 20),
// Slider de contrôle
Text(
'Proportion: ${(_mixAmount * 100).toStringAsFixed(0)}% bleu',
style: Theme.of(context).textTheme.titleMedium,
),
Slider(value: _mixAmount, onChanged: (value) => setState(() => _mixAmount = value)),
const SizedBox(height: 30),
// Exemple multi-couleurs
const Text('Mélange de 3 couleurs:', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold)),
const SizedBox(height: 10),
_MultiColorMixExample(),
],
),
),
);
}
}
class _ColorBox extends StatelessWidget {
final Color color;
final String label;
final double height;
const _ColorBox({required this.color, required this.label, this.height = 100});
@override
Widget build(BuildContext context) {
return Container(
height: height,
decoration: BoxDecoration(
color: color,
borderRadius: BorderRadius.circular(8),
border: Border.all(color: Colors.black26),
),
child: Center(
child: Text(
label,
style: TextStyle(color: _getContrastColor(color), fontWeight: FontWeight.bold),
),
),
);
}
Color _getContrastColor(Color background) {
final luminance = background.computeLuminance();
return luminance > 0.5 ? Colors.black : Colors.white;
}
}
class _MultiColorMixExample extends StatelessWidget {
// Couleurs pigments
static const cadmiumRed = Color(0xFFFF2702);
static const hansaYellow = Color(0xFFFCD300);
static const phthaloBlue = Color(0xFF0D1B44);
@override
Widget build(BuildContext context) {
// Conversion en espace latent
final z1 = Mixbox.rgbToLatent(cadmiumRed.toMixboxInt());
final z2 = Mixbox.rgbToLatent(hansaYellow.toMixboxInt());
final z3 = Mixbox.rgbToLatent(phthaloBlue.toMixboxInt());
// Mélange personnalisé: 40% rouge, 30% jaune, 30% bleu
final zMix = List.generate(Mixbox.latentSize, (i) => 0.4 * z1[i] + 0.3 * z2[i] + 0.3 * z3[i]);
final mixedColor = Color(Mixbox.latentToRgb(zMix));
return Column(
children: [
Row(
children: [
Expanded(child: _SmallColorBox(cadmiumRed, '40% Rouge')),
const SizedBox(width: 5),
Expanded(child: _SmallColorBox(hansaYellow, '30% Jaune')),
const SizedBox(width: 5),
Expanded(child: _SmallColorBox(phthaloBlue, '30% Bleu')),
],
),
const SizedBox(height: 10),
_ColorBox(color: mixedColor, label: 'Résultat', height: 80),
],
);
}
}
class _SmallColorBox extends StatelessWidget {
final Color color;
final String label;
const _SmallColorBox(this.color, this.label);
@override
Widget build(BuildContext context) {
return Container(
height: 60,
decoration: BoxDecoration(
color: color,
borderRadius: BorderRadius.circular(6),
border: Border.all(color: Colors.black26),
),
child: Center(
child: Text(
label,
textAlign: TextAlign.center,
style: const TextStyle(color: Colors.white, fontSize: 11, fontWeight: FontWeight.bold),
),
),
);
}
}
/// Exemples d'usage direct
class MixboxExamples {
static void basicUsage() {
// 1. Mélange simple de 2 couleurs
final yellow = 0xFFFEEC00;
final blue = 0xFF190059;
final green = Mixbox.lerp(yellow, blue, 0.5);
print('Vert mélangé: ${green.toRadixString(16)}');
}
static void multiColorMix() {
// 2. Mélange de 3 couleurs ou plus
final red = Color(0xFFFF2702);
final yellow = Color(0xFFFCD300);
final blue = Color(0xFF0D1B44);
final z1 = Mixbox.rgbToLatent(red.toMixboxInt());
final z2 = Mixbox.rgbToLatent(yellow.toMixboxInt());
final z3 = Mixbox.rgbToLatent(blue.toMixboxInt());
final zMix = List.generate(Mixbox.latentSize, (i) => 0.5 * z1[i] + 0.3 * z2[i] + 0.2 * z3[i]);
final mixed = Mixbox.latentToRgb(zMix);
print('Couleur mélangée: ${mixed.toRadixString(16)}');
}
static void floatUsage() {
// 3. Utilisation avec des floats (0.0-1.0)
final color1 = [1.0, 0.93, 0.0]; // Jaune
final color2 = [0.1, 0.0, 0.35]; // Bleu
final mixed = Mixbox.lerpFloat(color1, color2, 0.5);
print('RGB mélangé: ${mixed[0]}, ${mixed[1]}, ${mixed[2]}');
}
static void gradientExample() {
// 4. Créer un gradient physiquement correct
final yellow = Color(0xFFFEEC00);
final blue = Color(0xFF190059);
final gradient = List.generate(10, (i) => yellow.mixWith(blue, i / 9.0));
for (var color in gradient) {
print('Couleur gradient: ${color.value.toRadixString(16)}');
}
}
}