Aurora Boeralis card that varies size according to mouse position
Last active
August 7, 2024 16:50
-
-
Save renancaraujo/4d49d8d7d676c8cdd0d8fdc5f191547e to your computer and use it in GitHub Desktop.
Aurora borealis card in Flutter using mesh gradients
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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