الرسوم المتحركة
الرسوم المتحركة في أنجولار (Angular Animations) تُعدّ من أقوى الأدوات التي تتيح للمطورين إنشاء واجهات مستخدم ديناميكية وسلسة تضيف تجربة بصرية متميزة للتطبيقات أحادية الصفحة (SPAs). تُستخدم الرسوم المتحركة في أنجولار لتوضيح الانتقالات بين الحالات المختلفة للمكونات (Components) أو العناصر داخل الصفحة، مثل إظهار عنصر أو إخفائه، أو التحريك بين صفحات مختلفة داخل التطبيق.
تكمن أهمية الرسوم المتحركة في أنها تُساعد على تعزيز تجربة المستخدم (UX) عبر توجيه الانتباه، وتوضيح التغيرات في الحالة (State Changes) بطريقة بصرية. تعتمد أنجولار على مكتبة داخلية تُعرف بـ @angular/animations
والتي تُتيح للمطور استخدام وظائف مثل trigger
، وstate
، وtransition
، وanimate
لبناء حركة دقيقة وقابلة للتحكم.
في هذا الدرس، سيتعلم القارئ كيفية إنشاء وتحكم بالرسوم المتحركة داخل المكونات، وكيفية ربطها بدورة حياة المكون (Lifecycle) وحالة البيانات (State Management). كما سنتناول كيفية تحسين الأداء باستخدام استراتيجيات تمنع إعادة التصيير (Unnecessary Re-renders) وضمان تدفق بيانات (Data Flow) فعّال داخل التطبيق.
تمثل الرسوم المتحركة في أنجولار جزءاً أساسياً من بناء تطبيقات ويب حديثة متجاوبة تُضفي سلاسة وحيوية على التفاعل مع المستخدمين.
مثال أساسي
typescript// app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { AppComponent } from './app.component';
@NgModule({
declarations: [AppComponent],
imports: [BrowserModule, BrowserAnimationsModule],
bootstrap: [AppComponent]
})
export class AppModule { }
// app.component.ts
import { Component } from '@angular/core';
import { trigger, state, style, animate, transition } from '@angular/animations';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
animations: [
trigger('boxState', [
state('inactive', style({
backgroundColor: '#e0e0e0',
transform: 'scale(1)'
})),
state('active', style({
backgroundColor: '#3f51b5',
transform: 'scale(1.2)'
})),
transition('inactive <=> active', [
animate('300ms ease-in-out')
])
])
]
})
export class AppComponent {
state = 'inactive';
toggleState() {
this.state = this.state === 'active' ? 'inactive' : 'active';
}
}
// app.component.html
<div [@boxState]="state" class="box" (click)="toggleState()">
اضغط لتغيير الحالة
</div>
// app.component.css
.box {
width: 200px;
height: 200px;
margin: 50px auto;
text-align: center;
line-height: 200px;
cursor: pointer;
color: white;
border-radius: 8px;
}
في هذا المثال الأساسي، نُنشئ مكوناً في أنجولار يُطبّق حركة بسيطة باستخدام مكتبة @angular/animations
.
في ملف app.module.ts
، نقوم باستيراد BrowserAnimationsModule
الذي يُمكّن أنجولار من استخدام واجهة التحريك داخل المتصفح. هذا الاستيراد ضروري لتفعيل الرسوم المتحركة على مستوى التطبيق.
أما في app.component.ts
، نُعرف مجموعة من الحالات (state
) تحت اسم boxState
، وهي تمثل الوضعين المختلفين للمكون: inactive
وactive
. داخل كل حالة نُحدد أسلوب العرض باستخدام style()
مثل اللون والحجم. الانتقال بين الحالتين يتم عبر transition
باستخدام animate
الذي يحدد مدة الحركة وطريقتها.
عند الضغط على المربع (في <a href="/ar/html/" class="smart-link">HTML</a>
)، يتم استدعاء دالة toggleState()
لتغيير الحالة، مما يُشغل الرسوم المتحركة تلقائياً. هذه الآلية تعتمد على مفهوم إدارة الحالة (State Management) داخل المكون، حيث يتغير مظهر العنصر بناءً على قيمته الحالية.
هذا النمط يعكس التكامل بين دورة حياة المكون وتدفق البيانات، ويُظهر كيف يمكن للرسوم المتحركة أن تكون مرتبطة مباشرة بتغيرات الحالة المنطقية داخل التطبيق. كما يوضح كيفية تنظيم الأكواد بطريقة قابلة لإعادة الاستخدام (Reusable Components) ضمن تطبيقات أنجولار الحديثة.
مثال عملي
typescript// animated-list.component.ts
import { Component } from '@angular/core';
import { trigger, transition, style, animate, query, stagger } from '@angular/animations';
@Component({
selector: 'app-animated-list',
templateUrl: './animated-list.component.html',
styleUrls: ['./animated-list.component.css'],
animations: [
trigger('listAnimation', [
transition('* => *', [
query(':enter', [
style({ opacity: 0, transform: 'translateY(-20px)' }),
stagger(100, [
animate('400ms ease-out', style({ opacity: 1, transform: 'translateY(0)' }))
])
], { optional: true }),
query(':leave', [
animate('300ms', style({ opacity: 0, transform: 'translateY(20px)' }))
], { optional: true })
])
])
]
})
export class AnimatedListComponent {
items = ['العنصر الأول', 'العنصر الثاني', 'العنصر الثالث'];
addItem() {
this.items.push(`عنصر جديد ${this.items.length + 1}`);
}
removeItem() {
this.items.pop();
}
}
// animated-list.component.html
<div [@listAnimation]="items.length">
<div *ngFor="let item of items" class="list-item">{{ item }}</div>
</div>
<button (click)="addItem()">إضافة عنصر</button>
<button (click)="removeItem()">إزالة عنصر</button>
// animated-list.component.css
.list-item {
background-color: #2196f3;
color: white;
margin: 10px;
padding: 15px;
border-radius: 6px;
}
في هذا المثال العملي، ننتقل إلى سيناريو أكثر واقعية حيث يتم تطبيق الرسوم المتحركة على قائمة ديناميكية من العناصر.
استخدمنا trigger('listAnimation', ...)
مع query
وstagger
لإدارة دخول وخروج العناصر من القائمة بطريقة متتابعة وسلسة. هذه التقنية تُبرز قوة أنجولار في التعامل مع DOM بطريقة آمنة ومتحكم بها من خلال دورة حياة المكون.
يُستدعى التحريك تلقائياً عند تغيير طول المصفوفة items
بفضل الربط في [@listAnimation]="items.length"
. عندما يُضاف عنصر جديد، يُطبّق تأثير الدخول (:enter
)، وعند إزالة عنصر، يُنفّذ تأثير الخروج (:leave
).
يمثل هذا المثال دمجاً فعلياً بين إدارة الحالة (State Management) وتدفق البيانات (Data Flow) في المكون. كما يُظهر كيف يمكن تحسين الأداء عبر استخدام stagger
لتوزيع الحركات زمنياً وتجنب التحميل الزائد على واجهة المستخدم.
يُعتبر هذا الأسلوب من أفضل الممارسات في بناء واجهات تفاعلية ديناميكية، مع الحفاظ على أداء عالي وقابلية إعادة الاستخدام ضمن أنجولار.
أفضل الممارسات والمزالق الشائعة في أنجولار (200-250 كلمة):
من أهم الممارسات المثلى في استخدام الرسوم المتحركة داخل أنجولار هي عزل منطق الرسوم المتحركة عن منطق العمل (Business Logic) في المكون، بحيث تكون الحركة مرتبطة بالحالة فقط وليس بالمخرجات المباشرة. كما يُفضل تعريف التحريكات في ملفات مخصصة أو داخل قسم animations
في @Component
للحفاظ على القابلية للصيانة.
تجنّب الأخطاء الشائعة مثل:
- "Prop Drilling" أي تمرير القيم المتكررة بين المكونات دون الحاجة، مما يؤدي إلى إعادة تصيير غير ضرورية.
- إعادة التصيير المتكرر (Unnecessary Re-renders) عند ربط متغيرات غير مستقرة بالرسوم المتحركة.
- التعديل المباشر على الحالة (State Mutations) دون استخدام آليات أنجولار مثل
ChangeDetection
.
لتحسين الأداء، استخدم استراتيجيات مثلOnPush Change Detection
وتقليل العمليات الحسابية داخلtemplate
.
من ناحية الأمان، تجنب تنفيذ تحريكات مبنية على مدخلات المستخدم دون التحقق منها لمنع هجمات XSS أو CSS Injection.
في حال وجود مشاكل، استخدم أدوات مثلAngular DevTools
لتحليل الأداء ومراقبة دورة حياة المكونات أثناء تنفيذ التحريك.
الهدف هو تحقيق توازن بين الجمالية والأداء والاستقرار في التطبيق.
📊 جدول مرجعي
أنجولار Element/Concept | Description | Usage Example |
---|---|---|
trigger | يُعرّف نقطة بداية لتحريك عنصر | trigger('fadeIn', [...]) |
state | يُحدد الحالة البصرية للمكون | state('active', style({ opacity: 1 })) |
transition | يُحدد العلاقة الزمنية بين الحالات | transition('void => *', [animate('300ms')]) |
animate | يُحدد مدة وطريقة التحريك | animate('500ms ease-in') |
query | يستخدم لتحديد عناصر فرعية ضمن الرسوم المتحركة | query(':enter', [...]) |
stagger | يُنفّذ تحريكاً متتابعاً على عدة عناصر | stagger(100, [animate(...)]) |
الملخص والخطوات التالية في أنجولار:
تعلمت في هذا الدرس كيفية إنشاء وتحكم بالرسوم المتحركة في أنجولار بدءاً من الأمثلة البسيطة وصولاً إلى التطبيقات العملية الواقعية. أصبحت الآن قادراً على استخدام @angular/animations
لربط الحالة المنطقية بالمظهر البصري بطريقة متناسقة داخل دورة حياة المكون.
الرسوم المتحركة لا تُعد فقط عنصراً جمالياً، بل أداة تفاعلية فعّالة تساعد المستخدم على فهم التغيرات داخل التطبيق.
الخطوة التالية الموصى بها هي دراسة التحريكات المعقدة باستخدام AnimationBuilder
وAnimationFactory
لتوليد حركات ديناميكية برمجياً.
كما يُنصح باستكشاف مواضيع متقدمة مثل الأداء مع ChangeDetectionStrategy.OnPush
ودمج الرسوم المتحركة مع مكتبات خارجية مثل Angular Material
لتحسين واجهات المستخدم.
تطبيق هذه المفاهيم سيُساهم في بناء تطبيقات ويب حديثة عالية الأداء وجذابة بصرياً.
🧠 اختبر معرفتك
اختبر معرفتك
تحدى نفسك مع هذا الاختبار التفاعلي واكتشف مدى فهمك للموضوع
📝 التعليمات
- اقرأ كل سؤال بعناية
- اختر أفضل إجابة لكل سؤال
- يمكنك إعادة الاختبار عدة مرات كما تريد
- سيتم عرض تقدمك في الأعلى