Skip to content

Instantly share code, notes, and snippets.

@dhruvilp
Last active March 25, 2020 21:45
Show Gist options
  • Save dhruvilp/719b6da9b859abd6c5f50bbd0a104d03 to your computer and use it in GitHub Desktop.
Save dhruvilp/719b6da9b859abd6c5f50bbd0a104d03 to your computer and use it in GitHub Desktop.
Neumorphic / Skeuomorphic Button
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Neumorphic Container',
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Neumorphic Container'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool _isPressed = false;
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.grey[300],
appBar: AppBar(
title: Text(widget.title),
elevation: 0.0,
backgroundColor: Colors.grey[800],
),
body: Center(
child: NeumorphicButton(
enablePressEffect: _isPressed,
onPressed: (){
setState((){
_isPressed = !_isPressed;
});
},
width: 200.0,
height: 100.0,
color: Colors.grey[100],
borderRadius: BorderRadius.circular(10.0),
),
),
);
}
}
class NeumorphicButton extends StatefulWidget {
const NeumorphicButton({Key key, this.color, this.blurOffset, this.bevel, this.enablePressEffect, this.borderRadius, this.width, this.height, this.child, @required this.onPressed, this.onLongPress, this.padding,}) : super(key: key);
final Widget child;
final Color color;
final Offset blurOffset;
final double bevel;
final bool enablePressEffect;
final BorderRadius borderRadius;
final double width;
final double height;
final VoidCallback onPressed;
final VoidCallback onLongPress;
final EdgeInsetsGeometry padding;
@override
_NeumorphicButtonState createState() => _NeumorphicButtonState();
}
class _NeumorphicButtonState extends State<NeumorphicButton> {
@override
Widget build(BuildContext context) {
bool _enablePressEffect = widget.enablePressEffect ?? false;
Offset _blurOffset = widget.blurOffset ?? Offset(5.0/2, 5.0/2);
double _bevel = widget.bevel ?? 7.0;
BorderRadius _borderRadius = widget.borderRadius ?? BorderRadius.circular(_bevel * 10);
Color _color = widget.color ?? Theme.of(context).backgroundColor;
EdgeInsetsGeometry _padding = widget.padding ?? EdgeInsets.all(15.0);
return NeumorphicContainer(
width: widget.width,
height: widget.height,
enablePressEffect: _enablePressEffect,
blurOffset: _blurOffset,
bevel: _bevel,
borderRadius: _borderRadius,
color: _color,
child: InkWell(
onTap: widget.onPressed,
onLongPress: widget.onLongPress,
borderRadius: _borderRadius,
child: Container(
padding: _padding,
child: Center(
widthFactor: 1.0,
heightFactor: 1.0,
child: widget.child,
),
),
),
);
}
}
class NeumorphicContainer extends StatefulWidget {
const NeumorphicContainer({
Key key,
this.child,
this.color,
this.blurOffset,
this.bevel,
this.enablePressEffect,
this.borderRadius,
this.width,
this.height,
}) : super(key: key);
final Widget child;
final Color color;
final Offset blurOffset;
final double bevel;
final bool enablePressEffect;
final BorderRadius borderRadius;
final double width;
final double height;
@override
_NeumorphicContainerState createState() => _NeumorphicContainerState();
}
class _NeumorphicContainerState extends State<NeumorphicContainer> {
@override
Widget build(BuildContext context) {
bool _enablePressEffect = widget.enablePressEffect ?? false;
Offset _blurOffset = widget.blurOffset ?? Offset(5.0/2, 5.0/2);
double _bevel = widget.bevel ?? 5.0;
BorderRadius _borderRadius = widget.borderRadius ?? BorderRadius.circular(_bevel * 10);
Color _color = widget.color ?? Theme.of(context).backgroundColor;
return Container(
width: widget.width,
height: widget.height,
child: widget.child,
decoration: BoxDecoration(
borderRadius: _borderRadius,
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
_enablePressEffect ? _color : _color.mix(Colors.black, .1),
_enablePressEffect ? _color.mix(Colors.black, .05) : _color,
_enablePressEffect ? _color.mix(Colors.black, .05) : _color,
_color.mix(Colors.white, _enablePressEffect ? .1 : .5),
],
stops: [
0.0,
.3,
.6,
1.0,
],
),
boxShadow: _enablePressEffect
? [
BoxShadow(
blurRadius: _bevel / 2,
offset: _blurOffset,
color: _color.mix(Colors.white, .6),
),
BoxShadow(
blurRadius: _bevel / 2,
offset: -_blurOffset,
color: _color.mix(Colors.black, .3),
),
]
: [
BoxShadow(
blurRadius: _bevel / 2,
offset: -_blurOffset,
color: _color.mix(Colors.white, .6),
),
BoxShadow(
blurRadius: _bevel / 2,
offset: _blurOffset,
color: _color.mix(Colors.black, .3),
)
],
),
);
}
}
extension ColorUtils on Color {
Color mix(Color another, double amount) {
return Color.lerp(this, another, amount);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment