From 6741333367662562028a2042c54dca2c010a7cec Mon Sep 17 00:00:00 2001 From: bggRGjQaUbCoE Date: Fri, 29 Aug 2025 14:49:24 +0800 Subject: [PATCH] opt marquee Signed-off-by: bggRGjQaUbCoE --- lib/common/widgets/marquee.dart | 23 +++++-- lib/pages/video/widgets/header_control.dart | 68 ++++++++++++--------- 2 files changed, 55 insertions(+), 36 deletions(-) diff --git a/lib/common/widgets/marquee.dart b/lib/common/widgets/marquee.dart index dfb58404..d2f62165 100644 --- a/lib/common/widgets/marquee.dart +++ b/lib/common/widgets/marquee.dart @@ -5,12 +5,18 @@ class MarqueeText extends StatelessWidget { final double maxWidth; final String text; final TextStyle? style; + final int? count; + final bool bounce; + final double spacing; const MarqueeText( this.text, { + super.key, required this.maxWidth, this.style, - super.key, + this.count, + this.bounce = true, + this.spacing = 0, }); @override @@ -22,18 +28,21 @@ class MarqueeText extends StatelessWidget { ), textDirection: TextDirection.ltr, maxLines: 1, - )..layout(maxWidth: maxWidth); + )..layout(); + final width = textPainter.width; final child = Text( text, style: style, maxLines: 1, textDirection: TextDirection.ltr, ); - if (textPainter.didExceedMaxLines) { + if (width > maxWidth) { return SingleWidgetMarquee( child, - duration: const Duration(seconds: 5), - bounce: true, + duration: Duration(milliseconds: (width / 50 * 1000).round()), + bounce: bounce, + count: count, + spacing: spacing, ); } else { return child; @@ -46,6 +55,7 @@ class SingleWidgetMarquee extends StatefulWidget { final Duration? duration; final bool bounce; final double spacing; + final int? count; const SingleWidgetMarquee( this.child, { @@ -53,6 +63,7 @@ class SingleWidgetMarquee extends StatefulWidget { this.duration, this.bounce = false, this.spacing = 0, + this.count, }); @override @@ -65,7 +76,7 @@ class _SingleWidgetMarqueeState extends State vsync: this, duration: widget.duration, reverseDuration: widget.duration, - )..repeat(reverse: widget.bounce); + )..repeat(reverse: widget.bounce, count: widget.count); @override Widget build(BuildContext context) => widget.bounce diff --git a/lib/pages/video/widgets/header_control.dart b/lib/pages/video/widgets/header_control.dart index 937ba30e..827541a7 100644 --- a/lib/pages/video/widgets/header_control.dart +++ b/lib/pages/video/widgets/header_control.dart @@ -1956,36 +1956,44 @@ class HeaderControlState extends TripleState { mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ - LayoutBuilder( - builder: (context, constraints) { - return Obx( - () { - final videoDetail = - introController.videoDetail.value; - final String title; - if (videoDetail.videos == 1) { - title = videoDetail.title!; - } else { - title = - videoDetail.pages - ?.firstWhereOrNull( - (e) => - e.cid == videoDetailCtr.cid.value, - ) - ?.pagePart ?? - videoDetail.title!; - } - return MarqueeText( - title, - maxWidth: constraints.maxWidth, - style: const TextStyle( - color: Colors.white, - fontSize: 16, - ), - ); - }, - ); - }, + Padding( + padding: isPortrait + ? EdgeInsets.zero + : const EdgeInsets.only(right: 10), + child: LayoutBuilder( + builder: (context, constraints) { + return Obx( + () { + final videoDetail = + introController.videoDetail.value; + final String title; + if (videoDetail.videos == 1) { + title = videoDetail.title!; + } else { + title = + videoDetail.pages + ?.firstWhereOrNull( + (e) => + e.cid == videoDetailCtr.cid.value, + ) + ?.pagePart ?? + videoDetail.title!; + } + return MarqueeText( + title, + maxWidth: constraints.maxWidth, + count: 3, + bounce: false, + spacing: 30, + style: const TextStyle( + color: Colors.white, + fontSize: 16, + ), + ); + }, + ); + }, + ), ), if (introController.isShowOnlineTotal) Obx(