Fix mode-button gradient to fade via alpha instead of a color mix
Interpolating RGB between activeTint and inactiveColor produced a visibly muddy intermediate color that read as a hard cut inside the button rather than a soft fade. Switched to a pure alpha gradient of inactiveColor itself (0.0 -> 0.85): at alpha 0 it exactly matches the header container's own tint sitting behind it, so the seam disappears entirely, and the color only ever mixes with itself. Also pushed the stop from 30% to 45% of the button's width for more breathing room before the solid fill starts.
This commit is contained in:
@@ -46,8 +46,7 @@ class TopModeBar extends ConsumerWidget {
|
|||||||
/// Leistenkante (HTML-Demonstrator: `#topBarWrap{padding:5px 10px}`) - der
|
/// Leistenkante (HTML-Demonstrator: `#topBarWrap{padding:5px 10px}`) - der
|
||||||
/// inaktive Button verzichtet bewusst darauf, siehe Klassendoku oben.
|
/// inaktive Button verzichtet bewusst darauf, siehe Klassendoku oben.
|
||||||
static const _outerPaddingH = 10.0;
|
static const _outerPaddingH = 10.0;
|
||||||
// Halbiert (Nutzerwunsch: vertikaler Innenabstand noch zu gross) - der
|
// Der aktive Moduswechsel-Button und der mittlere Inhalt (Wind-Pille/
|
||||||
// aktive Moduswechsel-Button und der mittlere Inhalt (Wind-Pille/
|
|
||||||
// Suchleiste/Flugmodus) bleiben oben/unten um diesen Betrag von der
|
// Suchleiste/Flugmodus) bleiben oben/unten um diesen Betrag von der
|
||||||
// Leistenkante eingerueckt, siehe Klassendoku.
|
// Leistenkante eingerueckt, siehe Klassendoku.
|
||||||
static const _outerPaddingV = 5.0;
|
static const _outerPaddingV = 5.0;
|
||||||
@@ -113,7 +112,6 @@ class TopModeBar extends ConsumerWidget {
|
|||||||
_ModeButton(
|
_ModeButton(
|
||||||
label: 'Plan',
|
label: 'Plan',
|
||||||
isActive: !isFly,
|
isActive: !isFly,
|
||||||
activeTint: activeTint,
|
|
||||||
inactiveColor: DmcColors.planModeColor,
|
inactiveColor: DmcColors.planModeColor,
|
||||||
isLeftButton: true,
|
isLeftButton: true,
|
||||||
onTap: () => context.read<AppModeCubit>().toPlan(),
|
onTap: () => context.read<AppModeCubit>().toPlan(),
|
||||||
@@ -132,7 +130,6 @@ class TopModeBar extends ConsumerWidget {
|
|||||||
_ModeButton(
|
_ModeButton(
|
||||||
label: 'Fly',
|
label: 'Fly',
|
||||||
isActive: isFly,
|
isActive: isFly,
|
||||||
activeTint: activeTint,
|
|
||||||
inactiveColor: DmcColors.flyModeColor,
|
inactiveColor: DmcColors.flyModeColor,
|
||||||
isLeftButton: false,
|
isLeftButton: false,
|
||||||
onTap: () {
|
onTap: () {
|
||||||
@@ -161,7 +158,6 @@ class _ModeButton extends StatelessWidget {
|
|||||||
const _ModeButton({
|
const _ModeButton({
|
||||||
required this.label,
|
required this.label,
|
||||||
required this.isActive,
|
required this.isActive,
|
||||||
required this.activeTint,
|
|
||||||
required this.inactiveColor,
|
required this.inactiveColor,
|
||||||
required this.isLeftButton,
|
required this.isLeftButton,
|
||||||
required this.onTap,
|
required this.onTap,
|
||||||
@@ -169,11 +165,6 @@ class _ModeButton extends StatelessWidget {
|
|||||||
|
|
||||||
final String label;
|
final String label;
|
||||||
final bool isActive;
|
final bool isActive;
|
||||||
|
|
||||||
/// Aktuelle Kopfleisten-Toenung (TopModeBar.activeTint) - dient nur als
|
|
||||||
/// Startfarbe des Farbverlaufs im inaktiven Zustand (siehe unten), der
|
|
||||||
/// aktive Button hat ohnehin keinen eigenen Hintergrund.
|
|
||||||
final Color activeTint;
|
|
||||||
final Color inactiveColor;
|
final Color inactiveColor;
|
||||||
|
|
||||||
/// true = Plan-Button (linkes Ende der Leiste), false = Fly-Button
|
/// true = Plan-Button (linkes Ende der Leiste), false = Fly-Button
|
||||||
@@ -207,20 +198,31 @@ class _ModeButton extends StatelessWidget {
|
|||||||
decoration: isActive
|
decoration: isActive
|
||||||
? null
|
? null
|
||||||
: BoxDecoration(
|
: BoxDecoration(
|
||||||
// Kurzer Farbverlauf von der Kopfleisten-eigenen Toenung zur
|
// Farbverlauf von der Kopfleisten-eigenen Toenung zur vollen
|
||||||
// vollen Button-Farbe statt einer harten Kante an der
|
// Button-Farbe statt einer harten Kante an der Nahtstelle zum
|
||||||
// Nahtstelle zum mittleren Inhalt (Nutzerwunsch: "linearer
|
// mittleren Inhalt (Nutzerwunsch: "linearer kurzer
|
||||||
// kurzer Farbverlauf zwischen button und rest header") - nur
|
// Farbverlauf zwischen button und rest header"). Reiner
|
||||||
// die ersten 30% der Breite blenden ein, der Rest bleibt
|
// Alpha-Verlauf DERSELBEN inactiveColor (0.0 -> 0.85) statt
|
||||||
// solide, damit der Text weiterhin auf vollem Kontrast sitzt.
|
// einer RGB-Ueberblendung zwischen zwei verschiedenen Farben -
|
||||||
|
// Letzteres erzeugte einen sichtbar "verschmutzten"
|
||||||
|
// Zwischenton, der wie eine harte Kante mitten im Button
|
||||||
|
// wirkte, statt wie ein weiches Einblenden (Nutzer-Feedback:
|
||||||
|
// "der Verlauf schneidet in den Knopf rein"). Bei Alpha 0
|
||||||
|
// liegt exakt die Toenung des umgebenden TopModeBar-
|
||||||
|
// Containers darunter (dieselbe activeTint-Farbe, derselbe
|
||||||
|
// Alpha-Wert 0.55, siehe dortige Decoration), der Uebergang
|
||||||
|
// an der Nahtstelle ist dadurch von selbst nahtlos. Stop bei
|
||||||
|
// 45% statt vorher 30% laesst mehr Abstand, bevor die
|
||||||
|
// Volltonflaeche des eigentlichen Knopfes beginnt (ebenfalls
|
||||||
|
// Nutzer-Feedback).
|
||||||
gradient: LinearGradient(
|
gradient: LinearGradient(
|
||||||
begin: isLeftButton ? Alignment.centerRight : Alignment.centerLeft,
|
begin: isLeftButton ? Alignment.centerRight : Alignment.centerLeft,
|
||||||
end: isLeftButton ? Alignment.centerLeft : Alignment.centerRight,
|
end: isLeftButton ? Alignment.centerLeft : Alignment.centerRight,
|
||||||
colors: [
|
colors: [
|
||||||
activeTint.withValues(alpha: 0.55),
|
inactiveColor.withValues(alpha: 0.0),
|
||||||
inactiveColor.withValues(alpha: 0.85),
|
inactiveColor.withValues(alpha: 0.85),
|
||||||
],
|
],
|
||||||
stops: const [0.0, 0.3],
|
stops: const [0.0, 0.45],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
child: Text(
|
child: Text(
|
||||||
|
|||||||
Reference in New Issue
Block a user