Skip to content

Commit 4f1058b

Browse files
committed
feat: refactor noise shader builder and add intensity control widget
1 parent 9716d94 commit 4f1058b

File tree

2 files changed

+143
-34
lines changed

2 files changed

+143
-34
lines changed
Lines changed: 78 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,11 @@
11
import 'package:flutter/material.dart';
22
import 'package:flutter_shaders/flutter_shaders.dart';
3+
import 'package:google_fonts/google_fonts.dart';
34
import 'dart:ui';
45
import 'shader_builder.dart';
56

67
class NoiseOverlayShaderBuilder extends CustomShaderBuilder {
7-
final double filmGrainIntensity;
8-
final double noiseOpacity;
9-
10-
const NoiseOverlayShaderBuilder({
11-
this.filmGrainIntensity = 0.2,
12-
this.noiseOpacity = 0.3,
13-
});
8+
const NoiseOverlayShaderBuilder();
149

1510
@override
1611
bool get requiresImageSampler => true;
@@ -22,8 +17,7 @@ class NoiseOverlayShaderBuilder extends CustomShaderBuilder {
2217
void setUniforms(FragmentShader shader, Size size, double time) {
2318
shader
2419
..setFloat(0, size.width)
25-
..setFloat(1, size.height)
26-
..setFloat(2, filmGrainIntensity);
20+
..setFloat(1, size.height);
2721
}
2822

2923
@override
@@ -34,23 +28,9 @@ class NoiseOverlayShaderBuilder extends CustomShaderBuilder {
3428
double time,
3529
Widget? child,
3630
) {
37-
return Stack(
38-
children: [
39-
AnimatedSampler(
40-
(image, size, canvas) {
41-
shader.setImageSampler(0, image);
42-
canvas.drawRect(Rect.fromLTWH(0, 0, size.width, size.height), Paint()..shader = shader);
43-
},
44-
45-
child: child ?? const SizedBox(),
46-
),
47-
Center(
48-
child: Text(
49-
'Noise',
50-
style: TextStyle(color: Colors.white, fontSize: 32, fontWeight: FontWeight.bold),
51-
),
52-
),
53-
],
31+
return NoiseShaderOverlayWidget(
32+
shader: shader,
33+
child: child,
5434
);
5535
}
5636

@@ -71,3 +51,75 @@ class NoiseOverlayShaderBuilder extends CustomShaderBuilder {
7151
);
7252
}
7353
}
54+
55+
class NoiseShaderOverlayWidget extends StatefulWidget {
56+
const NoiseShaderOverlayWidget({
57+
super.key,
58+
required this.shader,
59+
this.child,
60+
});
61+
62+
final FragmentShader shader;
63+
final Widget? child;
64+
65+
@override
66+
State<NoiseShaderOverlayWidget> createState() => _NoiseShaderOverlayWidgetState();
67+
}
68+
69+
class _NoiseShaderOverlayWidgetState extends State<NoiseShaderOverlayWidget> {
70+
double intensity = 0.2;
71+
72+
@override
73+
void initState() {
74+
super.initState();
75+
widget.shader.setFloat(2, intensity);
76+
}
77+
78+
@override
79+
Widget build(BuildContext context) {
80+
return Stack(
81+
children: [
82+
AnimatedSampler(
83+
(image, size, canvas) {
84+
widget.shader.setImageSampler(0, image);
85+
canvas.drawRect(Rect.fromLTWH(0, 0, size.width, size.height), Paint()..shader = widget.shader);
86+
},
87+
88+
child: widget.child ?? const SizedBox(),
89+
),
90+
Center(
91+
child: Text(
92+
'Noise',
93+
style: TextStyle(color: Colors.white, fontSize: 32, fontWeight: FontWeight.bold),
94+
),
95+
),
96+
Positioned(
97+
bottom: 0,left: 0, right: 0,
98+
child: Row(
99+
children: [
100+
Expanded(
101+
child: Slider(
102+
value: intensity,
103+
min: 0,
104+
max: 1,
105+
onChanged: (value) {
106+
setState(() {
107+
intensity = value;
108+
widget.shader.setFloat(2, intensity);
109+
});
110+
},
111+
),
112+
),
113+
Text(
114+
'Intensity: ${intensity.toStringAsFixed(2)}',
115+
style: GoogleFonts.spaceMono(
116+
fontSize: 14,
117+
),
118+
),
119+
],
120+
),
121+
),
122+
],
123+
);
124+
}
125+
}

lib/noise_shader_builder.dart

Lines changed: 65 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
import 'package:flutter/material.dart';
2+
import 'package:google_fonts/google_fonts.dart';
23
import 'dart:ui';
34
import 'shader_builder.dart';
45

56
class NoiseShaderBuilder extends CustomShaderBuilder {
6-
final double filmGrainIntensity;
7-
8-
const NoiseShaderBuilder({this.filmGrainIntensity = 0.1});
7+
const NoiseShaderBuilder();
98

109
@override
1110
bool get requiresImageSampler => false;
@@ -18,8 +17,8 @@ class NoiseShaderBuilder extends CustomShaderBuilder {
1817
shader
1918
..setFloat(0, size.width)
2019
..setFloat(1, size.height)
21-
..setFloat(2, time)
22-
..setFloat(3, filmGrainIntensity);
20+
..setFloat(2, time);
21+
// ..setFloat(3, filmGrainIntensity);
2322
}
2423

2524
@override
@@ -30,9 +29,8 @@ class NoiseShaderBuilder extends CustomShaderBuilder {
3029
double time,
3130
Widget? child,
3231
) {
33-
return CustomPaint(
34-
size: Size.infinite,
35-
painter: _NoiseShaderPainter(shader),
32+
return NoiseShaderWidget(
33+
shader: shader,
3634
);
3735
}
3836

@@ -42,6 +40,65 @@ class NoiseShaderBuilder extends CustomShaderBuilder {
4240
}
4341
}
4442

43+
class NoiseShaderWidget extends StatefulWidget {
44+
const NoiseShaderWidget({
45+
super.key,
46+
required this.shader,
47+
});
48+
49+
final FragmentShader shader;
50+
51+
@override
52+
State<NoiseShaderWidget> createState() => _NoiseShaderWidgetState();
53+
}
54+
55+
class _NoiseShaderWidgetState extends State<NoiseShaderWidget> {
56+
double intensity = 0.1;
57+
58+
@override
59+
void initState() {
60+
super.initState();
61+
widget.shader.setFloat(3, intensity);
62+
}
63+
64+
@override
65+
Widget build(BuildContext context) {
66+
return Column(
67+
children: [
68+
Expanded(
69+
child: CustomPaint(
70+
size: Size.infinite,
71+
painter: _NoiseShaderPainter(widget.shader),
72+
),
73+
),
74+
Row(
75+
children: [
76+
Expanded(
77+
child: Slider(
78+
value: intensity,
79+
min: 0,
80+
max: 1,
81+
onChanged: (value) {
82+
setState(() {
83+
intensity = value;
84+
widget.shader.setFloat(3, intensity);
85+
});
86+
},
87+
),
88+
),
89+
Text(
90+
'Intensity: ${intensity.toStringAsFixed(2)}',
91+
style: GoogleFonts.spaceMono(
92+
fontSize: 14,
93+
),
94+
),
95+
],
96+
),
97+
],
98+
);
99+
}
100+
}
101+
45102
class _NoiseShaderPainter extends CustomPainter {
46103
final FragmentShader shader;
47104

0 commit comments

Comments
 (0)