Skip to content

Instantly share code, notes, and snippets.

@roipeker
Created December 10, 2020 02:33
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save roipeker/096f6daf782fa744e720cd83b73aae76 to your computer and use it in GitHub Desktop.
Save roipeker/096f6daf782fa744e720cd83b73aae76 to your computer and use it in GitHub Desktop.
GlassBox - Flutter Widget: Glassmorphism style .
/// roipeker 2020.
import 'dart:ui';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
/// Usage:
/// ```
/// GlassBox(
/// width: 140,
/// height: 120,
/// shadow: BoxShadow(
/// color: Colors.black26,
/// blurRadius: 12,
/// offset: Offset(0, 14),
/// ),
/// blurRadius: 8,
/// backgroundColor: Colors.white.withOpacity(.2),
/// cornerRadius: 10,
/// child: Center(
/// child: Text(
/// "Hello!",
/// style: TextStyle(
/// fontWeight: FontWeight.bold,
/// fontSize: 24,
/// color: Colors.white,
/// ),
/// ),
/// ),
///),
/// ```
class GlassBox extends StatelessWidget {
final double blurRadius, cornerRadius, width, height;
final Border outline;
final BoxShadow shadow;
final Color backgroundColor;
final Widget child;
const GlassBox({
Key key,
this.width = 100,
this.height = 100,
this.blurRadius = 4.0,
this.cornerRadius = 10,
this.child,
this.outline,
this.shadow,
this.backgroundColor = const Color(0x44ffffff),
}) : super(key: key);
@override
Widget build(BuildContext context) {
final double blurSigma = blurRadius * 0.57735 + 0.5;
final borderRadius = BorderRadius.circular(cornerRadius);
return Container(
width: width ?? 100,
height: height ?? 100,
child: Stack(
clipBehavior: Clip.none,
children: [
ClipPath(
clipper: _InvRRectClipper(cornerRadius),
child: Container(
decoration: BoxDecoration(
borderRadius: borderRadius,
boxShadow: [
if (shadow != null) shadow,
],
),
),
),
Container(
decoration: BoxDecoration(borderRadius: borderRadius),
clipBehavior: Clip.antiAlias,
child: BackdropFilter(
filter: ImageFilter.blur(sigmaX: blurSigma, sigmaY: blurSigma),
child: Container(color: const Color(0x0), child: child),
),
),
Container(
foregroundDecoration:
BoxDecoration(border: outline, borderRadius: borderRadius),
decoration: BoxDecoration(
color: backgroundColor,
borderRadius: borderRadius,
),
),
],
),
);
}
}
class _InvRRectClipper extends CustomClipper<Path> {
final double radius;
_InvRRectClipper([this.radius = 12]);
@override
Path getClip(Size size) {
final p = Path()
..addRRect(RRect.fromLTRBR(
0,
0,
size.width,
size.height,
Radius.circular(radius),
))
..addRect(Rect.largest)
..fillType = PathFillType.evenOdd;
return p;
}
@override
bool shouldReclip(covariant CustomClipper<Path> oldClipper) => true;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment