This commit is contained in:
='fauz
2025-04-09 16:28:42 +07:00
commit 64e1abb8db
199 changed files with 10265 additions and 0 deletions
+28
View File
@@ -0,0 +1,28 @@
import 'package:flutter/material.dart';
import 'package:furibase/components/navbar_container.dart';
import 'package:furibase/components/navbar_shape_1.dart';
import 'package:furibase/components/navbar_shape_2.dart';
import 'package:furibase/components/navbar_shape_3.dart';
import 'package:furibase/components/custom_shape.dart';
class BottomNavbar extends StatefulWidget {
const BottomNavbar({super.key});
@override
State<BottomNavbar> createState() => _BottomNavbarState();
}
class _BottomNavbarState extends State<BottomNavbar> {
Widget build(BuildContext context) {
final Size screenSize = MediaQuery.of(context).size;
return CustomPaint(
size: Size(screenSize.width, 100.0),
painter:
// BNBCustomPainter1(),
// BNBCustomPainter2(),
BNBCustomPainter3(),
// RPSCustomPainter(),
// MyShape(),
);
}
}
+80
View File
@@ -0,0 +1,80 @@
import 'package:flutter/material.dart';
class BuildcardInfo extends StatelessWidget {
final IconData icon;
final String text;
final double? width; // = 120,
final IconData? extraIcon; //,
final String? extraText; //,
const BuildcardInfo({
super.key,
required this.icon,
required this.text,
required this.width,
this.extraIcon,
this.extraText,
});
@override
Widget build(BuildContext context) {
return Container(
height: 36,
width: width ?? 120,
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 5),
decoration: BoxDecoration(
color: Color.fromARGB(200, 255, 255, 255),
borderRadius: BorderRadius.circular(10),
boxShadow: [
BoxShadow(
// color: Color.fromARGB(255, 214, 213, 121),
blurRadius: 0,
spreadRadius: 0,
),
],
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
IconTheme(
data: IconThemeData(
size: 20,
color: Color.fromARGB(255, 244, 189, 72),
),
child: Icon(icon),
),
SizedBox(width: 4),
Expanded(
child: Text(
text,
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
color: const Color.fromARGB(255, 0, 0, 0),
),
overflow: TextOverflow.ellipsis,
),
),
if (extraIcon != null && extraText != null) ...[
SizedBox(width: 6),
IconTheme(
data: IconThemeData(
size: 18,
color: Color.fromARGB(255, 244, 189, 72),
),
child: Icon(extraIcon),
),
SizedBox(width: 4),
Text(
extraText ?? '',
style: TextStyle(
fontSize: 12,
fontWeight: FontWeight.bold,
color: Color.fromARGB(255, 0, 0, 0),
),
),
],
],
),
);
}
}
+76
View File
@@ -0,0 +1,76 @@
import 'package:flutter/material.dart';
class CardList extends StatelessWidget {
const CardList({super.key});
@override
Widget build(BuildContext context) {
return Card(
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(10.0)),
elevation: 5,
color: const Color.fromARGB(225, 79, 76, 182),
child: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
ClipRRect(
borderRadius: BorderRadius.circular(
10.0,
), // Opsional: membuat gambar lebih rounded
child: Image.asset(
'images/cepott.png', // Ganti dengan path gambar Anda
width: 80, // Atur ukuran gambar
height: 120,
fit: BoxFit.cover,
),
),
const SizedBox(width: 10),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
"Judul Card",
style: const TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 5, width: 10),
Text(
"Deskripsi singkat tentang item ini. karena ini sangat panjang maka ini akan dipotong",
style: const TextStyle(
fontSize: 12,
fontWeight: FontWeight.normal,
),
maxLines: 2,
overflow: TextOverflow.ellipsis,
),
const Spacer(),
Padding(
padding: const EdgeInsets.all(8.0),
child: const Row(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Row(
children: [
Text("50"),
SizedBox(width: 40),
Text("100"),
],
),
Text("Quiz"),
],
),
),
],
),
),
],
),
),
);
}
}
@@ -0,0 +1,145 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
class CollectionContainer extends StatelessWidget {
final String? label;
final String? imagesrc;
final String? imageSvg;
final double? width;
final double? height;
final double? iconw;
final double? iconh;
final VoidCallback onTapAc;
final Color? textColor;
final double? lblSize;
final bool? circle;
const CollectionContainer({
super.key,
this.label,
this.imagesrc,
this.width,
this.height,
required this.onTapAc,
this.textColor,
this.imageSvg,
this.iconh,
this.iconw,
this.lblSize,
this.circle,
});
@override
Widget build(BuildContext context) {
return Container(
width: width ?? 130,
height: height ?? 150,
decoration: BoxDecoration(borderRadius: BorderRadius.circular(10)),
child: GestureDetector(
onTap: onTapAc,
child: Card(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
elevation: 5,
color: const Color.fromARGB(255, 255, 255, 255).withOpacity(0.5),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
ClipRRect(
borderRadius: BorderRadius.circular(12),
child:
imageSvg != null && imageSvg!.isNotEmpty
? Container(
decoration:
(circle ?? false)
? BoxDecoration(
color: const Color.fromARGB(
225,
79,
76,
182,
),
borderRadius: BorderRadius.circular(50),
)
: null,
child: Container(
decoration:
(circle ?? false)
? BoxDecoration(
color: const Color.fromARGB(
225,
79,
76,
182,
),
borderRadius: BorderRadius.circular(50),
shape: BoxShape.circle,
)
: null,
child: Container(
decoration:
(circle ?? false)
? BoxDecoration(
color: const Color.fromARGB(
225,
79,
76,
182,
),
borderRadius: BorderRadius.circular(50),
shape: BoxShape.circle,
)
: null,
child: SvgPicture.asset(
imageSvg!,
width: 20,
height: 20,
colorFilter: const ColorFilter.mode(
Color.fromARGB(255, 118, 3, 3),
BlendMode.srcIn,
),
),
),
),
)
: imagesrc != null && imagesrc!.isNotEmpty
? Image.asset(
imagesrc!,
width: iconw ?? 60,
height: iconh ?? 60,
fit: BoxFit.cover,
)
: const SizedBox(
width: 60,
height: 60,
child: Center(
child: Icon(
Icons.image_not_supported,
color: Colors.white,
),
),
),
),
SizedBox(height: 8),
Positioned(
bottom: 0,
child: Container(
// color: Colors.amber,
child: Text(
label ?? '',
style: TextStyle(
fontSize: lblSize ?? 14,
fontWeight: FontWeight.bold,
color: textColor,
),
),
),
),
],
),
),
),
);
}
}
+124
View File
@@ -0,0 +1,124 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
class CollectionContainer extends StatelessWidget {
final String? label;
final String? imagesrc;
final String? imageSvg;
final double? width;
final double? height;
final VoidCallback onTapAc;
final Color? textColor;
final double? iconw;
final double? iconh;
final double? lblSize;
final bool? circle;
final Color? colorContiner;
const CollectionContainer({
Key? key,
this.label,
this.imagesrc,
this.imageSvg,
this.width,
this.height,
required this.onTapAc,
this.textColor,
this.iconh,
this.iconw,
this.lblSize,
this.circle,
this.colorContiner,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: onTapAc,
child: Container(
// padding: EdgeInsets.only(top: 20),
width: width ?? 130,
height: height ?? 170,
decoration: BoxDecoration(
color: const Color.fromARGB(0, 83, 246, 8),
borderRadius: BorderRadius.circular(10),
),
child: Card(
// shape: RoundedRectangleBorder(
// borderRadius: BorderRadius.circular(10.0),
// ),
elevation: 5,
color: colorContiner ?? Color.fromRGBO(76, 77, 164, 1.0),
child: Stack(
children: [
Padding(
padding: const EdgeInsets.all(8.0),
child: Center(
child: Padding(
padding: const EdgeInsets.only(bottom: 30.0),
child:
imageSvg != null && imageSvg!.isNotEmpty
? Container(
decoration:
(circle ?? false)
? BoxDecoration(
color: const Color.fromARGB(
224,
0,
0,
0,
),
borderRadius: BorderRadius.circular(50),
)
: null,
child: Padding(
padding: const EdgeInsets.all(
8.0,
), // Tambahkan padding di sini
child: SvgPicture.asset(
imageSvg!,
width: iconw ?? 40,
height: iconh ?? 40,
colorFilter: const ColorFilter.mode(
Color.fromARGB(255, 242, 242, 242),
BlendMode.srcIn,
),
),
),
)
: imagesrc != null && imagesrc!.isNotEmpty
? Image.asset(imagesrc!, fit: BoxFit.cover)
: const SizedBox(
// width: 60,
// height: 60,
child: Center(
child: Icon(
Icons.image_not_supported,
color: Colors.white,
),
),
),
),
),
),
Positioned(
bottom: 10,
left: 0,
right: 0,
child: Text(
label ?? '',
textAlign: TextAlign.center,
style: TextStyle(
fontSize: lblSize ?? 14,
fontWeight: FontWeight.bold,
color: textColor ?? Colors.black,
),
),
),
],
),
),
),
);
}
}
+186
View File
@@ -0,0 +1,186 @@
import 'package:flutter/material.dart';
import 'package:furibase/components/navbar_shape_2.dart';
class CustomShape extends StatelessWidget {
const CustomShape({super.key});
@override
Widget build(BuildContext context) {
var screen = MediaQuery.of(context).size;
return Positioned(
child: Container(
width: screen.width,
height: screen.height,
color: const Color.fromARGB(255, 38, 139, 92),
child: CustomPaint(child: CustomPaint(painter: RPSCustomPainter())),
),
);
}
}
class RPSCustomPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
// Layer 1
Paint paint_fill_0 =
Paint()
..color = const Color.fromARGB(255, 189, 18, 18)
..style = PaintingStyle.fill
..strokeWidth = size.width * 0.00
..strokeCap = StrokeCap.butt
..strokeJoin = StrokeJoin.miter;
Path path_0 = Path();
path_0.moveTo(size.width * 0.8040007, size.height * 0.1994400);
path_0.cubicTo(
size.width * 0.3471602,
size.height * 0.1989000,
size.width * 0.3471602,
size.height * 0.1989000,
size.width * 0.1948800,
size.height * 0.1987200,
);
path_0.cubicTo(
size.width * 0.1333300,
size.height * 0.2084400,
size.width * 0.1371800,
size.height * 0.3968400,
size.width * 0.1964501,
size.height * 0.4014400,
);
path_0.cubicTo(
size.width * 0.3483083,
size.height * 0.4004200,
size.width * 0.6520247,
size.height * 0.3983800,
size.width * 0.8038829,
size.height * 0.3973600,
);
path_0.cubicTo(
size.width * 0.8621500,
size.height * 0.3952400,
size.width * 0.8608700,
size.height * 0.2083600,
size.width * 0.8040007,
size.height * 0.1994400,
);
path_0.close();
canvas.drawPath(path_0, paint_fill_0);
// Layer 1
Paint paint_stroke_0 =
Paint()
..color = const Color.fromARGB(255, 33, 150, 243)
..style = PaintingStyle.stroke
..strokeWidth = size.width * 0.00
..strokeCap = StrokeCap.butt
..strokeJoin = StrokeJoin.miter;
canvas.drawPath(path_0, paint_stroke_0);
// Layer 1
Paint paint_fill_1 =
Paint()
..color = const Color.fromARGB(255, 28, 163, 52)
..style = PaintingStyle.fill
..strokeWidth = size.width * 0.00
..strokeCap = StrokeCap.butt
..strokeJoin = StrokeJoin.miter;
Path path_1 = Path();
path_1.moveTo(size.width * 0.4000300, size.height * 0.1987400);
path_1.lineTo(size.width * 0.6010900, size.height * 0.2005400);
path_1.quadraticBezierTo(
size.width * 0.5764200,
size.height * 0.1947400,
size.width * 0.5721900,
size.height * 0.1545000,
);
path_1.cubicTo(
size.width * 0.5500300,
size.height * 0.0020000,
size.width * 0.4492300,
size.height * 0.0042400,
size.width * 0.4271600,
size.height * 0.1487400,
);
path_1.quadraticBezierTo(
size.width * 0.4232300,
size.height * 0.1963200,
size.width * 0.4000300,
size.height * 0.1987400,
);
path_1.close();
canvas.drawPath(path_1, paint_fill_1);
// Layer 1
Paint paint_stroke_1 =
Paint()
..color = const Color.fromARGB(255, 33, 150, 243)
..style = PaintingStyle.stroke
..strokeWidth = size.width * 0.00
..strokeCap = StrokeCap.butt
..strokeJoin = StrokeJoin.miter;
canvas.drawPath(path_1, paint_stroke_1);
// layer 2
// Paint paint_fill_0 =
// Paint()
// ..color = const Color.fromARGB(255, 28, 163, 52)
// ..style = PaintingStyle.fill
// ..strokeWidth = size.width * 0.00
// ..strokeCap = StrokeCap.butt
// ..strokeJoin = StrokeJoin.miter;
// Path path_0 = Path();
path_0.moveTo(size.width * 0.4000300, size.height * 0.1987400);
path_0.lineTo(size.width * 0.6010900, size.height * 0.2005400);
path_0.quadraticBezierTo(
size.width * 0.5764200,
size.height * 0.1947400,
size.width * 0.5721900,
size.height * 0.1545000,
);
path_0.cubicTo(
size.width * 0.5500300,
size.height * 0.0020000,
size.width * 0.4492300,
size.height * 0.0042400,
size.width * 0.4271600,
size.height * 0.1487400,
);
path_0.quadraticBezierTo(
size.width * 0.4232300,
size.height * 0.1963200,
size.width * 0.4000300,
size.height * 0.1987400,
);
path_0.close();
canvas.drawPath(path_0, paint_fill_0);
// Layer 1
// Paint paint_stroke_0 =
// Paint()
// ..color = const Color.fromARGB(255, 33, 150, 243)
// ..style = PaintingStyle.stroke
// ..strokeWidth = size.width * 0.00
// ..strokeCap = StrokeCap.butt
// ..strokeJoin = StrokeJoin.miter;
// canvas.drawPath(path_0, paint_stroke_0);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
return true;
}
}
+72
View File
@@ -0,0 +1,72 @@
import 'package:flutter/material.dart';
import 'package:furibase/components/bottom_navbar.dart';
import 'package:furibase/components/menu_button.dart';
import 'package:furibase/components/scan_button.dart';
import 'package:furibase/screen/Home_screen.dart';
import 'package:furibase/screen/koleksi_screen.dart';
import 'package:furibase/screen/pustaka_screen.dart';
import 'package:furibase/screen/saya/profile_screen.dart';
class MainMenu extends StatelessWidget {
const MainMenu({super.key});
@override
Widget build(BuildContext context) {
final Size size = MediaQuery.of(context).size;
return Container(
color: Colors.transparent,
padding: const EdgeInsets.symmetric(vertical: 10),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
mainAxisSize: MainAxisSize.min,
children: [
MenuButton(
label: "E-furibuddy",
icon: 'icons/furrybuddy.svg',
onPress:
() => {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => HomeScreen()),
),
},
),
MenuButton(
label: "Koleksi",
icon: 'icons/koleksi.svg',
onPress:
() => {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => KoleksiScreen()),
),
},
),
SizedBox(width: 120),
MenuButton(
label: "Pustaka",
icon: 'icons/Pustaka.svg',
onPress:
() => {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => PustakaScreen()),
),
},
),
MenuButton(
label: "Saya",
icon: 'icons/Saya.svg',
onPress:
() => {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => ProfileScreen()),
),
},
),
],
),
);
}
}
+52
View File
@@ -0,0 +1,52 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
class MenuButton extends StatelessWidget {
final String? label;
final String? icon;
final VoidCallback? onPress;
final bool? isSelected;
final double? w;
final double? h;
const MenuButton({
super.key,
this.label,
this.icon,
this.onPress,
this.isSelected,
this.w,
this.h,
});
@override
Widget build(BuildContext context) {
return Expanded(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
IconButton(
icon: SvgPicture.asset(
icon ?? '',
width: w ?? 28,
height: h ?? 28,
// allowDrawingOutsideViewBox: true,
colorFilter: ColorFilter.mode(
Color.fromARGB(255, 255, 255, 255),
BlendMode.srcIn,
),
),
onPressed: onPress,
),
Text(
label ?? '',
style: TextStyle(
color: Color.fromARGB(255, 239, 224, 232),
fontWeight: FontWeight.bold,
),
),
],
),
);
}
}
+113
View File
@@ -0,0 +1,113 @@
import 'package:flutter/material.dart';
import 'package:furibase/components/navbar_shape_2.dart';
class NavbarContainer extends StatelessWidget {
const NavbarContainer({super.key});
@override
Widget build(BuildContext context) {
var screen = MediaQuery.of(context).size;
return Positioned(
child: Container(
width: screen.width,
height: screen.height,
color: const Color.fromARGB(255, 38, 139, 92),
child: CustomPaint(child: CustomPaint(painter: MyShape())),
),
);
}
}
class MyShape extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
// TODO: implement paint
Paint paint =
new Paint()
..color = const Color.fromARGB(255, 166, 12, 66)
..style = PaintingStyle.fill;
Path path = Path();
path.moveTo(20, size.height / 2); // Start at bottom-left
// shape curve kiri
path.quadraticBezierTo(
size.width * 0.04,
size.height * 0.7, // Control point
size.width * 0.09, // almost half
size.height * 0.8, // End point
);
path.lineTo(size.width * 0.92, size.height - 20);
// Curve kanan bawah
path.quadraticBezierTo(
size.width * 0.96,
size.height * 0.7, // Control point
size.width * 0.964,
size.height / 2, // End point (bottom-right)
);
// curve ujung kanan atas
path.quadraticBezierTo(
size.width * 0.95,
size.height * 0.28, // Control point
size.width * 0.91,
size.height * 0.23, // End point (bottom-right)
);
path.lineTo(size.width / 2 + 80, size.height * 0.23);
// ==========
// sebelum curve tengah
path.quadraticBezierTo(
size.width / 2 + 30,
18,
size.width / 2 + 10,
5, // End point (bottom-right)
);
// ==========================================
//==========================================
// curve tengah sebelah kanan
path.quadraticBezierTo(
size.width / 2 - 20,
13,
size.width / 2 + 2,
size.height * 0.030,
);
// sebelah kiri curve
path.quadraticBezierTo(
(size.width / 2) * 0.92,
size.height * 0.189,
size.width / 2 - 40,
18,
);
// ===============================================
// setelah curve tengah
path.quadraticBezierTo(
size.width / 2 - 30,
size.height * 0.188, // Control point
size.width / 2 - 80,
20, // End point (bottom-right)
);
path.lineTo(size.width * 0.1, 20);
path.quadraticBezierTo(
24,
size.height * 0.2, // Control point
20,
size.height / 2, // End point (bottom-right)
);
path.close();
canvas.drawPath(path, paint);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
// TODO: implement shouldRepaint
throw false;
}
}
+159
View File
@@ -0,0 +1,159 @@
import 'dart:ui';
import 'package:flutter/material.dart';
class BNBCustomPainter1 extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
debugPrint("Drawing navbar...");
Paint paint =
new Paint()
..color = const Color.fromARGB(255, 79, 76, 182)
..style = PaintingStyle.fill;
// Path path = Path();
// path.moveTo(0, 10); // Start
// path.quadraticBezierTo(size.width * 0.20, 0, size.width * 0.35, 0);
// path.quadraticBezierTo(size.width * 0.40, 0, size.width * 0.40, 20);
// path.arcToPoint(
// Offset(size.width * 0.60, 20),
// radius: Radius.circular(20.0),
// clockwise: false,
// );
// path.quadraticBezierTo(size.width * 0.60, 0, size.width * 0.63, 0);
// path.quadraticBezierTo(size.width * 0.88, 0, size.width, 10);
// path.lineTo(size.width, size.height);
// path.lineTo(0, size.height);
// path.lineTo(0, 20);
// canvas.drawShadow(path, Colors.black, 5, true);
// canvas.drawPath(path, paint);
// Path path = Path();
// double cornerRadius = 35; // Radius untuk sisi kiri & kanan
// double centerCircleRadius = 40; // Radius untuk lengkungan tengah
// // Mulai dari sisi kiri bawah
// path.moveTo(cornerRadius, size.height);
// // Buat lengkungan di sisi kiri
// path.quadraticBezierTo(0, size.height, 0, size.height - cornerRadius);
// // Tarik garis lurus ke atas sebelum lengkungan tengah
// path.lineTo(0, cornerRadius);
// // Kurva sisi kiri menuju bagian atas
// path.quadraticBezierTo(0, 0, cornerRadius, 0);
// // Garis lurus ke bagian tengah sebelum lekukan
// path.lineTo(size.width / 2 - centerCircleRadius - 20, 0);
// // *** Lengkungan ke atas untuk ikon tengah ***
// path.quadraticBezierTo(
// size.width / 2 - centerCircleRadius,
// -centerCircleRadius,
// size.width / 2,
// -centerCircleRadius,
// );
// path.quadraticBezierTo(
// size.width / 2 + centerCircleRadius,
// -centerCircleRadius,
// size.width / 2 + centerCircleRadius + 20,
// 0,
// );
// // Lanjutkan garis ke kanan
// path.lineTo(size.width - cornerRadius, 0);
// // Kurva sisi kanan
// path.quadraticBezierTo(size.width, 0, size.width, cornerRadius);
// // Tarik garis lurus ke bawah
// path.lineTo(size.width, size.height - cornerRadius);
// // Buat lengkungan di sisi kanan
// path.quadraticBezierTo(
// size.width,
// size.height,
// size.width - cornerRadius,
// size.height,
// );
// // Tarik garis ke kiri hingga kembali ke titik awal
// path.close();
// canvas.drawPath(path, paint);
Path path = Path();
double cornerRadius = 45; // Radius sudut kiri & kanan
double centerCircleRadius = 40; // Meningkatkan puncak 10px dari sebelumnya
// Mulai dari sisi kiri bawah
path.moveTo(cornerRadius, size.height);
// Buat lengkungan di sisi kiri
path.quadraticBezierTo(0, size.height, 0, size.height - cornerRadius);
// Tarik garis lurus ke atas sebelum lengkungan tengah
path.lineTo(0, cornerRadius);
// Kurva sisi kiri menuju bagian atas
path.quadraticBezierTo(0, 0, cornerRadius, 0);
// Garis lurus ke bagian tengah sebelum lekukan
path.lineTo(size.width / 2 - centerCircleRadius - 55, 0);
// *** Transisi menuju puncak gunung lebih smooth ***
path.quadraticBezierTo(
size.width / 2 - centerCircleRadius - 20,
-20,
size.width / 2 - centerCircleRadius,
-35,
);
// *** Puncak lebih tinggi & curve lebih halus ***
path.quadraticBezierTo(
size.width / 2,
-centerCircleRadius - 20,
size.width / 2 + centerCircleRadius,
-35,
);
path.quadraticBezierTo(
size.width / 2 + centerCircleRadius + 20,
-20,
size.width / 2 + centerCircleRadius + 55,
0,
);
// Lanjutkan garis ke kanan
path.lineTo(size.width - cornerRadius, 0);
// Kurva sisi kanan
path.quadraticBezierTo(size.width, 0, size.width, cornerRadius);
// Tarik garis lurus ke bawah
path.lineTo(size.width, size.height - cornerRadius);
// Buat lengkungan di sisi kanan
path.quadraticBezierTo(
size.width,
size.height,
size.width - cornerRadius,
size.height,
);
// Tutup path
path.close();
// Gambar path
canvas.drawPath(path, paint);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return false;
}
}
+93
View File
@@ -0,0 +1,93 @@
import 'dart:ui';
import 'package:flutter/material.dart';
class BNBCustomPainter2 extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
debugPrint("Drawing navbar...");
Paint paint =
new Paint()
..color = const Color.fromARGB(255, 79, 76, 182)
..style = PaintingStyle.fill;
// Path path = Path();
// path.moveTo(0, 10); // Start
// path.quadraticBezierTo(size.width * 0.20, 0, size.width * 0.35, 0);
// path.quadraticBezierTo(size.width * 0.40, 0, size.width * 0.40, 20);
// path.arcToPoint(
// Offset(size.width * 0.60, 20),
// radius: Radius.circular(20.0),
// clockwise: false,
// );
// path.quadraticBezierTo(size.width * 0.60, 0, size.width * 0.63, 0);
// path.quadraticBezierTo(size.width * 0.88, 0, size.width, 10);
// path.lineTo(size.width, size.height);
// path.lineTo(0, size.height);
// path.lineTo(0, 20);
// canvas.drawShadow(path, Colors.black, 5, true);
// canvas.drawPath(path, paint);
Path path = Path();
double cornerRadius = 35; // Radius untuk sisi kiri & kanan
double centerCircleRadius = 40; // Radius untuk lengkungan tengah
// Mulai dari sisi kiri bawah
path.moveTo(cornerRadius, size.height);
// Buat lengkungan di sisi kiri
path.quadraticBezierTo(0, size.height, 0, size.height - cornerRadius);
// Tarik garis lurus ke atas sebelum lengkungan tengah
path.lineTo(0, cornerRadius);
// Kurva sisi kiri menuju bagian atas
path.quadraticBezierTo(0, 0, cornerRadius, 0);
// Garis lurus ke bagian tengah sebelum lekukan
path.lineTo(size.width / 2 - centerCircleRadius - 20, 0);
// *** Lengkungan ke atas untuk ikon tengah ***
path.quadraticBezierTo(
size.width / 2 - centerCircleRadius,
-centerCircleRadius,
size.width / 2,
-centerCircleRadius,
);
path.quadraticBezierTo(
size.width / 2 + centerCircleRadius,
-centerCircleRadius,
size.width / 2 + centerCircleRadius + 20,
0,
);
// Lanjutkan garis ke kanan
path.lineTo(size.width - cornerRadius, 0);
// Kurva sisi kanan
path.quadraticBezierTo(size.width, 0, size.width, cornerRadius);
// Tarik garis lurus ke bawah
path.lineTo(size.width, size.height - cornerRadius);
// Buat lengkungan di sisi kanan
path.quadraticBezierTo(
size.width,
size.height,
size.width - cornerRadius,
size.height,
);
// Tarik garis ke kiri hingga kembali ke titik awal
path.close();
canvas.drawPath(path, paint);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return false;
}
}
+36
View File
@@ -0,0 +1,36 @@
import 'dart:ui';
import 'package:flutter/material.dart';
class BNBCustomPainter3 extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
debugPrint("Drawing navbar...");
Paint paint =
new Paint()
..color = const Color.fromARGB(255, 79, 76, 182)
..style = PaintingStyle.fill;
Path path = Path();
path.moveTo(0, 10); // Start
path.quadraticBezierTo(size.width * 0.20, 0, size.width * 0.35, 0);
path.quadraticBezierTo(size.width * 0.40, 0, size.width * 0.40, 20);
path.arcToPoint(
Offset(size.width * 0.60, 20),
radius: Radius.circular(20.0),
clockwise: false,
);
path.quadraticBezierTo(size.width * 0.60, 0, size.width * 0.63, 0);
path.quadraticBezierTo(size.width * 0.88, 0, size.width, 10);
path.lineTo(size.width, size.height);
path.lineTo(0, size.height);
path.lineTo(0, 20);
canvas.drawShadow(path, Colors.black, 5, true);
canvas.drawPath(path, paint);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return false;
}
}
+32
View File
@@ -0,0 +1,32 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
class ScanButton extends StatelessWidget {
const ScanButton({super.key});
static const Color transparent = Color(0xFFFFFFF);
@override
Widget build(BuildContext context) {
return Expanded(
child: Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
color: const Color.fromARGB(223, 67, 63, 179),
),
padding: EdgeInsets.all(10),
child: IconButton(
icon: SvgPicture.asset(
'icons/Scan.svg',
width: 60,
height: 60,
colorFilter: ColorFilter.mode(
Color.fromARGB(255, 217, 219, 227),
BlendMode.srcIn,
),
),
onPressed: () {},
),
),
);
}
}
+75
View File
@@ -0,0 +1,75 @@
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
class TabMenuButton extends StatelessWidget {
final String? label;
final String? icon;
final VoidCallback onPress;
final bool isSelected;
const TabMenuButton({
super.key,
this.label,
this.icon,
required this.onPress,
this.isSelected = false,
});
@override
Widget build(BuildContext context) {
return Column(
mainAxisSize: MainAxisSize.min,
children: [
if (icon != null && icon!.isNotEmpty)
IconButton(
icon: SvgPicture.asset(
icon!,
width: 28,
height: 28,
colorFilter: ColorFilter.mode(
isSelected
? const Color.fromARGB(255, 106, 24, 207)
: Colors.white,
BlendMode.srcIn,
),
),
onPressed: onPress, // Semua aksi klik hanya lewat satu function
),
GestureDetector(
onTap: onPress, // Menggunakan satu event handler saja
child: Container(
width: 120,
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
decoration: BoxDecoration(
color:
isSelected
? const Color.fromARGB(255, 199, 204, 212).withOpacity(0)
: Colors.transparent,
border:
isSelected
? const Border(
top: BorderSide(color: Colors.white, width: 2),
)
: null,
// borderRadius: BorderRadius.circular(20),
),
child: Center(
child: Text(
label ?? '',
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color:
isSelected
? const Color.fromARGB(255, 255, 255, 255)
: const Color.fromARGB(255, 0, 0, 0),
),
),
),
),
),
],
);
}
}
+25
View File
@@ -0,0 +1,25 @@
import 'package:flutter/material.dart';
class TopbarContainer extends StatefulWidget {
const TopbarContainer({super.key});
@override
State<TopbarContainer> createState() => _TopbarContainerState();
}
class _TopbarContainerState extends State<TopbarContainer> {
Widget build(BuildContext context) {
final Size size = MediaQuery.of(context).size;
return Container(
width: size.width,
height: 120,
decoration: BoxDecoration(
color: const Color.fromRGBO(76, 77, 164, 1.0),
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(25),
bottomRight: Radius.circular(25),
),
),
);
}
}