Update README and code to set default sparkle shape to 'none' and add opacity control
Signed-off-by: Hans Kokx <hans.d.kokx@gmail.com>
This commit is contained in:
+91
-35
@@ -3,10 +3,12 @@ import 'dart:async';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:holo_shiny/holo_shiny.dart';
|
||||
|
||||
/// Entry point for the package demo application.
|
||||
void main() {
|
||||
runApp(const ExampleApp());
|
||||
}
|
||||
|
||||
/// Root app widget for the interactive shader demo.
|
||||
class ExampleApp extends StatelessWidget {
|
||||
const ExampleApp({super.key});
|
||||
|
||||
@@ -15,6 +17,7 @@ class ExampleApp extends StatelessWidget {
|
||||
return MaterialApp(
|
||||
debugShowCheckedModeBanner: false,
|
||||
theme: ThemeData(
|
||||
useMaterial3: true,
|
||||
colorScheme: ColorScheme.fromSeed(seedColor: const Color(0xFF24A6A8)),
|
||||
),
|
||||
home: const ExampleHome(),
|
||||
@@ -22,6 +25,7 @@ class ExampleApp extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
/// Interactive screen used to test style and uniform controls.
|
||||
class ExampleHome extends StatefulWidget {
|
||||
const ExampleHome({super.key});
|
||||
|
||||
@@ -30,19 +34,26 @@ class ExampleHome extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _ExampleHomeState extends State<ExampleHome> {
|
||||
/// Sensor-driven controller used by the first two demo surfaces.
|
||||
late final ShinyController _sensorController;
|
||||
|
||||
/// Manual stream used by tilt preset buttons.
|
||||
late final StreamController<Offset> _externalTiltController;
|
||||
|
||||
/// Controller backed by [_externalTiltController].
|
||||
late final ShinyController _overrideController;
|
||||
|
||||
double _prismatic = 0.8;
|
||||
double _sparkle = 0.8;
|
||||
double _specular = 0.8;
|
||||
double _diffraction = 0.8;
|
||||
double _opacity = 1.0;
|
||||
HolographStyle _style = HolographStyle.crackedIce;
|
||||
SparkleShapeSpec _sparkleShape = SparkleShapeSpec.eightPointStar;
|
||||
SparkleShapeSpec _sparkleShape = SparkleShapeSpec.none;
|
||||
|
||||
static const Map<String, SparkleShapeSpec> _sparkleChoices =
|
||||
<String, SparkleShapeSpec>{
|
||||
'None': SparkleShapeSpec.none,
|
||||
'8-Point Star': SparkleShapeSpec.eightPointStar,
|
||||
'5-Point Star': SparkleShapeSpec.fivePointStar,
|
||||
'Rectangle': SparkleShapeSpec.rectangle,
|
||||
@@ -90,6 +101,11 @@ class _ExampleHomeState extends State<ExampleHome> {
|
||||
child: Shiny(
|
||||
controller: _sensorController,
|
||||
style: _style,
|
||||
prismatic: _prismatic,
|
||||
sparkle: _sparkle,
|
||||
specular: _specular,
|
||||
diffraction: _diffraction,
|
||||
opacity: _opacity,
|
||||
sparkleShape: _sparkleShape,
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(16),
|
||||
@@ -127,6 +143,7 @@ class _ExampleHomeState extends State<ExampleHome> {
|
||||
sparkle: _sparkle,
|
||||
specular: _specular,
|
||||
diffraction: _diffraction,
|
||||
opacity: _opacity,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
@@ -169,27 +186,18 @@ class _ExampleHomeState extends State<ExampleHome> {
|
||||
_diffraction = value;
|
||||
});
|
||||
}),
|
||||
_LabeledSlider('Opacity', _opacity, (double value) {
|
||||
setState(() {
|
||||
_opacity = value;
|
||||
});
|
||||
}),
|
||||
const SizedBox(height: 24),
|
||||
const Text('External Tilt Stream + Custom Shape (card)'),
|
||||
const SizedBox(height: 8),
|
||||
Row(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: ElevatedButton(
|
||||
onPressed: () =>
|
||||
_externalTiltController.add(const Offset(0.7, 0.0)),
|
||||
child: const Text('Tilt Right'),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: ElevatedButton(
|
||||
onPressed: () =>
|
||||
_externalTiltController.add(const Offset(-0.7, 0.0)),
|
||||
child: const Text('Tilt Left'),
|
||||
),
|
||||
),
|
||||
],
|
||||
_TiltPresetPicker(
|
||||
onChanged: (Offset tilt) {
|
||||
_externalTiltController.add(tilt);
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Center(
|
||||
@@ -197,6 +205,11 @@ class _ExampleHomeState extends State<ExampleHome> {
|
||||
controller: _overrideController,
|
||||
style: _style,
|
||||
sparkleShape: _sparkleShape,
|
||||
prismatic: _prismatic,
|
||||
sparkle: _sparkle,
|
||||
specular: _specular,
|
||||
diffraction: _diffraction,
|
||||
opacity: _opacity,
|
||||
shape: const StadiumBorder(),
|
||||
background: Container(
|
||||
decoration: const BoxDecoration(
|
||||
@@ -225,6 +238,7 @@ class _ExampleHomeState extends State<ExampleHome> {
|
||||
}
|
||||
|
||||
class _LabeledSlider extends StatelessWidget {
|
||||
/// Creates a slider row with a live numeric label.
|
||||
const _LabeledSlider(this.label, this.value, this.onChanged);
|
||||
|
||||
final String label;
|
||||
@@ -236,7 +250,7 @@ class _LabeledSlider extends StatelessWidget {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: <Widget>[
|
||||
Text(label),
|
||||
Text('$label: ${value.toStringAsFixed(2)}'),
|
||||
Slider(
|
||||
value: value,
|
||||
onChanged: onChanged,
|
||||
@@ -247,6 +261,7 @@ class _LabeledSlider extends StatelessWidget {
|
||||
}
|
||||
|
||||
class _StylePicker extends StatelessWidget {
|
||||
/// Creates the style selection control.
|
||||
const _StylePicker({
|
||||
required this.selectedStyle,
|
||||
required this.onChanged,
|
||||
@@ -262,21 +277,21 @@ class _StylePicker extends StatelessWidget {
|
||||
children: <Widget>[
|
||||
const Text('Style'),
|
||||
const SizedBox(height: 6),
|
||||
Wrap(
|
||||
spacing: 8,
|
||||
runSpacing: 8,
|
||||
children: HolographStyle.values.map((HolographStyle style) {
|
||||
return ChoiceChip(
|
||||
label: Text(_styleLabel(style)),
|
||||
selected: selectedStyle == style,
|
||||
onSelected: (bool selected) {
|
||||
if (!selected) {
|
||||
return;
|
||||
}
|
||||
onChanged(style);
|
||||
},
|
||||
);
|
||||
}).toList(),
|
||||
SegmentedButton<HolographStyle>(
|
||||
segments: HolographStyle.values
|
||||
.map((HolographStyle style) => ButtonSegment<HolographStyle>(
|
||||
value: style,
|
||||
label: Text(_styleLabel(style)),
|
||||
))
|
||||
.toList(),
|
||||
selected: <HolographStyle>{selectedStyle},
|
||||
onSelectionChanged: (Set<HolographStyle> value) {
|
||||
if (value.isNotEmpty) {
|
||||
onChanged(value.first);
|
||||
}
|
||||
},
|
||||
showSelectedIcon: false,
|
||||
multiSelectionEnabled: false,
|
||||
),
|
||||
],
|
||||
);
|
||||
@@ -297,6 +312,7 @@ class _StylePicker extends StatelessWidget {
|
||||
}
|
||||
|
||||
class _SparkleShapePicker extends StatelessWidget {
|
||||
/// Creates sparkle shape chips from the provided shape map.
|
||||
const _SparkleShapePicker({
|
||||
required this.selectedShape,
|
||||
required this.choices,
|
||||
@@ -336,6 +352,45 @@ class _SparkleShapePicker extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
/// Preset controls for feeding an external tilt stream.
|
||||
class _TiltPresetPicker extends StatelessWidget {
|
||||
const _TiltPresetPicker({required this.onChanged});
|
||||
|
||||
final ValueChanged<Offset> onChanged;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Row(
|
||||
children: <Widget>[
|
||||
Expanded(
|
||||
child: FilledButton.tonalIcon(
|
||||
onPressed: () => onChanged(const Offset(-0.7, 0.0)),
|
||||
icon: const Icon(Icons.keyboard_double_arrow_left),
|
||||
label: const Text('Tilt Left'),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: OutlinedButton.icon(
|
||||
onPressed: () => onChanged(Offset.zero),
|
||||
icon: const Icon(Icons.restart_alt),
|
||||
label: const Text('Center'),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: FilledButton.tonalIcon(
|
||||
onPressed: () => onChanged(const Offset(0.7, 0.0)),
|
||||
icon: const Icon(Icons.keyboard_double_arrow_right),
|
||||
label: const Text('Tilt Right'),
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Demonstration card background for the primary example.
|
||||
class _DemoCardBackground extends StatelessWidget {
|
||||
const _DemoCardBackground();
|
||||
|
||||
@@ -390,6 +445,7 @@ class _DemoCardBackground extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
/// Small badge overlay placed on top of the shiny card.
|
||||
class _RareBadge extends StatelessWidget {
|
||||
const _RareBadge();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user