import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Marquee Text Example'),
),
body: const Center(
child: SizedBox(
width: 250,
child: MarqueeText(
text: '짧은 글입니다. 짧은 글입니다. 짧은 글입니다. 짧은 글입니다.',
),
),
),
),
);
}
}
class MarqueeText extends StatefulWidget {
final String text;
final TextStyle style;
final Duration duration;
const MarqueeText({
super.key,
required this.text,
this.style = const TextStyle(fontSize: 24),
this.duration = const Duration(seconds: 5),
});
@override
_MarqueeTextState createState() => _MarqueeTextState();
}
class _MarqueeTextState extends State<MarqueeText>
with SingleTickerProviderStateMixin {
late final ScrollController _scrollController;
late final AnimationController _animationController;
late final Animation<double> _animation;
@override
void initState() {
super.initState();
_scrollController = ScrollController();
_animationController = AnimationController(
vsync: this,
duration: Duration(
milliseconds: widget.text.length * 150,
),
);
_animation = Tween<double>(begin: 0, end: 1).animate(_animationController)
..addListener(() {
if (_scrollController.hasClients) {
_scrollController.jumpTo(
_scrollController.position.maxScrollExtent * _animation.value);
}
})
..addStatusListener((status) {
if (status == AnimationStatus.completed) {
_animationController.repeat(
reverse: true,
);
}
});
WidgetsBinding.instance.addPostFrameCallback((_) {
if (_scrollController.hasClients) {
_animationController.forward();
}
});
}
@override
void dispose() {
_animationController.dispose();
_scrollController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return ShaderMask(
shaderCallback: (Rect bounds) {
return const LinearGradient(
begin: Alignment.centerLeft,
end: Alignment.centerRight,
colors: [
Colors.transparent,
Colors.black,
Colors.black,
Colors.transparent
],
stops: [0.0, 0.05, 0.95, 1.0],
).createShader(bounds);
},
blendMode: BlendMode.dstIn,
child: SingleChildScrollView(
controller: _scrollController,
scrollDirection: Axis.horizontal,
child: Text(
widget.text,
style: widget.style,
),
),
);
}
}