تقبل العديد من واجهات برمجة التطبيقات Animation API عادةً مَعلمات لتخصيص سلوكها.
تخصيص الصور المتحركة باستخدام المَعلمة AnimationSpec
تتيح معظم Animation API للمطوّرين تخصيص مواصفات الحركة من خلال مَعلمة AnimationSpec اختيارية.
val alpha: Float by animateFloatAsState( targetValue = if (enabled) 1f else 0.5f, // Configure the animation duration and easing. animationSpec = tween(durationMillis = 300, easing = FastOutSlowInEasing), label = "alpha" )
هناك أنواع مختلفة من AnimationSpec لإنشاء أنواع مختلفة من
الرسوم المتحركة.
إنشاء صور متحركة مستنِدة إلى الفيزياء باستخدام spring
تنشئ السمة spring صورة متحركة مستندة إلى الفيزياء بين قيمتَي البداية والنهاية. وتتطلّب مَعلمتَين: dampingRatio وstiffness.
تحدّد السمة dampingRatio مدى ارتداد النابض. القيمة التلقائية هي
Spring.DampingRatioNoBouncy.
تحدّد السمة stiffness مدى سرعة تحرّك النابض نحو القيمة النهائية. القيمة التلقائية هي Spring.StiffnessMedium.
val value by animateFloatAsState( targetValue = 1f, animationSpec = spring( dampingRatio = Spring.DampingRatioHighBouncy, stiffness = Spring.StiffnessMedium ), label = "spring spec" )
يمكن أن يتعامل spring مع الانقطاعات بسلاسة أكبر من الأنواع
AnimationSpec المستندة إلى المدة لأنّه يضمن استمرارية السرعة عند
تغيير القيمة المستهدَفة أثناء عرض الصور المتحركة. يتم استخدام spring كقيمة تلقائية لـ AnimationSpec من خلال العديد من واجهات برمجة التطبيقات الخاصة بالحركة، مثل animate*AsState وupdateTransition.
على سبيل المثال، إذا طبّقنا إعدادات spring على الصورة المتحركة التالية التي يتم تشغيلها من خلال لمس المستخدم، عند مقاطعة الصورة المتحركة أثناء تقدّمها، يمكنك ملاحظة أنّ استخدام tween لا يستجيب بسلاسة مثل استخدام spring.
tween مقابل spring للصور المتحركة ومقاطعتهايمكنك إنشاء صور متحركة بين قيمتَي البداية والنهاية باستخدام منحنى التخفيف مع tween
تُنشئ الدالة tween صورًا متحركة بين قيمتَي البداية والنهاية خلال
durationMillis المحدَّدة باستخدام منحنى التخفيف. tween هو اختصار لكلمة "بين"،
لأنّه يقع بين قيمتَين.
يمكنك أيضًا تحديد delayMillis لتأجيل بدء الحركة.
val value by animateFloatAsState( targetValue = 1f, animationSpec = tween( durationMillis = 300, delayMillis = 50, easing = LinearOutSlowInEasing ), label = "tween delay" )
لمزيد من المعلومات، يُرجى الاطّلاع على التخفيف.
يمكنك إنشاء صور متحركة بقيم محدّدة في أوقات معيّنة باستخدام keyframes
يتم تحريك keyframes استنادًا إلى قيم اللقطات المحدّدة في طوابع زمنية مختلفة خلال مدة الصورة المتحركة. في أي وقت، سيتم استيفاء قيمة الصورة المتحركة بين قيمتَي إطارين رئيسيين. بالنسبة إلى كل من هذه الإطارات الرئيسية، يمكن تحديد "التخفيف" لتحديد منحنى الاستكمال.
يمكنك تحديد القيم عند 0 ملي ثانية وعند مدة العرض، ولكن هذا الإجراء اختياري. إذا لم تحدّد هذه القيم، سيتم ضبطها تلقائيًا على قيمتَي البداية والنهاية للحركة على التوالي.
val value by animateFloatAsState( targetValue = 1f, animationSpec = keyframes { durationMillis = 375 0.0f at 0 using LinearOutSlowInEasing // for 0-15 ms 0.2f at 15 using FastOutLinearInEasing // for 15-75 ms 0.4f at 75 // ms 0.4f at 225 // ms }, label = "keyframe" )
يمكنك إضافة تأثيرات متحركة بين الإطارات الرئيسية بسلاسة باستخدام keyframesWithSpline
لإنشاء صورة متحركة تتبع منحنى سلسًا أثناء انتقالها بين القيم، يمكنك استخدام مواصفات الصورة المتحركة keyframesWithSpline بدلاً من keyframes.
val offset by animateOffsetAsState( targetValue = Offset(300f, 300f), animationSpec = keyframesWithSpline { durationMillis = 6000 Offset(0f, 0f) at 0 Offset(150f, 200f) atFraction 0.5f Offset(0f, 100f) atFraction 0.7f } )
تُعدّ الإطارات الرئيسية المستندة إلى المنحنيات مفيدة بشكل خاص للحركة الثنائية الأبعاد للعناصر على الشاشة.
تعرض الفيديوهات التالية الاختلافات بين keyframes وkeyframesWithSpline بالنظر إلى مجموعة الإحداثيات نفسها التي يجب أن تتبعها الدائرة.
keyframes
|
keyframesWithSpline
|
|---|---|
كما ترون، توفّر الإطارات الرئيسية المستندة إلى الخطوط المنحنية انتقالات أكثر سلاسة بين النقاط، لأنّها تستخدم منحنيات بيزييه لتحريك العناصر بسلاسة. هذه المواصفات مفيدة للحركات المُعدّة مُسبَقًا. ومع ذلك، إذا كنت تعمل مع نقاط يحركها المستخدم، فمن الأفضل استخدام النوابض لتحقيق سلاسة مماثلة بين النقاط لأنها قابلة للمقاطعة.
تكرار صورة متحركة باستخدام "repeatable"
تُشغِّل السمة repeatable حركة مستندة إلى المدة (مثل tween أو keyframes)
بشكل متكرر إلى أن تصل إلى عدد التكرارات المحدّد. يمكنك تمرير المَعلمة repeatMode لتحديد ما إذا كان يجب تكرار الحركة من البداية (RepeatMode.Restart) أو من النهاية (RepeatMode.Reverse).
val value by animateFloatAsState( targetValue = 1f, animationSpec = repeatable( iterations = 3, animation = tween(durationMillis = 300), repeatMode = RepeatMode.Reverse ), label = "repeatable spec" )
تكرار صورة متحركة بشكل لا نهائي باستخدام infiniteRepeatable
infiniteRepeatable تشبه repeatable، ولكنها تتكرر لعدد لا نهائي
من المرات.
val value by animateFloatAsState( targetValue = 1f, animationSpec = infiniteRepeatable( animation = tween(durationMillis = 300), repeatMode = RepeatMode.Reverse ), label = "infinite repeatable" )
في الاختبارات التي تستخدم
ComposeTestRule،
لا يتم تشغيل الصور المتحركة التي تستخدم infiniteRepeatable. سيتم عرض المكوّن باستخدام القيمة الأولية لكل قيمة متحركة.
الانتقال فورًا إلى القيمة النهائية باستخدام snap
snap هو AnimationSpec خاص يغيّر القيمة على الفور إلى القيمة النهائية. يمكنك تحديد delayMillis لتأخير بدء
الحركة.
val value by animateFloatAsState( targetValue = 1f, animationSpec = snap(delayMillis = 50), label = "snap spec" )
ضبط دالة تخفيف مخصّصة
تستخدم عمليات AnimationSpec المستندة إلى المدة (مثل tween أو keyframes)
Easing لضبط جزء من الحركة. يتيح ذلك لقيمة الحركة أن تزيد سرعتها أو تنخفض، بدلاً من التحرك بمعدل ثابت. "الكسر" هو قيمة بين 0 (البداية) و1.0 (النهاية) تشير إلى النقطة الحالية في الحركة.
في الواقع، التسهيل هو دالة تأخذ قيمة كسرية بين 0 و1.0 وتعرض عددًا عشريًا. يمكن أن تكون القيمة المعروضة خارج الحدود لتمثيل التجاوز أو النقص. يمكن إنشاء "تخفيف" مخصّص مثل الرمز أدناه.
val CustomEasing = Easing { fraction -> fraction * fraction } @Composable fun EasingUsage() { val value by animateFloatAsState( targetValue = 1f, animationSpec = tween( durationMillis = 300, easing = CustomEasing ), label = "custom easing" ) // …… }
توفّر أداة Compose العديد من دوال Easing المضمّنة التي تغطي معظم حالات الاستخدام.
يُرجى الاطّلاع على السرعة - التصميم المتعدد الأبعاد لمزيد من المعلومات حول "التخفيف" الذي يجب استخدامه حسب السيناريو.
FastOutSlowInEasingLinearOutSlowInEasingFastOutLinearInEasingLinearEasingCubicBezierEasing- عرض المزيد
تحريك أنواع البيانات المخصّصة من خلال التحويل من وإلى AnimationVector
تتيح معظم واجهات برمجة التطبيقات للحركة في Compose استخدام Float وColor وDp وأنواع البيانات الأساسية الأخرى كقيم للحركة تلقائيًا، ولكنك تحتاج أحيانًا إلى تحريك أنواع بيانات أخرى، بما في ذلك الأنواع المخصّصة. أثناء الحركة، يتم تمثيل أي قيمة متحركة على أنّها AnimationVector. يتم تحويل القيمة إلى AnimationVector والعكس صحيح من خلال TwoWayConverter المقابل بحيث يمكن لنظام الصور المتحركة الأساسي التعامل معها بشكل موحد. على سبيل المثال، يتم تمثيل Int على أنه AnimationVector1D يحتوي على قيمة عائمة واحدة.
TwoWayConverter لـ "Int" تظهر على النحو التالي:
val IntToVector: TwoWayConverter<Int, AnimationVector1D> = TwoWayConverter({ AnimationVector1D(it.toFloat()) }, { it.value.toInt() })
Color هي في الأساس مجموعة من 4 قيم، وهي الأحمر والأخضر والأزرق وألفا، لذا يتم تحويل Color إلى AnimationVector4D يحتوي على 4 قيم عائمة. بهذه الطريقة، يتم تحويل كل نوع بيانات مستخدَم في الصور المتحركة إلى AnimationVector1D أو AnimationVector2D أو AnimationVector3D أو AnimationVector4D حسب أبعاده. يتيح ذلك تحريك المكوّنات المختلفة للعنصر بشكل مستقل، ولكل منها تتبُّع السرعة الخاص بها. يمكن الوصول إلى المحوّلات المضمّنة لأنواع البيانات الأساسية
باستخدام محوّلات مثل Color.VectorConverter أو Dp.VectorConverter.
عندما تريد إضافة دعم لنوع بيانات جديد كقيمة متحركة، يمكنك إنشاء TwoWayConverter الخاص بك وتقديمه إلى واجهة برمجة التطبيقات. على سبيل المثال، يمكنك
استخدام animateValueAsState لإضافة تأثيرات حركية إلى نوع البيانات المخصّص على النحو التالي:
data class MySize(val width: Dp, val height: Dp) @Composable fun MyAnimation(targetSize: MySize) { val animSize: MySize by animateValueAsState( targetSize, TwoWayConverter( convertToVector = { size: MySize -> // Extract a float value from each of the `Dp` fields. AnimationVector2D(size.width.value, size.height.value) }, convertFromVector = { vector: AnimationVector2D -> MySize(vector.v1.dp, vector.v2.dp) } ), label = "size" ) }
تتضمّن القائمة التالية بعض VectorConverters المضمّنة:
Color.VectorConverterDp.VectorConverterOffset.VectorConverterInt.VectorConverterFloat.VectorConverterIntSize.VectorConverter
التطبيقات المقترَحة لك
- ملاحظة: يتم عرض نص الرابط عندما يكون JavaScript غير مفعَّل
- الصور المتحركة المستندة إلى القيمة
- تطوير الرموز البرمجية بشكل متكرّر
- الصور المتحركة في Compose