Skip to content

Commit 7acb307

Browse files
committed
❇️ Add ClipEffect.
1 parent 5f4b282 commit 7acb307

File tree

2 files changed

+114
-0
lines changed

2 files changed

+114
-0
lines changed

lib/src/effects/clip_effect.dart

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
import 'package:flutter/widgets.dart';
2+
import 'package:hyper_effects/hyper_effects.dart';
3+
4+
/// Provides a extension method to apply an [ClipEffect] to a [Widget].
5+
extension ClipEffectExtension on Widget {
6+
/// Applies an [ClipEffect] to a [Widget] with the given [clip] and [radius].
7+
Widget clip([
8+
double radius = 16,
9+
Clip? clip,
10+
]) {
11+
return AnimatableEffect(
12+
effect: ClipEffect(
13+
clip: clip ?? Clip.antiAlias,
14+
borderRadius: BorderRadius.circular(radius),
15+
),
16+
child: this,
17+
);
18+
}
19+
20+
/// Applies an [ClipEffect] to a [Widget] with the given [clip] and a
21+
/// [corners].
22+
Widget clipCorners([
23+
List<double> corners = const [16, 16, 16, 16],
24+
Clip? clip,
25+
]) {
26+
final length = corners.length;
27+
28+
assert(length != 3 && length <= 4, 'Corners must have 1, 2 or 4 values');
29+
30+
final BorderRadius borderRadius = switch (corners) {
31+
[num all] => BorderRadius.circular(all.toDouble()),
32+
[num horizontal, num vertical] => BorderRadius.only(
33+
topLeft: Radius.circular(horizontal.toDouble()),
34+
topRight: Radius.circular(horizontal.toDouble()),
35+
bottomRight: Radius.circular(vertical.toDouble()),
36+
bottomLeft: Radius.circular(vertical.toDouble()),
37+
),
38+
[num topLeft, num topRight, num bottomRight, num bottomLeft] =>
39+
BorderRadius.only(
40+
topLeft: Radius.circular(topLeft.toDouble()),
41+
topRight: Radius.circular(topRight.toDouble()),
42+
bottomRight: Radius.circular(bottomRight.toDouble()),
43+
bottomLeft: Radius.circular(bottomLeft.toDouble()),
44+
),
45+
_ => BorderRadius.zero
46+
};
47+
48+
return AnimatableEffect(
49+
effect: ClipEffect(
50+
clip: clip ?? Clip.antiAlias,
51+
borderRadius: borderRadius,
52+
),
53+
child: this,
54+
);
55+
}
56+
57+
/// Applies an [ClipEffect] to a [Widget] with the given [clip] and a
58+
/// [borderRadius].
59+
Widget clipRRect([
60+
BorderRadius borderRadius = const BorderRadius.all(Radius.circular(16)),
61+
Clip? clip,
62+
]) {
63+
return AnimatableEffect(
64+
effect: ClipEffect(
65+
clip: clip ?? Clip.antiAlias,
66+
borderRadius: borderRadius,
67+
),
68+
child: this,
69+
);
70+
}
71+
}
72+
73+
/// An [Effect] that applies an clip to a [Widget].
74+
class ClipEffect extends Effect {
75+
/// The clip to apply to the [Widget]. Defaults to [Clip.antiAlias].
76+
final Clip clip;
77+
78+
/// The border radius to apply to the [Widget]. Defaults to [0].
79+
final BorderRadius borderRadius;
80+
81+
/// Creates an [ClipEffect].
82+
ClipEffect({
83+
required this.clip,
84+
required this.borderRadius,
85+
});
86+
87+
@override
88+
ClipEffect lerp(covariant ClipEffect other, double value) {
89+
return ClipEffect(
90+
clip: other.clip,
91+
borderRadius: BorderRadius.lerp(borderRadius, other.borderRadius, value)!,
92+
);
93+
}
94+
95+
@override
96+
Widget apply(BuildContext context, Widget child) {
97+
// if (clip == Clip.none) return child;
98+
// if (borderRadius == BorderRadius.zero) {
99+
// return ClipRect(
100+
// clipBehavior: clip,
101+
// child: child,
102+
// );
103+
// }
104+
return ClipRRect(
105+
clipBehavior: clip,
106+
borderRadius: borderRadius,
107+
child: child,
108+
);
109+
}
110+
111+
@override
112+
List<Object?> get props => [clip, borderRadius];
113+
}

lib/src/effects/effects.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ export 'translate_effect.dart';
77
export 'skew_effect.dart';
88
export 'transform_effect.dart';
99
export 'blur_effect.dart';
10+
export 'clip_effect.dart';
1011
export 'opacity_effect.dart';

0 commit comments

Comments
 (0)