Stagger Animation
Stagger Animation یکی از قابلیت های بسیار زیبا و کاربردی فلاتر است . توسط Stagger Animation شما قادر خواهید بود انیمیشن های ترکیبی و زیبایی را خلق نمایید . در واقع Stagger Animation به شما این امکان را می دهد که تعدادی انیمیشن را در یک دسته قرار داده و به ترتیب اجرا نمایید .
Stagger Animation در واقع یک تکنیک است . تکنیکی که به شما این امکان را می دهد با یکبار صدور فرمان شروع انیمیشن ، بتوانید تعداد زیادی انیمیشن را به ترتیب ، اجرا نمایید . ترتیب اجرای انیمیشن ها مقیاسی بین عدد ۰ تا ۱ است به طوری که این بازه عددی به ۱۰۰۰ قسمت تقسیم شده است و شما می توانید تعیین کنید هر انیمیشن شما چه سهمی از این ۱۰۰۰ قسمت را داشته باشد . در ادامه وقتی مدت اجرای انیمیشن را در خصوصیت duration کنترلر تعریف کردید ، کامپایلر به صورت خودکار مقیاس تعیین شده بین ۰ و ۱ را به مدت اجرای انیمیشن تبدیل و انیمیشن را بر اساس آن اجرا می نماید .
قطعه کد زیر نمونه از پیاده سازی Stagger Animation به نمایش گذاشته است :
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
debugShowCheckedModeBanner: false,
home: StaggerAnimationDemo(),
));
}
class StaggerAnimationDemo extends StatefulWidget {
@override
_StaggerAnimationDemoState createState() => _StaggerAnimationDemoState();
}
class _StaggerAnimationDemoState extends State<StaggerAnimationDemo>
with SingleTickerProviderStateMixin {
AnimationController controller; // گام اول : تعریف یک کنترلر
@override
void initState() {
// TODO: implement initState
super.initState();
// گام دوم : مقداردهی به کنترلر
controller = new AnimationController(
vsync: this, duration: Duration(milliseconds: 2000));
}
@override
void dispose() {
// جهت بهینه شدن استفاده از حافظه
controller.dispose(); // توقف انیمیشن در صورت خروج از این اسکرین
super.dispose();
}
// گام سوم : فراخوانی تابع اجرای انیمیشن
_playAnimation() async {
try {
await controller.forward();
await controller.reverse();
} on TickerCanceled {}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Stagger Animation'),
centerTitle: true,
),
body: GestureDetector(
onTap: () {
_playAnimation(); // فراخوانی اجرای انیمیشن
},
child: Center(
child: Container(
width: 300,
height: 400,
decoration: BoxDecoration(
color: Colors.black.withOpacity(0.1),
border: Border.all(
color: Colors.black.withOpacity(0.5),
),
borderRadius: BorderRadius.all(Radius.circular(15)),
),
child: StaggerAnimation(
// چون مایل نیستم تابع من روی کنترلر تغییر ایجاد کند فقط ویویی از کنترلر را به آن ارسال می کنم
controller: controller.view),
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
_playAnimation(); // فراخوانی اجرای انیمیشن
},
child: Icon(Icons.play_arrow),
),
bottomNavigationBar: BottomAppBar(
color: Theme.of(context).primaryColor,
shape: CircularNotchedRectangle(),
notchMargin: 8,
child: Container(
height: 55,
),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
);
}
}
class StaggerAnimation extends StatelessWidget {
final Animation<double> controller; // انیمیشن اصلی دریافت کننده کنترلر
final Animation<double> opacity; // انیمیشن کنترل کننده میزان شفافیت
final Animation<double> width; // انیمیشن کنترل کننده عرض ویجت
final Animation<double> height; // انیمیشن کنترل کننده ارتفاع ویجت
final Animation<EdgeInsets> padding; // انیمیشن کنترل کننده فاصله از داخل
final Animation<BorderRadius> borderRadius; // انیمیشن کنترل کننده گردی گوشه های حاشیه
final Animation<Color> color; // انیمیشن کنترل کننده رنگ ویجت
StaggerAnimation({@required this.controller}) // سازنده کلاس
: // مقداردهی اولیه به سایر انیمیشن ها
opacity = Tween<double>(begin: 0.0, end: 1.0).animate(new CurvedAnimation(
// اتصال این انیمیشن با انیمیشن اصلی که حاوی کنترلر هست توسط خصوصیت Parent
parent: controller,
curve: new Interval(0.0, 0.150, curve: Curves.ease))),
width = Tween<double>(begin: 50.0, end: 200.0).animate(new CurvedAnimation(
parent: controller,
curve: new Interval(0.150, 0.350, curve: Curves.ease))),
height = Tween<double>(begin: 50.0, end: 200.0).animate(new CurvedAnimation(
parent: controller,
curve: new Interval(0.350, 0.500, curve: Curves.ease))),
padding = EdgeInsetsTween(
begin: const EdgeInsets.only(bottom: 16),
end: const EdgeInsets.only(bottom: 150))
.animate(new CurvedAnimation(
parent: controller,
curve: new Interval(0.350, 0.500, curve: Curves.ease))),
borderRadius = BorderRadiusTween(
begin: BorderRadius.circular(5), end: BorderRadius.circular(100))
.animate(new CurvedAnimation(
parent: controller,
curve: new Interval(0.500, 0.700, curve: Curves.ease))),
color = ColorTween(begin: Colors.indigo[100], end: Colors.orange[400])
.animate(new CurvedAnimation(
parent: controller,
curve: new Interval(0.700, 0.999, curve: Curves.ease)));
// تابع سازنده ویجت
@override
Widget build(BuildContext context) {
// ایجاد انیمیشن بیلدر
return AnimatedBuilder(
animation: controller, // تعیین کنترلر
builder: buildAnimation, // تعیین ویجت مورد نظر جهت اجرای انیمیشن
);
}
// ایجاد ویجتی که توسط انیمیشن بیلدر کنترل خواهد شد
Widget buildAnimation(BuildContext context, Widget child){
return Container(
padding: padding.value,
alignment: Alignment.bottomCenter,
child: Opacity(
opacity: opacity.value,
child: Container(
width: width.value,
height: height.value,
decoration: BoxDecoration(
color: color.value,
border: Border.all(color: Colors.indigo[300], width: 3),
borderRadius: borderRadius.value),
),
),
);
}
}
خروجی کد فوق در تصویر زیر قابل مشاهده است :
ممکن است در ابتدا درک کدهای این انیمیشن قدری سخت باشد ولی مطمئنا با قدری تمرکز و تمرین مسئله به سرعت ساده و قابل مفهم می گردد . در مثال بالا شما فقط کافیست روش تعریف ویجت مربوط به انیمیشن و روش مقداردهی به انیمیشن ها بر اساس کنترلر را متوجه شوید تا مسئله به سمت ساده شدن برود .
قطعه کد زیر (خط ۱۰۷ کد فوق ) نمونه ی ساده شده ای از روش مقدار دهی به یک انیمیشن را نشان می دهد :
width = Tween<double>(
begin: 50.0, // نقطه شروع انیمیشن
end: 200.0 // نقطه پایان انیمیشن
).animate(
new CurvedAnimation(
parent: controller, // اتصال این انیمیشن به کنترلر
curve: new Interval(
۰٫۱۵۰, // لحظه شروع انیمیشن
۰٫۳۵۰, // لحظه پایان انیمیشن
curve: Curves.ease // روش اجرای انیمیشن
)
)
),
در کد فوق یک انیمیشن قرار است مقدار عرض یک ویجت را تغییر دهد . برای این منظور توسط Tween (به معنی : بین) اعلام شده که از begin:50 تا end:200 یعنی از عرض ۵۰ تا عرض ۲۰۰ انیمیشن تغییر ایجاد نماید . همچنین منحنی اجرای انیمیشن (CurvedAnimation) در خصوصیت animate تعیین شده است و به این روش به انیمیشن گفته ایم در فاصله زمانی ۰٫۱۵۰ تا ۰٫۳۵۰ ( یعنی ۲۰۰ سهم از ۱۰۰۰ سهم ) اجرا شود و روش اجرای انیمیشن نیز Curves.ease باشد . در این مثال انیمیشن ما دومین انیمیشنی است که اجرا خواهد شد ، چرا که از لحظه ۰٫۱۵۰ شروع شده است و قبل از این لحظه ، فقط یک انیمیشن وجود دارد .
جهت کسب اطلاعات بیشتر از این آدرس به سایت اصلی فلاتر مراجعه نمایید .
امیدوارم این مطلب برای شما مفید باشد .