Committed by
GitHub
Merge pull request #2050 from jonataslaw/4.5.1
Circular reveal
Showing
3 changed files
with
86 additions
and
0 deletions
1 | +import 'dart:math' show sqrt, max; | ||
2 | +import 'dart:ui' show lerpDouble; | ||
3 | + | ||
4 | +import 'package:flutter/material.dart'; | ||
5 | + | ||
6 | +class CircularRevealClipper extends CustomClipper<Path> { | ||
7 | + final double fraction; | ||
8 | + final Alignment? centerAlignment; | ||
9 | + final Offset? centerOffset; | ||
10 | + final double? minRadius; | ||
11 | + final double? maxRadius; | ||
12 | + | ||
13 | + CircularRevealClipper({ | ||
14 | + required this.fraction, | ||
15 | + this.centerAlignment, | ||
16 | + this.centerOffset, | ||
17 | + this.minRadius, | ||
18 | + this.maxRadius, | ||
19 | + }); | ||
20 | + | ||
21 | + @override | ||
22 | + Path getClip(Size size) { | ||
23 | + final Offset center = this.centerAlignment?.alongSize(size) ?? | ||
24 | + this.centerOffset ?? | ||
25 | + Offset(size.width / 2, size.height / 2); | ||
26 | + final minRadius = this.minRadius ?? 0; | ||
27 | + final maxRadius = this.maxRadius ?? calcMaxRadius(size, center); | ||
28 | + | ||
29 | + return Path() | ||
30 | + ..addOval( | ||
31 | + Rect.fromCircle( | ||
32 | + center: center, | ||
33 | + radius: lerpDouble(minRadius, maxRadius, fraction)!, | ||
34 | + ), | ||
35 | + ); | ||
36 | + } | ||
37 | + | ||
38 | + @override | ||
39 | + bool shouldReclip(CustomClipper<Path> oldClipper) => true; | ||
40 | + | ||
41 | + static double calcMaxRadius(Size size, Offset center) { | ||
42 | + final w = max(center.dx, size.width - center.dx); | ||
43 | + final h = max(center.dy, size.height - center.dy); | ||
44 | + return sqrt(w * w + h * h); | ||
45 | + } | ||
46 | +} | ||
47 | + |
@@ -184,3 +184,26 @@ class SizeTransitions { | @@ -184,3 +184,26 @@ class SizeTransitions { | ||
184 | ); | 184 | ); |
185 | } | 185 | } |
186 | } | 186 | } |
187 | + | ||
188 | + | ||
189 | +class CircularRevealTransition { | ||
190 | + Widget buildTransitions( | ||
191 | + BuildContext context, | ||
192 | + Curve? curve, | ||
193 | + Alignment? alignment, | ||
194 | + Animation<double> animation, | ||
195 | + Animation<double> secondaryAnimation, | ||
196 | + Widget child) { | ||
197 | + return ClipPath( | ||
198 | + clipper: CircularRevealClipper( | ||
199 | + fraction: animation.value, | ||
200 | + centerAlignment: Alignment.center, | ||
201 | + centerOffset: Offset.zero, | ||
202 | + minRadius: 0, | ||
203 | + maxRadius: 800, | ||
204 | + ), | ||
205 | + child: child, | ||
206 | + ); | ||
207 | + } | ||
208 | +} | ||
209 | + |
@@ -620,6 +620,22 @@ Cannot read the previousTitle for a route that has not yet been installed''', | @@ -620,6 +620,22 @@ Cannot read the previousTitle for a route that has not yet been installed''', | ||
620 | child: child) | 620 | child: child) |
621 | : child); | 621 | : child); |
622 | 622 | ||
623 | + case Transition.ciruclarReveal: | ||
624 | + return CircularRevealTransition().buildTransitions( | ||
625 | + context, | ||
626 | + route.curve, | ||
627 | + route.alignment, | ||
628 | + animation, | ||
629 | + secondaryAnimation, | ||
630 | + route.popGesture ?? Get.defaultPopGesture | ||
631 | + ? CupertinoBackGestureDetector<T>( | ||
632 | + gestureWidth: route.gestureWidth?.call(context) ?? | ||
633 | + _kBackGestureWidth, | ||
634 | + enabledCallback: () => _isPopGestureEnabled<T>(route), | ||
635 | + onStartPopGesture: () => _startPopGesture<T>(route), | ||
636 | + child: child) | ||
637 | + : child); | ||
638 | + | ||
623 | default: | 639 | default: |
624 | if (Get.customTransition != null) { | 640 | if (Get.customTransition != null) { |
625 | return Get.customTransition!.buildTransition(context, route.curve, | 641 | return Get.customTransition!.buildTransition(context, route.curve, |
-
Please register or login to post a comment