mirror of
https://github.com/bggRGjQaUbCoE/PiliPlus.git
synced 2026-05-31 08:08:19 +08:00
mod: marquee use velocity
This commit is contained in:
committed by
bggRGjQaUbCoE
parent
8d94c0405f
commit
498ab2818e
@@ -1,22 +1,21 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/rendering.dart';
|
import 'package:flutter/rendering.dart';
|
||||||
|
import 'package:flutter/scheduler.dart';
|
||||||
|
|
||||||
class MarqueeText extends StatelessWidget {
|
class MarqueeText extends StatelessWidget {
|
||||||
final double maxWidth;
|
final double maxWidth;
|
||||||
final String text;
|
final String text;
|
||||||
final TextStyle? style;
|
final TextStyle? style;
|
||||||
final int? count;
|
|
||||||
final bool bounce;
|
|
||||||
final double spacing;
|
final double spacing;
|
||||||
|
final double velocity;
|
||||||
|
|
||||||
const MarqueeText(
|
const MarqueeText(
|
||||||
this.text, {
|
this.text, {
|
||||||
super.key,
|
super.key,
|
||||||
required this.maxWidth,
|
required this.maxWidth,
|
||||||
this.style,
|
this.style,
|
||||||
this.count,
|
|
||||||
this.bounce = true,
|
|
||||||
this.spacing = 0,
|
this.spacing = 0,
|
||||||
|
this.velocity = 25,
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -37,12 +36,10 @@ class MarqueeText extends StatelessWidget {
|
|||||||
textDirection: TextDirection.ltr,
|
textDirection: TextDirection.ltr,
|
||||||
);
|
);
|
||||||
if (width > maxWidth) {
|
if (width > maxWidth) {
|
||||||
return SingleWidgetMarquee(
|
return NormalMarquee(
|
||||||
child,
|
velocity: velocity,
|
||||||
duration: Duration(milliseconds: (width / 50 * 1000).round()),
|
|
||||||
bounce: bounce,
|
|
||||||
count: count,
|
|
||||||
spacing: spacing,
|
spacing: spacing,
|
||||||
|
child: child,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return child;
|
return child;
|
||||||
@@ -50,63 +47,15 @@ class MarqueeText extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SingleWidgetMarquee extends StatefulWidget {
|
|
||||||
final Widget child;
|
|
||||||
final Duration? duration;
|
|
||||||
final bool bounce;
|
|
||||||
final double spacing;
|
|
||||||
final int? count;
|
|
||||||
|
|
||||||
const SingleWidgetMarquee(
|
|
||||||
this.child, {
|
|
||||||
super.key,
|
|
||||||
this.duration,
|
|
||||||
this.bounce = false,
|
|
||||||
this.spacing = 0,
|
|
||||||
this.count,
|
|
||||||
});
|
|
||||||
|
|
||||||
@override
|
|
||||||
State<StatefulWidget> createState() => _SingleWidgetMarqueeState();
|
|
||||||
}
|
|
||||||
|
|
||||||
class _SingleWidgetMarqueeState extends State<SingleWidgetMarquee>
|
|
||||||
with SingleTickerProviderStateMixin {
|
|
||||||
late final _controller = AnimationController(
|
|
||||||
vsync: this,
|
|
||||||
duration: widget.duration,
|
|
||||||
reverseDuration: widget.duration,
|
|
||||||
)..repeat(reverse: widget.bounce, count: widget.count);
|
|
||||||
|
|
||||||
@override
|
|
||||||
Widget build(BuildContext context) => widget.bounce
|
|
||||||
? BounceMarquee(
|
|
||||||
animation: _controller,
|
|
||||||
spacing: widget.spacing,
|
|
||||||
child: widget.child,
|
|
||||||
)
|
|
||||||
: NormalMarquee(
|
|
||||||
animation: _controller,
|
|
||||||
spacing: widget.spacing,
|
|
||||||
child: widget.child,
|
|
||||||
);
|
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
_controller.dispose();
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class Marquee extends SingleChildRenderObjectWidget {
|
abstract class Marquee extends SingleChildRenderObjectWidget {
|
||||||
final Axis direction;
|
final Axis direction;
|
||||||
final Clip clipBehavior;
|
final Clip clipBehavior;
|
||||||
final double spacing;
|
final double spacing;
|
||||||
final Animation<double> animation;
|
final double velocity;
|
||||||
|
|
||||||
const Marquee({
|
const Marquee({
|
||||||
super.key,
|
super.key,
|
||||||
required this.animation,
|
required this.velocity,
|
||||||
required super.child,
|
required super.child,
|
||||||
this.direction = Axis.horizontal,
|
this.direction = Axis.horizontal,
|
||||||
this.clipBehavior = Clip.hardEdge,
|
this.clipBehavior = Clip.hardEdge,
|
||||||
@@ -121,7 +70,7 @@ abstract class Marquee extends SingleChildRenderObjectWidget {
|
|||||||
renderObject
|
renderObject
|
||||||
..direction = direction
|
..direction = direction
|
||||||
..clipBehavior = clipBehavior
|
..clipBehavior = clipBehavior
|
||||||
..animation = animation
|
..velocity = velocity
|
||||||
..spacing = spacing;
|
..spacing = spacing;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -129,7 +78,7 @@ abstract class Marquee extends SingleChildRenderObjectWidget {
|
|||||||
class NormalMarquee extends Marquee {
|
class NormalMarquee extends Marquee {
|
||||||
const NormalMarquee({
|
const NormalMarquee({
|
||||||
super.key,
|
super.key,
|
||||||
required super.animation,
|
required super.velocity,
|
||||||
required super.child,
|
required super.child,
|
||||||
super.direction,
|
super.direction,
|
||||||
super.clipBehavior,
|
super.clipBehavior,
|
||||||
@@ -139,7 +88,7 @@ class NormalMarquee extends Marquee {
|
|||||||
@override
|
@override
|
||||||
RenderObject createRenderObject(BuildContext context) => _NormalMarqueeRender(
|
RenderObject createRenderObject(BuildContext context) => _NormalMarqueeRender(
|
||||||
direction: direction,
|
direction: direction,
|
||||||
animation: animation,
|
velocity: velocity,
|
||||||
clipBehavior: clipBehavior,
|
clipBehavior: clipBehavior,
|
||||||
spacing: spacing,
|
spacing: spacing,
|
||||||
);
|
);
|
||||||
@@ -148,7 +97,7 @@ class NormalMarquee extends Marquee {
|
|||||||
class BounceMarquee extends Marquee {
|
class BounceMarquee extends Marquee {
|
||||||
const BounceMarquee({
|
const BounceMarquee({
|
||||||
super.key,
|
super.key,
|
||||||
required super.animation,
|
required super.velocity,
|
||||||
required super.child,
|
required super.child,
|
||||||
super.direction,
|
super.direction,
|
||||||
super.clipBehavior,
|
super.clipBehavior,
|
||||||
@@ -158,7 +107,7 @@ class BounceMarquee extends Marquee {
|
|||||||
@override
|
@override
|
||||||
RenderObject createRenderObject(BuildContext context) => _BounceMarqueeRender(
|
RenderObject createRenderObject(BuildContext context) => _BounceMarqueeRender(
|
||||||
direction: direction,
|
direction: direction,
|
||||||
animation: animation,
|
velocity: velocity,
|
||||||
clipBehavior: clipBehavior,
|
clipBehavior: clipBehavior,
|
||||||
spacing: spacing,
|
spacing: spacing,
|
||||||
);
|
);
|
||||||
@@ -168,15 +117,15 @@ abstract class MarqueeRender extends RenderBox
|
|||||||
with RenderObjectWithChildMixin<RenderBox> {
|
with RenderObjectWithChildMixin<RenderBox> {
|
||||||
MarqueeRender({
|
MarqueeRender({
|
||||||
required Axis direction,
|
required Axis direction,
|
||||||
required Animation<double> animation,
|
required double velocity,
|
||||||
|
required double spacing,
|
||||||
required this.clipBehavior,
|
required this.clipBehavior,
|
||||||
required this.spacing,
|
}) : _spacing = spacing,
|
||||||
}) : _direction = direction,
|
_velocity = velocity,
|
||||||
_animation = animation,
|
_direction = direction,
|
||||||
assert(spacing.isFinite && !spacing.isNaN);
|
assert(spacing.isFinite && !spacing.isNaN);
|
||||||
|
|
||||||
Clip clipBehavior;
|
Clip clipBehavior;
|
||||||
double spacing;
|
|
||||||
|
|
||||||
Axis _direction;
|
Axis _direction;
|
||||||
Axis get direction => _direction;
|
Axis get direction => _direction;
|
||||||
@@ -186,40 +135,61 @@ abstract class MarqueeRender extends RenderBox
|
|||||||
markNeedsLayout();
|
markNeedsLayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
Animation<double> _animation;
|
double _velocity;
|
||||||
Animation<double> get animation => _animation;
|
set velocity(double value) {
|
||||||
set animation(Animation<double> value) {
|
if (_velocity == value) return;
|
||||||
if (_animation == value) return;
|
_velocity = value;
|
||||||
if (_listened) {
|
_simulation = _simulation?.copyWith(initialValue: _delta, velocity: value);
|
||||||
_animation.removeListener(markNeedsPaint);
|
ticker?.reset();
|
||||||
value.addListener(markNeedsPaint);
|
}
|
||||||
|
|
||||||
|
double _spacing;
|
||||||
|
set spacing(double value) {
|
||||||
|
if (value.isNegative) {
|
||||||
|
value *= _direction == Axis.horizontal ? -size.width : -size.height;
|
||||||
}
|
}
|
||||||
_animation = value;
|
if (_spacing == value) return;
|
||||||
|
|
||||||
|
_simulation = _simulation?.copyWith(
|
||||||
|
initialValue: _delta,
|
||||||
|
addSize: value - _spacing,
|
||||||
|
);
|
||||||
|
_spacing = value;
|
||||||
|
ticker?.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
double _delta = 0;
|
||||||
|
set delta(double value) {
|
||||||
|
if (_delta == value) return;
|
||||||
|
_delta = value;
|
||||||
|
markNeedsPaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void detach() {
|
void detach() {
|
||||||
_removeListener();
|
ticker?.stop();
|
||||||
super.detach();
|
super.detach();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _listened = false;
|
@override
|
||||||
void _addListener() {
|
void attach(PipelineOwner owner) {
|
||||||
if (!_listened) {
|
super.attach(owner);
|
||||||
_animation.addListener(markNeedsPaint);
|
ticker?.start();
|
||||||
_listened = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _removeListener() {
|
@override
|
||||||
if (_listened) {
|
void dispose() {
|
||||||
_animation.removeListener(markNeedsPaint);
|
ticker?.dispose();
|
||||||
_listened = false;
|
ticker = null;
|
||||||
}
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
late double _distance;
|
late double _distance;
|
||||||
|
|
||||||
|
Ticker? ticker;
|
||||||
|
|
||||||
|
_MarqueeSimulation? _simulation;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void performLayout() {
|
void performLayout() {
|
||||||
final child = this.child;
|
final child = this.child;
|
||||||
@@ -235,7 +205,7 @@ abstract class MarqueeRender extends RenderBox
|
|||||||
);
|
);
|
||||||
size = constraints.constrain(child.size);
|
size = constraints.constrain(child.size);
|
||||||
_distance = child.size.width - size.width;
|
_distance = child.size.width - size.width;
|
||||||
if (spacing.isNegative) spacing *= -size.width;
|
if (_spacing.isNegative) _spacing *= -size.width;
|
||||||
} else {
|
} else {
|
||||||
child.layout(
|
child.layout(
|
||||||
BoxConstraints(maxWidth: constraints.maxWidth),
|
BoxConstraints(maxWidth: constraints.maxWidth),
|
||||||
@@ -243,12 +213,15 @@ abstract class MarqueeRender extends RenderBox
|
|||||||
);
|
);
|
||||||
size = constraints.constrain(child.size);
|
size = constraints.constrain(child.size);
|
||||||
_distance = child.size.height - size.height;
|
_distance = child.size.height - size.height;
|
||||||
if (spacing.isNegative) spacing *= -size.height;
|
if (_spacing.isNegative) _spacing *= -size.height;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_distance > 0) {
|
if (_distance > 0) {
|
||||||
_addListener();
|
updateSize();
|
||||||
|
ticker ??= Ticker(_onTick)..start();
|
||||||
} else {
|
} else {
|
||||||
_removeListener();
|
ticker?.dispose();
|
||||||
|
ticker = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -262,41 +235,42 @@ abstract class MarqueeRender extends RenderBox
|
|||||||
context.paintChild(child!, Offset(offset.dx, offset.dy - _distance / 2));
|
context.paintChild(child!, Offset(offset.dx, offset.dy - _distance / 2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _onTick(Duration elapsed) {
|
||||||
|
delta = _simulation!.x(
|
||||||
|
elapsed.inMicroseconds.toDouble() / Duration.microsecondsPerSecond,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _BounceMarqueeRender extends MarqueeRender {
|
class _BounceMarqueeRender extends MarqueeRender {
|
||||||
_BounceMarqueeRender({
|
_BounceMarqueeRender({
|
||||||
required super.direction,
|
required super.direction,
|
||||||
required super.animation,
|
required super.velocity,
|
||||||
required super.clipBehavior,
|
required super.clipBehavior,
|
||||||
required super.spacing,
|
required super.spacing,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
void updateSize() {
|
||||||
|
final size = _distance + _spacing;
|
||||||
|
if (size == _simulation?.size) return;
|
||||||
|
_simulation = _MarqueeSimulation(_delta, size, false, _velocity);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void paint(PaintingContext context, Offset offset) {
|
void paint(PaintingContext context, Offset offset) {
|
||||||
if (child == null) return;
|
if (child == null) return;
|
||||||
|
|
||||||
final tick = _animation.value;
|
|
||||||
|
|
||||||
if (_distance > 0) {
|
if (_distance > 0) {
|
||||||
final helfSpacing = spacing / 2.0;
|
final delta = _spacing / 2.0 - _delta;
|
||||||
void paintChild() {
|
void paintChild() {
|
||||||
if (_direction == Axis.horizontal) {
|
if (_direction == Axis.horizontal) {
|
||||||
context.paintChild(
|
context.paintChild(child!, Offset(offset.dx + delta, offset.dy));
|
||||||
child!,
|
|
||||||
Offset(
|
|
||||||
offset.dx + helfSpacing - tick * (_distance + spacing),
|
|
||||||
offset.dy,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
context.paintChild(
|
context.paintChild(child!, Offset(offset.dx, offset.dy + delta));
|
||||||
child!,
|
|
||||||
Offset(
|
|
||||||
offset.dx,
|
|
||||||
offset.dy + helfSpacing - tick * (_distance + spacing),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -315,33 +289,46 @@ class _BounceMarqueeRender extends MarqueeRender {
|
|||||||
class _NormalMarqueeRender extends MarqueeRender {
|
class _NormalMarqueeRender extends MarqueeRender {
|
||||||
_NormalMarqueeRender({
|
_NormalMarqueeRender({
|
||||||
required super.direction,
|
required super.direction,
|
||||||
required super.animation,
|
required super.velocity,
|
||||||
required super.clipBehavior,
|
required super.clipBehavior,
|
||||||
required super.spacing,
|
required super.spacing,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@override
|
||||||
|
void updateSize() {
|
||||||
|
final size =
|
||||||
|
(_direction == Axis.horizontal
|
||||||
|
? child!.size.width
|
||||||
|
: child!.size.height) +
|
||||||
|
_spacing;
|
||||||
|
if (size == _simulation?.size) return;
|
||||||
|
_simulation = _MarqueeSimulation(_delta, size, true, _velocity);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void paint(PaintingContext context, Offset offset) {
|
void paint(PaintingContext context, Offset offset) {
|
||||||
final child = this.child;
|
final child = this.child;
|
||||||
if (child == null) return;
|
if (child == null) return;
|
||||||
|
|
||||||
final tick = _animation.value;
|
|
||||||
|
|
||||||
if (_distance > 0) {
|
if (_distance > 0) {
|
||||||
void paintChild() {
|
void paintChild() {
|
||||||
if (_direction == Axis.horizontal) {
|
if (_direction == Axis.horizontal) {
|
||||||
final w = child.size.width + spacing;
|
final dx = _delta;
|
||||||
final dx = tick * w;
|
|
||||||
context.paintChild(child, Offset(offset.dx - dx, offset.dy));
|
context.paintChild(child, Offset(offset.dx - dx, offset.dy));
|
||||||
if (dx > _distance) {
|
if (dx > _distance) {
|
||||||
context.paintChild(child, Offset(offset.dx + w - dx, offset.dy));
|
context.paintChild(
|
||||||
|
child,
|
||||||
|
Offset(offset.dx + _simulation!.size - dx, offset.dy),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
final h = child.size.height + spacing;
|
final dy = _delta;
|
||||||
final dy = tick * h;
|
|
||||||
context.paintChild(child, Offset(offset.dx, offset.dy - dy));
|
context.paintChild(child, Offset(offset.dx, offset.dy - dy));
|
||||||
if (dy > _distance) {
|
if (dy > _distance) {
|
||||||
context.paintChild(child, Offset(offset.dx, offset.dy + h - dy));
|
context.paintChild(
|
||||||
|
child,
|
||||||
|
Offset(offset.dx, offset.dy + _simulation!.size - dy),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -357,3 +344,54 @@ class _NormalMarqueeRender extends MarqueeRender {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class _MarqueeSimulation extends Simulation {
|
||||||
|
_MarqueeSimulation(
|
||||||
|
this.initialValue,
|
||||||
|
this.size,
|
||||||
|
this.notBounce,
|
||||||
|
this.velocity,
|
||||||
|
);
|
||||||
|
|
||||||
|
final double initialValue;
|
||||||
|
final double size;
|
||||||
|
final bool notBounce;
|
||||||
|
final double velocity;
|
||||||
|
|
||||||
|
@override
|
||||||
|
double x(double timeInSeconds) {
|
||||||
|
assert(timeInSeconds >= 0.0);
|
||||||
|
final totalX = initialValue + velocity * timeInSeconds;
|
||||||
|
if (notBounce) return totalX % size;
|
||||||
|
|
||||||
|
final doublePeriod = 2.0 * size;
|
||||||
|
final doubleX = totalX % doublePeriod;
|
||||||
|
return doubleX < size ? doubleX : doublePeriod - doubleX;
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
double dx(double timeInSeconds) => velocity;
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool isDone(double timeInSeconds) => false;
|
||||||
|
|
||||||
|
_MarqueeSimulation copyWith({
|
||||||
|
final double? initialValue,
|
||||||
|
final double? addSize,
|
||||||
|
final bool? notBounce,
|
||||||
|
final double? velocity,
|
||||||
|
}) => _MarqueeSimulation(
|
||||||
|
initialValue ?? this.initialValue,
|
||||||
|
addSize == null ? size : size + addSize,
|
||||||
|
notBounce ?? this.notBounce,
|
||||||
|
velocity ?? this.velocity,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
extension on Ticker {
|
||||||
|
void reset() {
|
||||||
|
this
|
||||||
|
..stop()
|
||||||
|
..start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -19,18 +19,12 @@ class MusicRecommandPage extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _MusicRecommandPageState extends State<MusicRecommandPage>
|
class _MusicRecommandPageState extends State<MusicRecommandPage>
|
||||||
with GridMixin, SingleTickerProviderStateMixin {
|
with GridMixin {
|
||||||
late final _controller = Get.put(
|
late final _controller = Get.put(
|
||||||
MusicRecommendController(),
|
MusicRecommendController(),
|
||||||
tag: Utils.generateRandomString(8),
|
tag: Utils.generateRandomString(8),
|
||||||
);
|
);
|
||||||
|
|
||||||
late final _animation = AnimationController(
|
|
||||||
vsync: this,
|
|
||||||
duration: const Duration(seconds: 5),
|
|
||||||
reverseDuration: const Duration(seconds: 5),
|
|
||||||
)..repeat(reverse: true);
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final theme = Theme.of(context);
|
final theme = Theme.of(context);
|
||||||
@@ -68,10 +62,8 @@ class _MusicRecommandPageState extends State<MusicRecommandPage>
|
|||||||
response?.isNotEmpty == true
|
response?.isNotEmpty == true
|
||||||
? SliverGrid.builder(
|
? SliverGrid.builder(
|
||||||
gridDelegate: gridDelegate,
|
gridDelegate: gridDelegate,
|
||||||
itemBuilder: (context, index) => MusicVideoCardH(
|
itemBuilder: (context, index) =>
|
||||||
videoItem: response[index],
|
MusicVideoCardH(videoItem: response[index]),
|
||||||
animation: _animation,
|
|
||||||
),
|
|
||||||
itemCount: response!.length,
|
itemCount: response!.length,
|
||||||
)
|
)
|
||||||
: HttpError(onReload: _controller.onReload),
|
: HttpError(onReload: _controller.onReload),
|
||||||
@@ -120,10 +112,4 @@ class _MusicRecommandPageState extends State<MusicRecommandPage>
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
void dispose() {
|
|
||||||
_animation.dispose();
|
|
||||||
super.dispose();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,12 +14,10 @@ import 'package:flutter/material.dart';
|
|||||||
|
|
||||||
class MusicVideoCardH extends StatelessWidget {
|
class MusicVideoCardH extends StatelessWidget {
|
||||||
final BgmRecommend videoItem;
|
final BgmRecommend videoItem;
|
||||||
final Animation<double> animation;
|
|
||||||
|
|
||||||
const MusicVideoCardH({
|
const MusicVideoCardH({
|
||||||
super.key,
|
super.key,
|
||||||
required this.videoItem,
|
required this.videoItem,
|
||||||
required this.animation,
|
|
||||||
});
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -117,7 +115,7 @@ class MusicVideoCardH extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 3),
|
const SizedBox(height: 3),
|
||||||
BounceMarquee(
|
BounceMarquee(
|
||||||
animation: animation,
|
velocity: 25,
|
||||||
child: Row(
|
child: Row(
|
||||||
spacing: 8,
|
spacing: 8,
|
||||||
children: [
|
children: [
|
||||||
|
|||||||
@@ -1933,8 +1933,6 @@ class HeaderControlState extends TripleState<HeaderControl> {
|
|||||||
return MarqueeText(
|
return MarqueeText(
|
||||||
title,
|
title,
|
||||||
maxWidth: constraints.maxWidth,
|
maxWidth: constraints.maxWidth,
|
||||||
count: 3,
|
|
||||||
bounce: false,
|
|
||||||
spacing: 30,
|
spacing: 30,
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
|
|||||||
Reference in New Issue
Block a user