WanderndesCover ersetzt Hero-Übergang: Cover wandert live mit progress
This commit is contained in:
@@ -2,7 +2,6 @@ import 'package:audio_service/audio_service.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../shared/cover.dart';
|
||||
import '../shared/theme.dart';
|
||||
import 'audio_handler.dart';
|
||||
import 'now_playing_screen.dart';
|
||||
@@ -136,12 +135,11 @@ class _LeisteState extends State<_Leiste> {
|
||||
child: Row(
|
||||
children: [
|
||||
const SizedBox(width: MeloSpace.md),
|
||||
// Dasselbe Bild wie im Vollbild: es wandert beim Öffnen
|
||||
// dorthin, statt dass ein neuer Bildschirm aufspringt.
|
||||
Hero(
|
||||
tag: coverHeldenName,
|
||||
child: CoverImage(artUri: item.artUri, size: 52),
|
||||
),
|
||||
// Das Cover rendert WanderndesCover in HomeShell in
|
||||
// einer eigenen Ebene über allem (deckt exakt diese
|
||||
// Position bei progress == 0 ab) — hier nur Platz
|
||||
// freihalten, damit Titel/Bedienung nicht springen.
|
||||
const SizedBox(width: 52),
|
||||
const SizedBox(width: MeloSpace.md),
|
||||
Expanded(
|
||||
child: Column(
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'dart:async';
|
||||
import 'dart:ui' show lerpDouble;
|
||||
|
||||
import 'package:audio_service/audio_service.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
@@ -7,6 +8,7 @@ import 'package:provider/provider.dart';
|
||||
|
||||
import '../library/database.dart';
|
||||
import '../services/navidrome_service.dart';
|
||||
import '../shared/cover.dart';
|
||||
import '../shared/favorite_button.dart';
|
||||
import '../shared/server_favorite_button.dart';
|
||||
import '../shared/theme.dart';
|
||||
@@ -101,11 +103,6 @@ class NowPlayingScreen extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
/// Gemeinsamer Name des Coverbilds in Mini-Player und Vollbild — bis Task 6
|
||||
/// (WanderndesCover) den bisherigen Hero-Übergang vollständig ersetzt hat,
|
||||
/// nutzt `mini_player.dart` diesen Namen noch für sein eigenes Hero-Cover.
|
||||
const coverHeldenName = 'melo-cover';
|
||||
|
||||
/// Schlüssel des Cover-Platzhalters — Task 6 misst darüber die tatsächliche
|
||||
/// Vollbild-Position/-Größe des Covers (`RenderBox.localToGlobal`), statt
|
||||
/// `NowPlayingScreen`s responsives Layout (Row/Column-Weiche, AspectRatio)
|
||||
@@ -122,6 +119,40 @@ class _CoverPlatzhalter extends StatelessWidget {
|
||||
AspectRatio(key: coverPlatzhalterKey, aspectRatio: 1, child: const SizedBox());
|
||||
}
|
||||
|
||||
/// Cover-Bild, das zwischen Mini-Player- und Vollbild-Rechteck wandert.
|
||||
///
|
||||
/// Ersetzt die frühere `Hero`-Animation: die feuert nur bei echten
|
||||
/// Navigator-Transitions, und `NowPlayingScreen` ist seit dem Overlay-Umbau
|
||||
/// keine Route mehr. Positionierung/Größe kommen direkt aus [progress],
|
||||
/// live an die Zugstrecke der Wischgeste gekoppelt.
|
||||
class WanderndesCover extends StatelessWidget {
|
||||
const WanderndesCover({
|
||||
super.key,
|
||||
required this.progress,
|
||||
required this.artUri,
|
||||
required this.miniRect,
|
||||
required this.vollbildRect,
|
||||
});
|
||||
|
||||
final double progress;
|
||||
final Uri? artUri;
|
||||
final Rect miniRect;
|
||||
final Rect vollbildRect;
|
||||
|
||||
static const _miniRadius = 6.0;
|
||||
static const _vollbildRadius = 16.0;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final rect = Rect.lerp(miniRect, vollbildRect, progress)!;
|
||||
final radius = lerpDouble(_miniRadius, _vollbildRadius, progress)!;
|
||||
return Positioned.fromRect(
|
||||
rect: rect,
|
||||
child: CoverImage(artUri: artUri, radius: radius),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// Die bisherigen AppBar-Actions (Songtext, Sleep-Timer, Warteschlange) als
|
||||
/// eigene Kopfzeile statt echter AppBar — eine Route/Scaffold gibt es hier
|
||||
/// nicht mehr.
|
||||
|
||||
Reference in New Issue
Block a user