hero Animationhero Animation

في عالم تطوير التطبيقات الجوالة، أصبحت الرسوم المتحركة عنصرًا أساسيًا لتحسين تجربة المستخدم وجعل التطبيق أكثر جاذبية. مع إطار عمل Flutter، تبرز ميزة Hero Animations كأداة قوية لإنشاء انتقالات سلسة بين الشاشات، حيث يبدو العنصر وكأنه “يطير” من شاشة إلى أخرى. في هذا المقال، سنستعرض كل ما يتعلق بـ Hero Animations، من المفاهيم الأساسية إلى التنفيذ العملي، مع أمثلة كود ونصائح لتحقيق أفضل النتائج. إذا كنت مطور Flutter، هذا الدليل سيساعدك على إضافة لمسة احترافية إلى تطبيقاتك.

ما هي Hero Animations في Flutter؟

تُعد Hero Animations طريقة شائعة لإنشاء انتقال سلس بين الشاشات، مثل طيران صورة من شاشة إلى أخرى. تُستخدم هذه الرسوم المتحركة غالبًا لعرض تفاصيل عنصر معين، مثل عرض صورة مصغرة في قائمة ثم الانتقال بها إلى شاشة تفاصيل. تُعرف هذه الحركة أيضًا بـ “الانتقال بالعنصر المشترك”، ويمكن تنفيذها باستخدام واجهة Hero. هذه الميزة تجعل التطبيق يبدو أكثر تماسكًا وسلاسة، مما يعزز تجربة المستخدم بشكل كبير.

أنواع الرسوم المتحركة Hero

  • الرسوم المتحركة القياسية: انتقال العنصر مع تغيير الموقع والحجم.
  • الرسوم المتحركة الشعاعية (Radial): تغيير شكل العنصر أثناء الطيران، مثل الانتقال من دائرة إلى مربع.

العناصر المشتركة مثل الصورة تظهر في كلا الشاشتين، مما يخلق تجربة سلسة للمستخدم.

كيف تعمل Hero Animations؟

تعمل Hero Animations من خلال واجهتي Hero: واحدة في الشاشة الأصلية (المصدر) وأخرى في الشاشة الوجهة. يتم تعيين علامة (Tag) متطابقة لكلا الواجهتين لربطهما معًا. عند دفع الشاشة الوجهة باستخدام Navigator، يقوم Flutter بحساب الانتقال (Tween) لتحريك العنصر من موقعه وحجمه الأصليين إلى موقعه وحجمه الجديدين. يتم تنفيذ الرسوم المتحركة في طبقة Overlay، حيث يظهر العنصر في الأعلى أثناء الطيران، ثم ينتقل إلى الشاشة الوجهة عند اكتمال الحركة.

خطوات تنفيذ Hero Animations في Flutter

لتنفيذ Hero Animations، اتبع هذه الخطوات البسيطة:

  1. تعريف Hero في الشاشة الأصلية (المصدر): استخدم واجهة Hero مع علامة (Tag) تمثل البيانات الأساسية (مثل اسم الصورة). حدد التمثيل البصري (مثل صورة باستخدام Image).
  2. تعريف Hero في الشاشة الوجهة: أنشئ واجهة Hero أخرى بنفس العلامة (Tag) لضمان الارتباط. تأكد من أن شجرة الواجهات متطابقة تقريبًا للحصول على نتائج أفضل.
  3. إنشاء الشاشة الوجهة: استخدم Navigator لدفع الشاشة الوجهة باستخدام MaterialPageRoute أو طريقة مشابهة.
  4. تشغيل الرسوم المتحركة: عند دفع الشاشة الوجهة، يقوم Flutter تلقائيًا بتشغيل الرسوم المتحركة للعنصر Hero بناءً على العلامات المطابقة.

أمثلة كود لـ Hero Animations

الرسوم المتحركة القياسية

فيما يلي مثال على فئة PhotoHero لإنشاء Hero بسيط:

class PhotoHero extends StatelessWidget {
  const PhotoHero({
    super.key,
    required this.photo,
    this.onTap,
    required this.width,
  });

  final String photo;
  final VoidCallback? onTap;
  final double width;

  @override
  Widget build(BuildContext context) {
    return SizedBox(
      width: width,
      child: Hero(
        tag: photo,
        child: Material(
          color: Colors.transparent,
          child: InkWell(
            onTap: onTap,
            child: Image.asset(
              photo,
              fit: BoxFit.contain,
            ),
          ),
        ),
      ),
    );
  }
}

استخدام Hero في شاشتين

في الشاشة الأولى (MainScreen):

class MainScreen extends StatelessWidget {
  const MainScreen({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Main Screen'),
      ),
      body: GestureDetector(
        onTap: () {
          Navigator.push(context, MaterialPageRoute<void>(
            builder: (BuildContext context) {
              return Scaffold(
                appBar: AppBar(
                  title: const Text('Flippers Page'),
                ),
                body: Container(
                  color: Colors.lightBlueAccent,
                  alignment: Alignment.center,
                  child: const Hero(
                    tag: 'flutter_logo',
                    child: SizedBox(
                      width: 300.0,
                      child: FlutterLogo(),
                    ),
                  ),
                ),
              );
            },
          ));
        },
        child: Hero(
          tag: 'flutter_logo',
          child: SizedBox(
            width: 120.0,
            child: FlutterLogo(),
          ),
        ),
      ),
    );
  }
}

الرسوم المتحركة الشعاعية (Radial Hero)

لتنفيذ Radial Hero، استخدم RadialExpansion:

class RadialExpansionDemo extends StatelessWidget {
  static const double kMinRadius = 32.0;
  static const double kMaxRadius = 128.0;
  static const opacityCurve = Interval(0.0, 0.75, curve: Curves.fastOutSlowIn);

  static RectTween _createRectTween(Rect? begin, Rect? end) {
    return MaterialRectCenterArcTween(begin: begin, end: end);
  }

  static Widget _buildPage(BuildContext context, String imageName, String description) {
    return Container(
      color: Theme.of(context).canvasColor,
      child: Center(
        child: Card(
          elevation: 8.0,
          child: Column(
            mainAxisSize: MainAxisSize.min,
            children: [
              SizedBox(
                width: kMaxRadius * 2.0,
                height: kMaxRadius * 2.0,
                child: Hero(
                  createRectTween: _createRectTween,
                  tag: imageName,
                  child: RadialExpansion(
                    maxRadius: kMaxRadius,
                    child: Photo(
                      photo: imageName,
                      onTap: () {
                        Navigator.of(context).pop();
                      },
                    ),
                  ),
                ),
              ),
              Text(
                description,
                style: const TextStyle(fontWeight: FontWeight.bold),
                textScaleFactor: 3.0,
              ),
              const SizedBox(height: 16.0),
            ],
          ),
        ),
      ),
    );
  }

  Widget _buildHero(BuildContext context, String imageName, String description) {
    return SizedBox(
      width: kMinRadius * 2.0,
      height: kMinRadius * 2.0,
      child: Hero(
        createRectTween: _createRectTween,
        tag: imageName,
        child: RadialExpansion(
          maxRadius: kMaxRadius,
          child: Photo(
            photo: imageName,
            onTap: () {
              Navigator.of(context).push(
                PageRouteBuilder<void>(
                  pageBuilder: (BuildContext context, Animation<double> animation, Animation<double> secondaryAnimation) {
                    return AnimatedBuilder(
                      animation: animation,
                      builder: (BuildContext context, Widget? child) {
                        return Opacity(
                          opacity: opacityCurve.transform(animation.value),
                          child: _buildPage(context, imageName, description),
                        );
                      },
                    );
                  },
                ),
              );
            },
          ),
        ),
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Radial Transition Demo'),
      ),
      body: Container(
        padding: const EdgeInsets.all(32.0),
        alignment: FractionalOffset.bottomLeft,
        child: Row(
          mainAxisAlignment: MainAxisAlignment.spaceBetween,
          children: [
            _buildHero(context, 'assets/chair-alpha.png', 'Chair'),
            _buildHero(context, 'assets/binoculars-alpha.png', 'Binoculars'),
            _buildHero(context, 'assets/beachball-alpha.png', 'Beach ball'),
          ],
        ),
      ),
    );
  }
}

الاعتبارات للمنصات المختلفة

تتكيف Hero Animations تلقائيًا مع المنصات، مثل Android وiOS، لتوفير تأثيرات انتقال مناسبة. تأكد من اختبار التطبيق على منصات متعددة لضمان السلاسة.

نصائح إضافية لـ Hero Animations

  • استخدم علامات فريدة لكل Hero لتجنب التعارض.
  • ضمن تطابق شجرة الواجهات قدر الإمكان لنتائج أفضل.
  • استخدم Radial لتغييرات الشكل، مثل من دائري إلى مستطيل.
  • للرسوم المعقدة، جرب مكتبات مثل Rive أو Lottie كبدائل.

الخاتمة

Hero Animations هي أداة قوية في Flutter لإنشاء تجارب مستخدم سلسة وجذابة. باتباع الخطوات والأمثلة أعلاه، يمكنك إضافتها إلى تطبيقاتك بسهولة. جربها اليوم لترى الفرق في جاذبية تطبيقك!

By احمد علي

مطور تطبيقات هواتف ذكية باستخدام Flutter، وصانع محتوى تقني يكتب عن الذكاء الاصطناعي والبرمجة وتطورات التكنولوجيا الحديثة. أسعى لتبسيط الأفكار المعقدة ومشاركة خبرتي مع المهتمين بالمجال.

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *