شرح كيفية عمل انميشن للصور في Flutter بدون مكتبات
كما نعلم ان التاثيرات التي يتم وضعها على الصور في تطبيقات flutter تجعل من التطبيق اكثر استخداما لان المستخدم العادي يفضل وجود الانميشن ليس فقط بالصورة بل انميشن بشكل عام في التطبيق الخاص بك وفي هذه المقالة سوف نقوم بشرح لكم درس جديد من تاثيرات الانميشن على الصور في تطبيقات الجوال باستخدام تقنية Flutter كما اننا سوف نساعدكم في تكوين widgets معينه تكون مسؤوله عن الانميشن وتستطيع ارسال لها ال list معينه وتعمل عليها حتى تظهر لك الانميشن بشكل جميل .
لا تحتاج إلى معرفة أي رمز لإنشاء تطبيقات أو برامج ، والتي تُعرف باسم تطوير التطبيقات بدون تعليمات برمجية. لذلك ، بالإضافة إلى بساطة الإنشاء ، توفر هذه الطريقة أيضًا بعض المزايا الأخرى المثيرة للاهتمام ، مثل القدرة على نشر تطبيقك بسرعة أكبر ووقت استجابة أقصر بكثير للترقيات.
يمكن لغير المبرمجين إنشاء تطبيقات ومواقع ويب فعالة بسرعة بفضل تقنيات تطوير التطبيقات بدون تعليمات برمجية. يمكنك إنشاء تطبيقات بدون الحاجة إلى الترميز باستخدام أدوات تطوير التطبيقات التي لا تحتوي على تعليمات برمجية والتي لا تبدو جذابة فحسب ، بل تعمل بكامل طاقتها وقابلة للاستخدام.
How to Animate Image In Flutter
في هذا الجزء سوف يكون عباره عن التصميم الرئيسي والذي من خلاله سوف نقوم بعمل استدعاء للانميشن مع ال list وايضا تحديد مساحة معينه لعرض العناصر واستدعاء TransformPageViewWidget والتي تكون مسؤوله عن تنفيذ الانميشن .
home_page.dart
class HomeScreen extends StatelessWidget {
const HomeScreen({
Key? key,
}) : super(key: key);
@override
Widget build(BuildContext context) {
var mediaQuery = MediaQuery.of(context);
return Scaffold(
body: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Padding(
padding: EdgeInsets.only(
top: mediaQuery.padding.top + kToolbarHeight,
left: mediaQuery.size.width * 0.1,
),
child: const Text(
"Find your\nnext vacation",
style: TextStyle(
letterSpacing: 1.3,
color: Colors.black,
fontWeight: FontWeight.bold,
fontSize: 25,
height: 1.3,
),
),
),
SizedBox(
height: mediaQuery.size.height * 0.75,
width: mediaQuery.size.width,
child: const TransformPageViewWidget(),
),
],
),
);
}
}
تصميم لعمل الانميشن في Flutter واضافة الصور والملحقات
في هذا الجزء والذي يعبر عن ال list التي تظهر مع وجود انميشن للانتقال بين كل عنصر والاخر مع التصميم المراد يمكنك فقط تغيير نوع ال list والعناصر التي بداخلها في هذه الصفحة حتى تحصل على الصورة والاسماء الخاصه بك في عناصرك بدون اي مشاكل تماما .
image.dart
class TransformPageViewWidget extends StatefulWidget {
const TransformPageViewWidget({super.key});
@override
State<TransformPageViewWidget> createState() =>
_TransformPageViewWidgetState();
}
class _TransformPageViewWidgetState extends State<TransformPageViewWidget> {
List<VacationSpots> pageItems = generateSomeData();
PageController? pageController;
var viewportFraction = 0.8;
double? pageOffset = 0;
Size? size;
@override
void initState() {
super.initState();
pageController =
PageController(initialPage: 0, viewportFraction: viewportFraction)
..addListener(
() => setState(
() => pageOffset = pageController!.page,
),
);
}
@override
Widget build(BuildContext context) {
size = MediaQuery.of(context).size;
return PageView.builder(
controller: pageController,
itemCount: pageItems.length,
itemBuilder: (context, index) {
double scale = max(viewportFraction,
1 - (pageOffset! - index).abs() + viewportFraction);
double angleY = (pageOffset! - index).abs();
if (angleY > 0.5) {
angleY = 1 - angleY;
}
return Padding(
padding: EdgeInsets.only(
right: size!.width * 0.04,
left: size!.width * 0.04,
top: 100 - scale * 25,
bottom: size!.width * 0.06,
),
child: Transform(
transform: Matrix4.identity()
..setEntry(3, 2, 0.001)
..rotateY(angleY),
alignment: Alignment.center,
child: Material(
color: Colors.transparent,
elevation: 15,
child: ClipRRect(
borderRadius: const BorderRadius.all(Radius.circular(15)),
child: Stack(
fit: StackFit.expand,
children: [
SizedBox(
width: MediaQuery.of(context).size.width,
child: Image.asset(
pageItems[index].img!,
width: MediaQuery.of(context).size.width,
fit: BoxFit.cover,
),
),
Positioned(
bottom: 0,
left: 0,
right: 0,
child: AnimatedOpacity(
opacity: angleY == 0 ? 1 : 0,
duration: const Duration(milliseconds: 300),
curve: Curves.easeOut,
child: Container(
padding: const EdgeInsets.only(
top: 15, bottom: 30, left: 20, right: 20),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [
Colors.black.withOpacity(0.05),
Colors.black.withOpacity(0.8),
],
),
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
pageItems[index].title!,
style: const TextStyle(
color: Colors.white,
fontSize: 23,
fontWeight: FontWeight.bold,
letterSpacing: 1.2,
),
),
Text(
pageItems[index].caption!,
style: const TextStyle(
color: Colors.white,
fontSize: 15,
),
),
],
),
),
),
),
],
),
),
),
),
);
},
);
}
}
تصميم model للتغير بين الصور والاسماء
الجزء الاخير وهو عباره عن model والذي سوف يكون معبر عن list حتى تظهر جميع العناصر للمستخدم التي ترغب بها مثل الاسم والصورة والنص
.
vacationSpots.dart
class VacationSpots {
String? title, caption, img;
VacationSpots(
this.title,
this.caption,
this.img,
);
}
List<VacationSpots> generateSomeData() {
List<String> titleList = [
"London",
"Düsseldorf",
"Lucerne",
"Malé",
];
List<String> captionList = [
"United Kingdom",
"Germany",
"Switzerland",
"Maldives",
];
List<String> assetName = [
"assets/img/background/onboarding.png",
"assets/img/background/single_post.png",
"assets/img/background/story-content.png",
"assets/img/background/story.png.jpg",
];
List<VacationSpots> list = List.generate(
4,
(index) => VacationSpots(
titleList[index],
captionList[index],
assetName[index],
),
);
return list;
}