Skip to content

Instantly share code, notes, and snippets.

@renancaraujo
Last active August 7, 2024 16:50
Show Gist options
  • Save renancaraujo/4d49d8d7d676c8cdd0d8fdc5f191547e to your computer and use it in GitHub Desktop.
Save renancaraujo/4d49d8d7d676c8cdd0d8fdc5f191547e to your computer and use it in GitHub Desktop.
Aurora borealis card in Flutter using mesh gradients

Aurora Boeralis card that varies size according to mouse position

Screenshot

class ExampleCard extends StatefulWidget {
const ExampleCard({
super.key,
});
@override
State<ExampleCard> createState() => _ExampleCardState();
}
class _ExampleCardState extends State<ExampleCard> {
Offset pointer = Offset.zero;
final frame1 = OMeshRect(
width: 6,
height: 3,
colorSpace: OMeshColorSpace.xyY,
fallbackColor: const Color(0xff090f1a),
backgroundColor: null,
vertices: [
(0.0, 0.0).v,
(0.2, 0.0).v,
(0.4, 0.0).v,
(0.6, 0.0).v,
(0.8, 0.0).v,
(1.0, 0.0).v, // Row 1
(-0.03, 0.38).v,
(0.24, 0.55).v,
(0.42, 0.63).v,
(0.59, 0.57).v,
(0.82, 0.49).v,
(1.03, 0.36).v, // Row 2
(-0.02, 1.06).v,
(0.22, 1.08).v,
(0.43, 1.05).v,
(0.63, 1.02).v,
(0.82, 1.05).v,
(1.02, 1.06).v, // Row 3
],
colors: const [
null,
null,
null,
null,
null,
null, // Row 1
Color(0xff11091a),
Color(0xff11091a),
Color(0xff11091a),
Color(0xff11091a),
Color(0xff11091a),
Color(0xff11091a), // Row 2
Color(0xff475a9f),
Color(0xff6067bb),
Color(0xffb99bfd),
Color(0xffd984ed),
Color(0xffd089e6),
Color(0xfff1d1fd), // Row 3
],
);
final frame2 = OMeshRect(
width: 6,
height: 3,
colorSpace: OMeshColorSpace.xyY,
fallbackColor: Color(0xff090f1a),
backgroundColor: null,
vertices: [
(0.0, 0.0).v,
(0.19, -0.0).v,
(0.4, 0.0).v,
(0.6, 0.0).v,
(0.8, 0.0).v,
(1.0, 0.0).v, // Row 1
(-0.06, 0.43).v,
(0.19, 0.16).v,
(0.44, 0.08).v,
(0.63, 0.11).v,
(0.83, 0.16).v,
(1.03, 0.37).v, // Row 2
(-0.02, 1.06).v,
(0.12, 1.07).v,
(0.44, 1.04).v,
(0.63, 1.03).v,
(0.8, 1.05).v,
(1.02, 1.06).v, // Row 3
],
colors: const [
null,
null,
null,
null,
null,
null, // Row 1
Color(0xff11091a),
Color(0xff11091a),
Color(0xff11091a),
Color(0xff11091a),
Color(0xff11091a),
Color(0xff11091a), // Row 2
Color(0xff475a9f),
Color(0xff6067bb),
Color(0xffb99bfd),
Color(0xffd984ed),
Color(0xffd089e6),
Color(0xfff1d1fd), // Row 3
],
);
@override
Widget build(BuildContext context) {
return Stack(
children: [
OMeshGradient(
// tesselation: 12,
// debugMode: DebugMode.none,
mesh: OMeshRect(
width: 3,
height: 3,
backgroundColor: Colors.black,
vertices: [
(0.0, 0.0).v,
(0.73, -0.01).v.bezier(
south: (0.57, 0.12).v,
),
(1.1, 0.13).v, // Row 1
(0.0, 0.5).v,
(0.5, 0.5).v.bezier(
east: (0.79, 0.56).v,
south: (0.56, 0.85).v,
west: (0.18, 0.64).v,
),
(1.06, 0.76).v.bezier(
west: (0.82, 0.58).v,
), // Row 2
(0.0, 1.0).v,
(0.71, 1.13).v,
(1.0, 1.0).v, // Row 3
],
colors: const [
null,
null,
null, // Row 1
null,
Color(0xff4d2b5d),
null, // Row 2
null,
null,
null, // Row 3
],
),
),
Center(
child: Listener(
onPointerHover: (event) {
setState(() {
pointer = Offset(
event.localPosition.dx / 300,
event.localPosition.dy / 400,
);
});
},
child: DecoratedBox(
decoration: BoxDecoration(
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.5),
blurRadius: 16,
spreadRadius: 8,
),
],
),
child: ClipRRect(
borderRadius: BorderRadius.circular(32),
child: Container(
width: 300,
height: 400,
child: Stack(
children: [
AnimatedOMeshGradient(
duration: const Duration(milliseconds: 50),
curve: Curves.easeInOut,
mesh: OMeshRect.lerp(frame1, frame2, 1-pointer.dy),
),
],
),
),
),
),
),
)
],
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment