Android Academy · पाठ

जेस्चर और स्प्रिंग एनीमेशन

प्राकृतिक, भौतिकी-आधारित गति।

पाठ 4, कुल 4 में से13 चरण

जेस्चर और स्प्रिंग एनीमेशन, CoddyKit पर Android Academy का एक निःशुल्क पाठ है। यह 4 में से 4वाँ पाठ है। इस अध्ययन पथ के 3 तक कोई भी पाठ पूरा पढ़ना निःशुल्क है — इसके बाद CoddyKit PRO हर पाठ अनलॉक करता है, साथ ही अंतर्निर्मित कोड संपादक और चौबीसों घंटे एआई शिक्षक के साथ व्यावहारिक अभ्यास भी उपलब्ध कराता है। यह Android Academy सीखने के मार्ग का हिस्सा है और आपकी प्रगति वेब तथा CoddyKit ऐप पर सिंक होती रहती है। Android Academy पाठ्यक्रम में कुल 4 पाठ शामिल हैं।

इंटरैक्टिव, भौतिक गति

सबसे आनंददायक एनिमेशन उपयोगकर्ता की उँगली पर प्रतिक्रिया देते हैं और वास्तविक वस्तुओं जैसे महसूस होते हैं, जिनमें जड़त्व और उछाल होता है। इन्हें बनाने के लिए आप जेस्चर को भौतिकी-आधारित एनिमेशन के साथ संयोजित करते हैं।

इस पाठ में Animatable, स्प्रिंग, फ्लिंग डिके और उन्हें ड्रैग जेस्चर से जोड़कर स्वाभाविक, इंटरैक्टिव यूआई बनाने का तरीका शामिल है।

Animatable: निम्न-स्तरीय नियंत्रण

जहाँ animate*AsState स्टेट पर प्रतिक्रिया करता है, वहीं Animatable आपको अनिवार्य नियंत्रण देता है। आप इसे remember में रखते हैं और animateTo या snapTo जैसे कॉल के साथ एक कॉरूटीन से नियंत्रित करते हैं।

यही जेस्चर-आधारित गति की नींव है।

@Composable
fun BounceOnClick() {
    val scale = remember { Animatable(1f) }
    val scope = rememberCoroutineScope()
    Box(
        Modifier
            .graphicsLayer { scaleX = scale.value; scaleY = scale.value }
            .clickable {
                scope.launch {
                    scale.animateTo(1.3f, spring())
                    scale.animateTo(1f, spring())
                }
            }
    )
}

स्प्रिंग: dampingRatio और stiffness

एक spring विनिर्देश दो मानों से परिभाषित होता है:

  • dampingRatio - कितना उछाल आएगा। कम मान पर अधिक उछाल आता है; 1f (क्रिटिकली डैम्प्ड) लक्ष्य से आगे नहीं जाता।
  • stiffness - कितनी तेज़ी से पहुँचेगा। अधिक मान लक्ष्य तक जल्दी पहुँचता है।

Compose Spring.DampingRatioMediumBouncy और Spring.StiffnessLow जैसे स्थिरांक उपलब्ध कराता है, इसलिए आपको कच्ची संख्याओं का बहुत कम उपयोग करना पड़ता है।

val spec = spring<Float>(
    dampingRatio = Spring.DampingRatioLowBouncy,
    stiffness = Spring.StiffnessMedium
)

// later, inside a coroutine:
// offset.animateTo(targetValue = 0f, animationSpec = spec)

ड्रैग जेस्चर पहचानना

गति को इंटरैक्टिव बनाने के लिए आप टच इनपुट पढ़ते हैं। उपयोगकर्ता अपनी उंगली हिलाता है, तो Modifier.pointerInput के साथ detectDragGestures ड्रैग डेल्टा की जानकारी देता है।

आप इन डेल्टा को एक ऑफ़सेट में जोड़ते जाते हैं और उसे कंपोज़ेबल पर लागू करते हैं।

@Composable
fun Draggable() {
    var offsetX by remember { mutableStateOf(0f) }
    Box(
        Modifier
            .offset { IntOffset(offsetX.roundToInt(), 0) }
            .size(80.dp)
            .background(Color.Red)
            .pointerInput(Unit) {
                detectDragGestures { change, drag ->
                    change.consume()
                    offsetX += drag.x
                }
            }
    )
}

स्प्रिंग के साथ वापस स्नैप करना

"वापस स्नैप" प्रभाव के लिए ड्रैग को Animatable के साथ मिलाएँ। ड्रैग करते समय आप उंगली की स्थिति पर तुरंत snapTo करते हैं; छोड़ने पर स्प्रिंग के साथ animateTo(0f) चलाते हैं, जिससे एलिमेंट उछलकर अपनी जगह लौटता है।

@Composable
fun SnapBack() {
    val offsetX = remember { Animatable(0f) }
    val scope = rememberCoroutineScope()
    Box(
        Modifier
            .offset { IntOffset(offsetX.value.roundToInt(), 0) }
            .size(80.dp)
            .background(Color.Blue)
            .pointerInput(Unit) {
                detectDragGestures(
                    onDrag = { change, drag ->
                        change.consume()
                        scope.launch { offsetX.snapTo(offsetX.value + drag.x) }
                    },
                    onDragEnd = {
                        scope.launch { offsetX.animateTo(0f, spring()) }
                    }
                )
            }
    )
}

वेग के साथ फ़्लिंग करना

वास्तविक फ़्लिंग में उंगली उठाने के बाद भी गति जारी रहती है। VelocityTracker से वेग ट्रैक करें, फिर उसे animateDecay को दें, ताकि एलिमेंट घर्षण-आधारित DecayAnimationSpec का उपयोग करते हुए स्वाभाविक रूप से रुक जाए।

val decay = rememberSplineBasedDecay<Float>()

// on drag end, with measured velocity:
// scope.launch {
//     offsetX.animateDecay(
//         initialVelocity = velocity,
//         animationSpec = decay
//     )
// }

एंकर के साथ स्वाइप करके हटाना

निश्चित विश्राम-स्थितियों वाले स्वाइप जेस्चर के लिए, जैसे स्वाइप करके हटाना, anchoredDraggable परिभाषित एंकर पर स्नैप करता है। आप स्थितियाँ और उनके पिक्सेल स्थान घोषित करते हैं, और Compose उनके बीच का स्प्रिंग संक्रमण संभालता है।

enum class DragValue { Start, End }

val state = remember {
    AnchoredDraggableState(
        initialValue = DragValue.Start,
        anchors = DraggableAnchors {
            DragValue.Start at 0f
            DragValue.End at 300f
        }
    )
}

अनंत और दोहराए जाने वाले एनीमेशन

धड़कते बिंदु या लोडिंग शिमर जैसी लगातार चलने वाली गति के लिए rememberInfiniteTransition को infiniteRepeatable के साथ इस्तेमाल करें। आगे-पीछे चलाने के लिए RepeatMode को Reverse पर सेट करें, या लूप चलाने के लिए Restart पर।

@Composable
fun Pulse() {
    val transition = rememberInfiniteTransition(label = "pulse")
    val scale by transition.animateFloat(
        initialValue = 1f,
        targetValue = 1.2f,
        animationSpec = infiniteRepeatable(
            animation = tween(700),
            repeatMode = RepeatMode.Reverse
        ),
        label = "scale"
    )
    Box(Modifier.graphicsLayer { scaleX = scale; scaleY = scale })
}

जेस्चर और स्प्रिंग को मिलाना

इंटरैक्टिव डिज़ाइन का मूल पैटर्न है: खींचकर स्थान बदलना और छोड़कर स्थिर होना। ड्रैग के दौरान वेग ट्रैक करें, फिर दूरी या गति के आधार पर animateDecay से फ़्लिंग करें या spring के साथ किसी एंकर की ओर स्थिर करें।

बॉटम शीट, कैरोसेल और हटाए जा सकने वाले कार्ड इतने स्वाभाविक इसी वजह से महसूस होते हैं।

// pattern:
// 1) onDrag    -> animatable.snapTo(current + delta)
// 2) onDragEnd -> if (fast) animatable.animateDecay(velocity, decay)
//                 else      animatable.animateTo(nearestAnchor, spring())

शुद्ध Kotlin में स्प्रिंग से स्थिर होना

स्प्रिंग के स्थिर होने का अनुभव समझने के लिए यहाँ शुद्ध Kotlin का एक न्यूनतम लूप है। यह हर चरण में लक्ष्य की ओर लौटाने वाला बल लागू करता है और वेग को कम करता है—यही विचार Compose हर फ़्रेम में चलाता है।

fun main() {
    var pos = 0f
    var vel = 0f
    val target = 200f
    val stiffness = 0.2f
    val damping = 0.75f
    repeat(8) { step ->
        vel = (vel + (target - pos) * stiffness) * damping
        pos += vel
        println("step $step pos=${"%.1f".format(pos)}")
    }
}

टैप, प्रेस और कई जेस्चर

ड्रैग ही एकमात्र जेस्चर नहीं है। pointerInput टैप, डबल-टैप और लंबे प्रेस के लिए detectTapGestures, तथा पिंच-टू-ज़ूम और रोटेशन के लिए detectTransformGestures भी उपलब्ध कराता है।

यहाँ लंबा प्रेस स्प्रिंग-आधारित स्केल शुरू करता है और जेस्चर पहचान को Animatable के साथ मिलाता है।

@Composable
fun LongPressScale() {
    val scale = remember { Animatable(1f) }
    val scope = rememberCoroutineScope()
    Box(
        Modifier
            .graphicsLayer { scaleX = scale.value; scaleY = scale.value }
            .pointerInput(Unit) {
                detectTapGestures(
                    onLongPress = {
                        scope.launch { scale.animateTo(1.4f, spring()) }
                    },
                    onPress = {
                        tryAwaitRelease()
                        scope.launch { scale.animateTo(1f, spring()) }
                    }
                )
            }
    )
}

त्वरित जाँच

आप ऐसा ड्रैगेबल कार्ड बना रहे हैं, जिसे छोड़ने पर अपने मूल स्थान पर उछलकर लौटना चाहिए। Compose में इसका मुहावरेदार विकल्प कौन-सा संयोजन है?

पुनरावलोकन: जेस्चर और स्प्रिंग

अब आप स्वाभाविक, इंटरैक्टिव गति बना सकते हैं:

  • Animatable, animateTo / snapTo के माध्यम से इम्पेरेटिव और कॉरूटीन-आधारित नियंत्रण देता है।
  • spring को dampingRatio (उछाल) और stiffness (गति) से समायोजित किया जाता है।
  • pointerInput + detectDragGestures टच को गति में बदलते हैं; animateDecay फ़्लिंग जोड़ता है।
  • anchoredDraggable स्वाइप इंटरैक्शन के लिए निश्चित स्थानों पर स्नैप करता है।
  • rememberInfiniteTransition धड़कन और शिमर जैसे लूप वाले प्रभाव चलाता है।

Jetpack Compose में एनीमेशन का यह पाठ पूरा हुआ। अब आप मान, दृश्यता, सामग्री और जेस्चर को आत्मविश्वास से एनीमेट कर सकते हैं।

शुरुआत निःशुल्क

एआई शिक्षक के साथ Kotlin सीखें — निःशुल्क

अपने ब्राउज़र में वास्तविक कोड लिखें और चलाएँ, चौबीसों घंटे एआई शिक्षक से तुरंत सहायता पाएँ, और वेब या ऐप पर वहीं से शुरू करें जहाँ आपने छोड़ा था।

पाठ्यक्रम
36
पाठ
152

अक्सर पूछे जाने वाले प्रश्न

क्या “जेस्चर और स्प्रिंग एनीमेशन” पाठ निःशुल्क है?

हाँ — Android Academy अध्ययन पथ के 3 तक कोई भी पाठ, जिसमें “जेस्चर और स्प्रिंग एनीमेशन” भी शामिल है, यहाँ वेब पर पूरा पढ़ना निःशुल्क है। इसके बाद CoddyKit PRO हर पाठ अनलॉक करता है, साथ ही अंतर्निर्मित कोड संपादक और चौबीसों घंटे एआई शिक्षक के साथ इंटरैक्टिव अभ्यास भी उपलब्ध कराता है। Android Academy पाठ्यक्रम में कुल 4 पाठ शामिल हैं।

“जेस्चर और स्प्रिंग एनीमेशन” में मैं क्या सीखूँगा?

प्राकृतिक, भौतिकी-आधारित गति। आप ब्राउज़र में सीधे चलाए जाने वाले व्यावहारिक कोड के साथ Android Academy का अभ्यास करते हैं, और पाठ पूरा करते समय 24/7 एआई ट्यूटर आपके प्रश्नों के उत्तर देता है।

क्या Android Academy शुरू करने के लिए मुझे किसी अनुभव की आवश्यकता है?

पहले के अनुभव की आवश्यकता नहीं है। CoddyKit पर Android Academy शुरुआती से लेकर उन्नत शिक्षार्थियों तक सभी के लिए व्यवस्थित किया गया है, इसलिए आप यहीं से या शुरुआत से सीखना शुरू कर सकते हैं और अपनी गति से आगे बढ़ सकते हैं। यह 4 में से 4वाँ पाठ है।

“जेस्चर और स्प्रिंग एनीमेशन” पाठ पूरा करने में कितना समय लगता है?

CoddyKit का अधिकांश पाठ लगभग 5–10 मिनट में पूरा हो जाता है। हर पाठ छोटा और संवादात्मक है, इसलिए आप लगातार प्रगति करते हैं और वेब या ऐप पर वहीं से सीखना जारी रख सकते हैं जहाँ आपने छोड़ा था।

क्या मैं इस Android Academy पाठ में कोड लिख और चला सकता हूँ?

हाँ। हर Android Academy पाठ में एक अंतर्निर्मित कोड संपादक शामिल है, जिससे आप सीधे अपने ब्राउज़र में वास्तविक कोड लिख और चला सकते हैं और तुरंत एआई प्रतिक्रिया पा सकते हैं—स्थानीय सेटअप की आवश्यकता नहीं है।

इस पाठ्यक्रम के सभी पाठ

  1. एनीमेशन क्यों महत्वपूर्ण हैं
  2. animate*AsState की मूल बातें
  3. AnimatedVisibility और ट्रांज़िशन
  4. जेस्चर और स्प्रिंग एनीमेशन
← Android Academy पर वापस जाएँ