Free copy-paste Button 004 for Flutter: a ready-to-use button widget with full Dart source code and a live preview. Works on desktop. No external packages.
Copy the Dart code below into a new file in your Flutter project (for example lib/widgets/button_004.dart) and use the widget anywhere in your widget tree.
import 'package:flutter/material.dart';
class Button004 extends StatefulWidget {
const Button004({
super.key,
this.icon = Icons.camera_alt,
this.tooltip = 'Action',
this.onPressed,
this.size = 52.0,
});
final IconData icon;
final String tooltip;
final VoidCallback? onPressed;
final double size;
@override
State<Button004> createState() => _Button004State();
}
class _Button004State extends State<Button004> {
bool _isHovered = false;
bool _isPressed = false;
@override
Widget build(BuildContext context) {
final Color buttonColor = _isPressed
? const Color(0xFFD44600)
: _isHovered
? const Color(0xFFFF6F1F)
: const Color(0xFFFF5700);
return MouseRegion(
cursor: SystemMouseCursors.click,
onEnter: (_) => setState(() => _isHovered = true),
onExit: (_) => setState(() {
_isHovered = false;
_isPressed = false;
}),
child: Stack(
clipBehavior: Clip.none,
alignment: Alignment.topCenter,
children: [
GestureDetector(
onTapDown: (_) => setState(() => _isPressed = true),
onTapUp: (_) {
setState(() => _isPressed = false);
widget.onPressed?.call();
},
onTapCancel: () {
if (_isPressed) setState(() => _isPressed = false);
},
child: AnimatedScale(
scale: _isPressed ? 0.95 : (_isHovered ? 1.06 : 1.0),
duration: const Duration(milliseconds: 140),
curve: Curves.easeOutCubic,
child: AnimatedContainer(
duration: const Duration(milliseconds: 140),
curve: Curves.easeOutCubic,
width: widget.size,
height: widget.size,
decoration: BoxDecoration(
color: buttonColor,
borderRadius: BorderRadius.circular(8),
),
child: Center(
child: AnimatedScale(
scale: _isHovered ? 1.10 : 1.0,
duration: const Duration(milliseconds: 140),
curve: Curves.easeOutCubic,
child: AnimatedRotation(
turns: _isHovered ? -0.04 : 0.0,
duration: const Duration(milliseconds: 180),
curve: Curves.easeOutBack,
child: Icon(
widget.icon,
size: widget.size * 0.46,
color: Colors.white,
),
),
),
),
),
),
),
Positioned(
top: widget.size,
child: IgnorePointer(
ignoring: !_isHovered,
child: AnimatedOpacity(
opacity: _isHovered ? 1.0 : 0.0,
duration: const Duration(milliseconds: 140),
curve: Curves.easeOutCubic,
child: Container(
padding: const EdgeInsets.symmetric(
horizontal: 10,
vertical: 5,
),
decoration: BoxDecoration(
color: const Color(0xFFCC4400),
borderRadius: BorderRadius.circular(5),
),
child: Text(
widget.tooltip,
style: const TextStyle(
fontSize: 11,
fontWeight: FontWeight.w600,
color: Colors.white,
letterSpacing: 0.3,
),
),
),
),
),
),
],
),
);
}
}