Add base interactive layout "rive" whit animation

This commit is contained in:
paoloGuagnano
2024-03-08 12:15:47 +01:00
parent 06336bd3d9
commit 2d5fba8897
58 changed files with 1946 additions and 133 deletions

View File

@@ -0,0 +1,25 @@
import 'package:flutter/material.dart';
class AnimatedBar extends StatelessWidget {
const AnimatedBar({
Key? key,
required this.isActive,
}) : super(key: key);
final bool isActive;
@override
Widget build(BuildContext context) {
return AnimatedContainer(
margin: const EdgeInsets.only(bottom: 2),
duration: const Duration(milliseconds: 200),
height: 4,
width: isActive ? 20 : 0,
decoration: const BoxDecoration(
color: Color(0xFF81B4FF),
borderRadius: BorderRadius.all(
Radius.circular(12),
)),
);
}
}

View File

@@ -0,0 +1,44 @@
import 'package:flutter/material.dart';
import 'package:rive/rive.dart';
import '../../../model/menu.dart';
import 'animated_bar.dart';
class BtmNavItem extends StatelessWidget {
const BtmNavItem(
{super.key,
required this.navBar,
required this.press,
required this.riveOnInit,
required this.selectedNav});
final Menu navBar;
final VoidCallback press;
final ValueChanged<Artboard> riveOnInit;
final Menu selectedNav;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: press,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
AnimatedBar(isActive: selectedNav == navBar),
SizedBox(
height: 36,
width: 36,
child: Opacity(
opacity: selectedNav == navBar ? 1 : 0.5,
child: RiveAnimation.asset(
navBar.rive.src,
artboard: navBar.rive.artboard,
onInit: riveOnInit,
),
),
),
],
),
);
}
}

View File

@@ -0,0 +1,33 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class InfoCard extends StatelessWidget {
const InfoCard({
Key? key,
required this.name,
required this.bio,
}) : super(key: key);
final String name, bio;
@override
Widget build(BuildContext context) {
return ListTile(
leading: const CircleAvatar(
backgroundColor: Colors.white24,
child: Icon(
CupertinoIcons.person,
color: Colors.white,
),
),
title: Text(
name,
style: const TextStyle(color: Colors.white),
),
subtitle: Text(
bio,
style: const TextStyle(color: Colors.white70),
),
);
}
}

View File

@@ -0,0 +1,38 @@
import 'package:flutter/material.dart';
import 'package:rive/rive.dart';
class MenuBtn extends StatelessWidget {
const MenuBtn({super.key, required this.press, required this.riveOnInit});
final VoidCallback press;
final ValueChanged<Artboard> riveOnInit;
@override
Widget build(BuildContext context) {
return SafeArea(
child: GestureDetector(
onTap: press,
child: Container(
margin: const EdgeInsets.only(left: 12),
height: 40,
width: 40,
decoration: const BoxDecoration(
color: Colors.white,
shape: BoxShape.circle,
boxShadow: [
BoxShadow(
color: Colors.black12,
offset: Offset(0, 3),
blurRadius: 8,
),
],
),
child: RiveAnimation.asset(
"assets/RiveAssets/menu_button.riv",
onInit: riveOnInit,
),
),
),
);
}
}

View File

@@ -0,0 +1,96 @@
import 'package:flutter/material.dart';
import '../../../model/menu.dart';
import '../../../utils/rive_utils.dart';
import 'info_card.dart';
import 'side_menu.dart';
class SideBar extends StatefulWidget {
const SideBar({super.key});
@override
State<SideBar> createState() => _SideBarState();
}
class _SideBarState extends State<SideBar> {
Menu selectedSideMenu = sidebarMenus.first;
@override
Widget build(BuildContext context) {
return SafeArea(
child: Container(
width: 288,
height: double.infinity,
decoration: const BoxDecoration(
color: Color(0xFF17203A),
borderRadius: BorderRadius.all(
Radius.circular(30),
),
),
child: DefaultTextStyle(
style: const TextStyle(color: Colors.white),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const InfoCard(
name: "Abu Anwar",
bio: "YouTuber",
),
Padding(
padding: const EdgeInsets.only(left: 24, top: 32, bottom: 16),
child: Text(
"Browse".toUpperCase(),
style: Theme.of(context)
.textTheme
.titleMedium!
.copyWith(color: Colors.white70),
),
),
...sidebarMenus
.map((menu) => SideMenu(
menu: menu,
selectedMenu: selectedSideMenu,
press: () {
RiveUtils.chnageSMIBoolState(menu.rive.status!);
setState(() {
selectedSideMenu = menu;
});
},
riveOnInit: (artboard) {
menu.rive.status = RiveUtils.getRiveInput(artboard,
stateMachineName: menu.rive.stateMachineName);
},
))
.toList(),
Padding(
padding: const EdgeInsets.only(left: 24, top: 40, bottom: 16),
child: Text(
"History".toUpperCase(),
style: Theme.of(context)
.textTheme
.titleMedium!
.copyWith(color: Colors.white70),
),
),
...sidebarMenus2
.map((menu) => SideMenu(
menu: menu,
selectedMenu: selectedSideMenu,
press: () {
RiveUtils.chnageSMIBoolState(menu.rive.status!);
setState(() {
selectedSideMenu = menu;
});
},
riveOnInit: (artboard) {
menu.rive.status = RiveUtils.getRiveInput(artboard,
stateMachineName: menu.rive.stateMachineName);
},
))
.toList(),
],
),
),
),
);
}
}

View File

@@ -0,0 +1,63 @@
import 'package:flutter/material.dart';
import 'package:rive/rive.dart';
import '../../../model/menu.dart';
class SideMenu extends StatelessWidget {
const SideMenu(
{super.key,
required this.menu,
required this.press,
required this.riveOnInit,
required this.selectedMenu});
final Menu menu;
final VoidCallback press;
final ValueChanged<Artboard> riveOnInit;
final Menu selectedMenu;
@override
Widget build(BuildContext context) {
return Column(
children: [
const Padding(
padding: EdgeInsets.only(left: 24),
child: Divider(color: Colors.white24, height: 1),
),
Stack(
children: [
AnimatedPositioned(
duration: const Duration(milliseconds: 300),
curve: Curves.fastOutSlowIn,
width: selectedMenu == menu ? 288 : 0,
height: 56,
left: 0,
child: Container(
decoration: const BoxDecoration(
color: Color(0xFF6792FF),
borderRadius: BorderRadius.all(Radius.circular(10)),
),
),
),
ListTile(
onTap: press,
leading: SizedBox(
height: 36,
width: 36,
child: RiveAnimation.asset(
menu.rive.src,
artboard: menu.rive.artboard,
onInit: riveOnInit,
),
),
title: Text(
menu.title,
style: const TextStyle(color: Colors.white),
),
),
],
),
],
);
}
}