Free copy-paste Card 007 for Flutter: a ready-to-use card 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/card_007.dart) and use the widget anywhere in your widget tree.
import 'dart:math' as math;
import 'package:flutter/material.dart';
class Card007 extends StatefulWidget {
const Card007({
super.key,
this.primaryText = 'Hello',
this.secondaryText = 'World',
this.title = 'CopyFlutter',
this.subtitle = 'CopyFlutter.com',
this.cardColor = const Color(0xFF243137),
this.goldColor = const Color(0xFFBD9F67),
this.duration = const Duration(milliseconds: 1000),
this.onTap,
});
final String primaryText, secondaryText, title, subtitle;
final Color cardColor, goldColor;
final Duration duration;
final VoidCallback? onTap;
@override
State<Card007> createState() => _Card007State();
}
class _Card007State extends State<Card007>
with SingleTickerProviderStateMixin {
late final AnimationController _controller;
late final Animation<double> _anim;
@override
void initState() {
super.initState();
_controller = AnimationController(vsync: this, duration: widget.duration);
_anim = CurvedAnimation(parent: _controller, curve: Curves.easeInOut);
}
@override
void didUpdateWidget(covariant Card007 oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.duration != widget.duration) {
_controller.duration = widget.duration;
}
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
void _setHover(bool hover) =>
hover ? _controller.forward() : _controller.reverse();
@override
Widget build(BuildContext context) {
return MouseRegion(
opaque: true,
cursor: SystemMouseCursors.click,
onEnter: (_) => _setHover(true),
onExit: (_) => _setHover(false),
child: GestureDetector(
behavior: HitTestBehavior.opaque,
onTap: widget.onTap,
child: AnimatedBuilder(
animation: _anim,
builder: (context, _) {
final t = _anim.value;
final scale = 1.0 + 0.08 * t;
final radius = (1.0 - t) * 10.0;
final borderInset = t * 14.0;
final borderRot = (1.0 - t) * (10.0 * math.pi / 180.0);
return Transform.scale(
scale: scale,
child: Container(
width: 300,
height: 200,
decoration: BoxDecoration(
color: widget.cardColor,
borderRadius: BorderRadius.circular(radius),
boxShadow: [
BoxShadow(
color: Colors.black.withValues(alpha: 0.3 + 0.2 * t),
blurRadius: 16 + 10 * t,
offset: Offset(0, 8 + 4 * t),
),
],
),
clipBehavior: Clip.antiAlias,
child: Stack(
alignment: Alignment.center,
children: [
if (t > 0.01)
Positioned(
left: borderInset,
right: borderInset,
top: borderInset,
bottom: borderInset,
child: Transform.rotate(
angle: borderRot,
child: Opacity(
opacity: t.clamp(0.0, 1.0),
child: DecoratedBox(
decoration: BoxDecoration(
border: Border.all(
color: widget.goldColor,
width: 2,
),
),
),
),
),
),
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
height: 35,
child: Center(
child: Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Text(
widget.primaryText,
style: TextStyle(
color: widget.goldColor,
fontSize: 26,
fontWeight: FontWeight.w900,
letterSpacing: 1.5,
),
),
if (widget.secondaryText.isNotEmpty)
ClipRect(
child: Align(
alignment: Alignment.centerLeft,
widthFactor: t,
child: Opacity(
opacity: t.clamp(0.0, 1.0),
child: Padding(
padding: const EdgeInsets.only(
left: 4,
),
child: Text(
widget.secondaryText,
style: TextStyle(
color: widget.goldColor,
fontSize: 22,
fontWeight: FontWeight.w400,
letterSpacing: 2,
),
),
),
),
),
),
],
),
),
),
const SizedBox(height: 10),
Opacity(
opacity: t.clamp(0.0, 1.0),
child: Text(
widget.title,
style: TextStyle(
color: widget.goldColor,
fontSize: 11,
fontWeight: FontWeight.w500,
letterSpacing: 2.0 + 7.5 * t,
),
),
),
],
),
Positioned(
bottom: 14,
child: Opacity(
opacity: t.clamp(0.0, 1.0),
child: Text(
widget.subtitle.toUpperCase(),
style: TextStyle(
color: widget.goldColor,
fontSize: 7,
fontWeight: FontWeight.w700,
letterSpacing: 1.0 + 2.0 * t,
),
),
),
),
],
),
),
);
},
),
),
);
}
}