Skip to content

Commit 41bc356

Browse files
committed
add color filter effect
1 parent 4073b81 commit 41bc356

File tree

5 files changed

+247
-27
lines changed

5 files changed

+247
-27
lines changed

example/lib/main.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ class MyApp extends StatelessWidget {
1919
title: 'Hyper Effects Story Book',
2020
debugShowCheckedModeBanner: false,
2121
home: Storybook(
22+
initialStory: 'Scroll Phase Offset',
2223
stories: [
2324
Story(
2425
name: 'Scroll Phase Offset',

example/lib/stories/scroll_phase_transition.dart

Lines changed: 73 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -18,35 +18,85 @@ class _ScrollPhaseTransitionState extends State<ScrollPhaseTransition> {
1818
return Color.fromARGB(255, r, g, b);
1919
}
2020

21+
static const List<String> images = [
22+
'https://imgv3.fotor.com/images/slider-image/A-clear-image-of-a-woman-wearing-red-sharpened-by-Fotors-image-sharpener.jpg',
23+
'https://media.istockphoto.com/id/1281783803/photo/mountains-velliangiri-view-with-blue-sky-and-green-fores.jpg?s=612x612&w=0&k=20&c=25epzQEXtzNmGMtUoBa13SpHZ4rGz2HDLuHfWaUa51o=',
24+
'https://stimg.cardekho.com/images/carexteriorimages/630x420/Hyundai/Venue/10142/1684739946788/front-left-side-47.jpg?imwidth=420&impolicy=resize',
25+
'https://www.befunky.com/images/prismic/82e0e255-17f9-41e0-85f1-210163b0ea34_hero-blur-image-3.jpg?auto=avif,webp&format=jpg&width=896',
26+
'https://images.unsplash.com/photo-1682685797661-9e0c87f59c60',
27+
];
28+
2129
@override
2230
Widget build(BuildContext context) {
2331
return ListView.builder(
2432
itemBuilder: (context, index) {
25-
return Container(
26-
width: 350,
27-
height: 200,
28-
margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
29-
alignment: Alignment.center,
30-
decoration: BoxDecoration(
31-
color: randomColor(index),
32-
borderRadius: BorderRadius.circular(16),
33-
),
34-
child: Text(
35-
'Item $index',
36-
style: const TextStyle(
37-
fontSize: 24,
38-
color: Colors.white,
33+
return Padding(
34+
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
35+
child: Container(
36+
width: 350,
37+
height: 200,
38+
alignment: Alignment.center,
39+
clipBehavior: Clip.antiAlias,
40+
decoration: BoxDecoration(
41+
// color: randomColor(index),
42+
image: DecorationImage(
43+
image: NetworkImage(
44+
images[index % images.length],
45+
),
46+
fit: BoxFit.cover,
47+
),
48+
borderRadius: BorderRadius.circular(16),
49+
),
50+
child: Text(
51+
'Item $index',
52+
style: const TextStyle(
53+
fontSize: 24,
54+
color: Colors.white,
55+
),
3956
),
40-
),
41-
).scrollTransition(
42-
(context, widget, event) =>
43-
widget.scale(event.phase.isIdentity ? 1 : 0.7).translateX(
44-
switch (event.phase) {
57+
).scrollTransition((context, widget, event) =>
58+
widget /*.translateX(
59+
switch (event.phase) {
60+
ScrollPhase.identity => 0,
61+
ScrollPhase.topLeading => 200,
62+
ScrollPhase.bottomTrailing => -200,
63+
},
64+
)*/
65+
/*.colorFilter(color:
66+
switch (event.phase) {
67+
ScrollPhase.identity =>
68+
Colors.pink.withOpacity(0.5),
69+
ScrollPhase.topLeading =>
70+
Colors.blue.withOpacity(0.5),
71+
ScrollPhase.bottomTrailing =>
72+
Colors.blue.withOpacity(0.5),
73+
},
74+
mode: BlendMode.overlay,
75+
)*/
76+
.colorFilter(
77+
matrix: switch (event.phase) {
78+
ScrollPhase.identity => ColorFilterMatrix.greyscale,
79+
ScrollPhase.topLeading => ColorFilterMatrix.sepia,
80+
ScrollPhase.bottomTrailing => ColorFilterMatrix.sepia,
81+
},
82+
// color: switch (event.phase) {
83+
// ScrollPhase.identity =>
84+
// Colors.pink.withOpacity(0.5),
85+
// ScrollPhase.topLeading =>
86+
// Colors.blue.withOpacity(0.5),
87+
// ScrollPhase.bottomTrailing =>
88+
// Colors.blue.withOpacity(0.5),
89+
// },
90+
mode: BlendMode.overlay,
91+
)
92+
.clipRRect(BorderRadius.circular(16))
93+
.scale(event.phase.isIdentity ? 1 : 0.7)
94+
/*.rotate(switch (event.phase) {
4595
ScrollPhase.identity => 0,
46-
ScrollPhase.topLeading => 200,
47-
ScrollPhase.bottomTrailing => -200,
48-
},
49-
),
96+
ScrollPhase.topLeading => pi / 2,
97+
ScrollPhase.bottomTrailing => -pi / 2,
98+
}),*/
99+
),
50100
);
51101
},
52102
);

example/macos/Runner/DebugProfile.entitlements

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
<true/>
77
<key>com.apple.security.cs.allow-jit</key>
88
<true/>
9+
<key>com.apple.security.network.client</key>
10+
<true/>
911
<key>com.apple.security.network.server</key>
1012
<true/>
1113
</dict>
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
import 'dart:ui';
2+
3+
import 'package:flutter/widgets.dart';
4+
import 'package:hyper_effects/hyper_effects.dart';
5+
6+
/// Provides a extension method to apply an [ColorFilterEffect] to a [Widget].
7+
extension ColorFilterEffectExtension on Widget {
8+
/// Applies an [ColorFilterEffect] to a [Widget].
9+
Widget colorFilter({
10+
Color? color,
11+
BlendMode mode = BlendMode.overlay,
12+
List<double>? matrix,
13+
}) {
14+
return AnimatableEffect(
15+
effect: ColorFilterEffect(
16+
color: color,
17+
mode: mode,
18+
matrix: matrix,
19+
),
20+
child: this,
21+
);
22+
}
23+
}
24+
25+
/// An [Effect] that applies an opacity to a [Widget].
26+
class ColorFilterEffect extends Effect {
27+
/// The color to apply.
28+
final Color? color;
29+
30+
/// The blend mode to apply.
31+
final BlendMode mode;
32+
33+
/// The matrix to apply.
34+
final List<double>? matrix;
35+
36+
/// Creates an [ColorFilterEffect].
37+
ColorFilterEffect({
38+
this.color,
39+
required this.mode,
40+
this.matrix,
41+
}) : assert(color != null || matrix != null,
42+
'Either color or matrix4 must be provided.');
43+
44+
@override
45+
ColorFilterEffect lerp(covariant ColorFilterEffect other, double value) {
46+
final List<double> lerped = [];
47+
for (final (index, item) in matrix?.indexed ?? [].indexed) {
48+
final val = lerpDouble(item, other.matrix?[index], value);
49+
lerped.add(val ?? 0);
50+
}
51+
return ColorFilterEffect(
52+
color: color != null ? Color.lerp(color, other.color, value) : null,
53+
matrix: lerped,
54+
mode: mode,
55+
);
56+
}
57+
58+
@override
59+
Widget apply(BuildContext context, Widget child) {
60+
return ColorFiltered(
61+
colorFilter: color != null
62+
? ColorFilter.mode(color!, mode)
63+
: ColorFilter.matrix(matrix!),
64+
child: child,
65+
);
66+
}
67+
68+
@override
69+
List<Object?> get props => [color, mode, matrix];
70+
}
71+
72+
class ColorFilterMatrix {
73+
ColorFilterMatrix._();
74+
75+
static const List<double> invert = <double>[
76+
-1,
77+
0,
78+
0,
79+
0,
80+
255,
81+
0,
82+
-1,
83+
0,
84+
0,
85+
255,
86+
0,
87+
0,
88+
-1,
89+
0,
90+
255,
91+
0,
92+
0,
93+
0,
94+
1,
95+
0,
96+
];
97+
98+
static const List<double> sepia = <double>[
99+
0.393,
100+
0.769,
101+
0.189,
102+
0,
103+
0,
104+
0.349,
105+
0.686,
106+
0.168,
107+
0,
108+
0,
109+
0.272,
110+
0.534,
111+
0.131,
112+
0,
113+
0,
114+
0,
115+
0,
116+
0,
117+
1,
118+
0,
119+
];
120+
121+
static const List<double> greyscale = <double>[
122+
0.2126,
123+
0.7152,
124+
0.0722,
125+
0,
126+
0,
127+
0.2126,
128+
0.7152,
129+
0.0722,
130+
0,
131+
0,
132+
0.2126,
133+
0.7152,
134+
0.0722,
135+
0,
136+
0,
137+
0,
138+
0,
139+
0,
140+
1,
141+
0,
142+
];
143+
144+
static const List<double> identity = <double>[
145+
1,
146+
0,
147+
0,
148+
0,
149+
0,
150+
0,
151+
1,
152+
0,
153+
0,
154+
0,
155+
0,
156+
0,
157+
1,
158+
0,
159+
0,
160+
0,
161+
0,
162+
0,
163+
1,
164+
0,
165+
];
166+
}

lib/src/effects/effects.dart

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
library effects;
22

3+
export 'blur_effect.dart';
4+
export 'clip_effect.dart';
5+
export 'color_filter_effect.dart';
36
export 'effect.dart';
7+
export 'opacity_effect.dart';
48
export 'rotation_effect.dart';
59
export 'scale_effect.dart';
6-
export 'translate_effect.dart';
710
export 'skew_effect.dart';
811
export 'transform_effect.dart';
9-
export 'blur_effect.dart';
10-
export 'clip_effect.dart';
11-
export 'opacity_effect.dart';
12+
export 'translate_effect.dart';

0 commit comments

Comments
 (0)