ऐनिमेशन को पसंद के मुताबिक बनाएं

आम तौर पर, कई ऐनिमेशन एपीआई अपने व्यवहार को पसंद के मुताबिक बनाने के लिए पैरामीटर स्वीकार करते हैं.

AnimationSpec पैरामीटर की मदद से ऐनिमेशन को पसंद के मुताबिक बनाना

ज़्यादातर ऐनिमेशन एपीआई, डेवलपर को ऐनिमेशन की जानकारी को पसंद के मुताबिक बनाने की अनुमति देते हैं. इसके लिए, 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, ऐनिमेशन के दौरान अलग-अलग टाइमस्टैंप पर बताई गई स्नैपशॉट वैल्यू के आधार पर ऐनिमेट करता है. किसी भी समय, ऐनिमेशन की वैल्यू को दो मुख्य फ़्रेम की वैल्यू के बीच इंटरपोलेट किया जाएगा. इनमें से हर एक keyframe के लिए, इंटरपोलेशन कर्व तय करने के लिए, आसानी से बदलने की सुविधा तय की जा सकती है.

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"
)

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 के बीच के फ़्रैक्शन की वैल्यू लेता है और एक फ़्लोट दिखाता है. रिटर्न की गई वैल्यू, तय सीमा से बाहर हो सकती है, ताकि ज़्यादा या कम होने की जानकारी दी जा सके. कस्टम ईज़िंग को नीचे दिए गए कोड की तरह बनाया जा सकता है.

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 फ़ंक्शन होते हैं, जो इस्तेमाल के ज़्यादातर उदाहरणों को कवर करते हैं. अपने हिसाब से, किस तरह के ऐक्शन के लिए किस तरह के ऐक्शन की सुविधा का इस्तेमाल करना है, इस बारे में ज़्यादा जानकारी के लिए स्पीड - Material Design देखें.

AnimationVector में बदलकर और उससे बदलकर, कस्टम डेटा टाइप को ऐनिमेट करना

Compose ऐनिमेशन एपीआई में, Float, Color, Dp, और अन्य बुनियादी डेटा टाइप को डिफ़ॉल्ट रूप से ऐनिमेशन वैल्यू के तौर पर इस्तेमाल किया जा सकता है. हालांकि, कभी-कभी आपको अपने कस्टम डेटा टाइप के साथ-साथ अन्य डेटा टाइप को ऐनिमेट करना पड़ता है. ऐनिमेशन के दौरान, ऐनिमेट की जा रही किसी भी वैल्यू को AnimationVector के तौर पर दिखाया जाता है. वैल्यू को AnimationVector में बदला जाता है और TwoWayConverter से वैल्यू को वापस AnimationVector में बदला जाता है, ताकि मुख्य ऐनिमेशन सिस्टम उन्हें एक जैसा मैनेज कर सके. उदाहरण के लिए, Int को AnimationVector1D के तौर पर दिखाया जाता है, जिसमें एक फ़्लोट वैल्यू होती है. Int के लिए TwoWayConverter इस तरह दिखता है:

val IntToVector: TwoWayConverter<Int, AnimationVector1D> =
    TwoWayConverter({ AnimationVector1D(it.toFloat()) }, { it.value.toInt() })

Color, असल में चार वैल्यू का एक सेट है, जैसे कि लाल, हरा, नीला, और अल्फा. इसलिए, Color को AnimationVector4D में बदल दिया जाता है, जिसमें चार फ़्लोट वैल्यू होती हैं. इस तरह, ऐनिमेशन में इस्तेमाल किए गए हर डेटा टाइप को, डाइमेंशन के हिसाब से 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"
    )
}

यहां दी गई सूची में, पहले से मौजूद कुछ VectorConverter शामिल हैं: