@@ -5,10 +5,7 @@ import 'package:shaders/tv_test_screen.dart';
55import 'main.dart' ;
66
77class ShaderScreen extends StatefulWidget {
8- const ShaderScreen ({
9- super .key,
10- required this .shaderInfo,
11- });
8+ const ShaderScreen ({super .key, required this .shaderInfo});
129
1310 final ShaderInfo shaderInfo;
1411
@@ -23,13 +20,26 @@ class _ShaderScreenState extends State<ShaderScreen>
2320 @override
2421 void initState () {
2522 super .initState ();
26- _controller = AnimationController (
27- vsync: this ,
28- duration: const Duration (milliseconds: 1800 ),
29- );
30- _controller
31- ..forward ()
32- ..repeat (reverse: true );
23+ final duration = widget.shaderInfo.config.animationDuration;
24+
25+ if (duration != null ) {
26+ // Bounded animation
27+ _controller = AnimationController (vsync: this , duration: duration);
28+ _controller
29+ ..forward ()
30+ ..repeat (reverse: true );
31+ } else {
32+ // Unbounded animation - use a long duration and repeat without reverse
33+ _controller = AnimationController (
34+ vsync: this ,
35+ duration: const Duration (
36+ seconds: 3600 ,
37+ ), // 1 hour cycle for continuous time
38+ );
39+ _controller
40+ ..forward ()
41+ ..repeat ();
42+ }
3343 }
3444
3545 @override
@@ -43,47 +53,59 @@ class _ShaderScreenState extends State<ShaderScreen>
4353 final shaderView = AnimatedBuilder (
4454 animation: _controller,
4555 builder: (context, child) {
46- return ShaderBuilder (
47- assetKey: widget.shaderInfo.assetKey,
48- (context, shader, _) {
49- return AnimatedSampler (
50- (image, size, canvas) {
51- final animation = TweenSequence <double >([
52- TweenSequenceItem (
53- tween: Tween <double >(begin: 0.0 , end: 1.0 )
54- .chain (CurveTween (curve: Curves .easeInOut)),
55- weight: 50.0 ,
56- ),
57- TweenSequenceItem (
58- tween: Tween <double >(begin: 1.0 , end: 0.0 )
59- .chain (CurveTween (curve: Curves .easeInOut)),
60- weight: 50.0 ,
61- ),
62- ]).animate (_controller);
63- widget.shaderInfo.config
64- .setUniforms (shader, size, animation.value);
65- shader.setImageSampler (0 , image);
56+ return ShaderBuilder (assetKey: widget.shaderInfo.assetKey, (
57+ context,
58+ shader,
59+ _,
60+ ) {
61+ return AnimatedSampler ((image, size, canvas) {
62+ final duration = widget.shaderInfo.config.animationDuration;
63+ double timeValue;
64+
65+ if (duration != null ) {
66+ // Bounded animation - use animated value between 0-1
67+ final animation = TweenSequence <double >([
68+ TweenSequenceItem (
69+ tween: Tween <double >(
70+ begin: 0.0 ,
71+ end: 1.0 ,
72+ ).chain (CurveTween (curve: Curves .easeInOut)),
73+ weight: 50.0 ,
74+ ),
75+ TweenSequenceItem (
76+ tween: Tween <double >(
77+ begin: 1.0 ,
78+ end: 0.0 ,
79+ ).chain (CurveTween (curve: Curves .easeInOut)),
80+ weight: 50.0 ,
81+ ),
82+ ]).animate (_controller);
83+ timeValue = animation.value;
84+ } else {
85+ // Unbounded animation - use controller value as continuous time
86+ // Scale the 0-1 controller value to actual time in seconds
87+ timeValue = _controller.value * _controller.duration! .inSeconds;
88+ }
89+
90+ widget.shaderInfo.config.setUniforms (shader, size, timeValue);
91+
92+ // Only set image sampler if the shader requires it
93+ if (widget.shaderInfo.config.requiresImageSampler) {
94+ shader.setImageSampler (0 , image);
95+ }
6696
67- canvas.drawRect (
68- Rect .fromLTWH (0 , 0 , size.width, size.height),
69- Paint ()..shader = shader,
70- );
71- },
72- child: child! ,
97+ canvas.drawRect (
98+ Rect .fromLTWH (0 , 0 , size.width, size.height),
99+ Paint ()..shader = shader,
73100 );
74- },
75- );
101+ }, child : child ! );
102+ } );
76103 },
77- child: const Center (
78- child: TvTestScreen (),
79- ),
104+ child: const Center (child: TvTestScreen ()),
80105 );
81106
82107 return Scaffold (
83- appBar: AppBar (
84- title: Text (widget.shaderInfo.name),
85- centerTitle: true ,
86- ),
108+ appBar: AppBar (title: Text (widget.shaderInfo.name), centerTitle: true ),
87109 body: shaderView,
88110 );
89111 }
0 commit comments