Jonny Borges
Committed by GitHub

Merge pull request #2050 from jonataslaw/4.5.1

Circular reveal
  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,