بسیاری از API های انیمیشن معمولاً پارامترهایی را برای سفارشی کردن رفتار خود می پذیرند.
انیمیشن ها را با پارامتر AnimationSpec سفارشی کنید
اکثر 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 یک انیمیشن مبتنی بر فیزیک بین مقادیر شروع و پایان ایجاد می کند. 2 پارامتر نیاز دارد: 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 پیش فرض توسط بسیاری از APIهای انیمیشن مانند animate*AsState و updateTransition استفاده می شود.
به عنوان مثال، اگر یک پیکربندی spring را به انیمیشن زیر اعمال کنیم که توسط لمس کاربر ایجاد میشود، وقتی انیمیشن در حال پیشرفت آن قطع میشود، میبینید که استفاده از tween به نرمی استفاده از spring پاسخ نمیدهد.
tween مشخصات در مقابل spring برای انیمیشن و قطع آن. متحرک سازی بین مقادیر شروع و پایان با منحنی کاهش با tween
بین مقادیر شروع و پایان در durationMillis مشخص شده Millis با استفاده از یک منحنی کاهش متحرک سازی tween . tween مخفف کلمه between - زیرا بین دو مقدار است.
همچنین می توانید delayMillis برای به تعویق انداختن شروع انیمیشن مشخص کنید.
val value by animateFloatAsState( targetValue = 1f, animationSpec = tween( durationMillis = 300, delayMillis = 50, easing = LinearOutSlowInEasing ), label = "tween delay" )
برای اطلاعات بیشتر به آسانی مراجعه کنید.
با استفاده از keyframes ، در زمانهای خاص به مقادیر خاصی متحرک شوید
keyframes بر اساس مقادیر عکس فوری مشخص شده در مُهرهای زمانی مختلف در طول مدت انیمیشن متحرک می شوند. در هر زمان معین، مقدار انیمیشن بین دو مقدار فریم کلیدی درون یابی می شود. برای هر یک از این فریم های کلیدی، Easing را می توان برای تعیین منحنی درون یابی تعیین کرد.
این اختیاری است که مقادیر را در 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" )
با keyframesWithSplines بین فریم های کلیدی به راحتی متحرک شوید
برای ایجاد انیمیشنی که در حین انتقال بین مقادیر از یک منحنی صاف پیروی می کند، می توانید به جای مشخصات انیمیشن فریم keyframes keyframesWithSplines استفاده کنید.
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 } )
فریم های کلیدی مبتنی بر Spline به ویژه برای جابجایی 2 بعدی آیتم ها روی صفحه مفید هستند.
ویدیوهای زیر تفاوتهای بین keyframes و keyframesWithSpline را با توجه به مجموعهای از مختصات x، y که یک دایره باید دنبال کند، نشان میدهد.
keyframes | keyframesWithSplines |
|---|---|
همانطور که می بینید، فریم های کلیدی مبتنی بر spline انتقال نرم تری را بین نقاط ارائه می دهند، زیرا از منحنی های bezier برای متحرک سازی هموار بین آیتم ها استفاده می کنند. این مشخصات برای یک انیمیشن از پیش تعیین شده مفید است. با این حال، اگر با نقاط کاربر محور کار میکنید، ترجیحاً از فنرها برای دستیابی به صافی مشابه بین نقاط استفاده کنید، زیرا آنها قابل وقفه هستند.
یک انیمیشن را با 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 (پایان) است که نقطه فعلی در انیمیشن را نشان می دهد.
Easing در واقع تابعی است که مقدار کسری بین 0 و 1.0 می گیرد و یک float برمی گرداند. مقدار برگشتی می تواند خارج از مرز باشد تا بیش از حد یا کمتر از آن را نشان دهد. یک Easing سفارشی می تواند مانند کد زیر ایجاد شود.
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 داخلی را ارائه می دهد که بیشتر موارد استفاده را پوشش می دهد. به Speed - Material Design برای اطلاعات بیشتر در مورد اینکه از چه Easing بسته به سناریوی شما استفاده کنید، مراجعه کنید.
-
FastOutSlowInEasing -
LinearOutSlowInEasing -
FastOutLinearEasing -
LinearEasing -
CubicBezierEasing - بیشتر ببینید
با تبدیل و تبدیل به AnimationVector ، انواع داده های سفارشی را متحرک کنید
اکثر APIهای انیمیشن 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 خود را ایجاد کرده و آن را به API ارائه دهید. به عنوان مثال، می توانید از 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" ) }
لیست زیر شامل برخی از VectorConverter داخلی است:
-
Color.VectorConverter -
Dp.VectorConverter -
Offset.VectorConverter -
Int.VectorConverter -
Float.VectorConverter -
IntSize.VectorConverter
برای شما توصیه می شود
- توجه: وقتی جاوا اسکریپت خاموش است، متن پیوند نمایش داده می شود
- انیمیشن های مبتنی بر ارزش
- توسعه کد تکراری {:#iterative-code-dev }
- انیمیشن ها در Compose