অ্যানিমেশন কাস্টমাইজ করা

অনেক অ্যানিমেশন 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 শুরু ও শেষ ভ্যালুর মধ্যে ফিজিক্স-ভিত্তিক অ্যানিমেশন তৈরি করে। এতে ২টি প্যারামিটার লাগে: 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-এর সাথে ইজিং কার্ভ ব্যবহার করে শুরু ও শেষের মানের মধ্যে অ্যানিমেট করুন

tween ইজিং কার্ভ ব্যবহার করে নির্দিষ্ট durationMillis-এর উপর শুরু ও শেষের মানের মধ্যে অ্যানিমেট করে। tween হল between শব্দের সংক্ষিপ্ত রূপ - কারণ এটি দুটি ভ্যালুর মধ্যে থাকে।

অ্যানিমেশন শুরু করার সময় পিছিয়ে দিতে আপনি delayMillis নির্দিষ্ট করতে পারেন।

val value by animateFloatAsState(
    targetValue = 1f,
    animationSpec = tween(
        durationMillis = 300,
        delayMillis = 50,
        easing = LinearOutSlowInEasing
    ),
    label = "tween delay"
)

আরও তথ্যের জন্য ইজিং দেখুন।

keyframes-এর সাহায্যে নির্দিষ্ট সময়ে নির্দিষ্ট ভ্যালুতে অ্যানিমেট করুন

অ্যানিমেশনের সময়সীমার মধ্যে বিভিন্ন টাইমস্ট্যাম্পে নির্দিষ্ট করা স্ন্যাপশট ভ্যালুর উপর ভিত্তি করে keyframes অ্যানিমেট করে। যেকোনও সময়ে, অ্যানিমেশনের মান দুটি কীফ্রেম মানের মধ্যে ইন্টারপোলেট করা হবে। এইসব কীফ্রেমের প্রতিটির জন্য, ইন্টারপোলেশন কার্ভ নির্ধারণ করতে ইজিং নির্দিষ্ট করা যেতে পারে।

০ মিলিসেকেন্ডে এবং সময়সীমার সময়ে ভ্যালু উল্লেখ করা ঐচ্ছিক। আপনি যদি এইসব ভ্যালু নির্দিষ্ট না করেন, তাহলে সেগুলি ডিফল্ট হিসেবে যথাক্রমে অ্যানিমেশনের শুরু ও শেষের ভ্যালু হিসেবে সেট করা হয়।

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

স্প্লাইন-ভিত্তিক কীফ্রেমগুলি স্ক্রিনে আইটেমের 2D মুভমেন্টের জন্য বিশেষভাবে উপযোগী।

নিম্নলিখিত ভিডিওতে keyframes এবং keyframesWithSpline-এর মধ্যে পার্থক্য দেখানো হয়েছে, যেখানে বৃত্তের অনুসরণ করার জন্য x, y স্থানাঙ্কের একই সেট দেওয়া হয়েছে।

keyframes keyframesWithSplines

আপনি দেখতে পাচ্ছেন যে স্প্লাইন-ভিত্তিক কীফ্রেমগুলি পয়েন্টের মধ্যে আরও মসৃণ ট্রানজিশন অফার করে, কারণ তারা আইটেমগুলির মধ্যে মসৃণভাবে অ্যানিমেট করার জন্য বেজিয়ার কার্ভ ব্যবহার করে। এই স্পেসিফিকেশন প্রিসেট অ্যানিমেশনের জন্য উপযোগী। তবে, আপনি যদি ব্যবহারকারী-চালিত পয়েন্ট নিয়ে কাজ করেন, তাহলে পয়েন্টের মধ্যে একই ধরনের মসৃণতা অর্জন করতে স্প্রিং ব্যবহার করা ভালো কারণ সেগুলি ইন্টারাপ্ট করা যায়।

repeatable-এর সাথে অ্যানিমেশন রিপিট করুন

repeatable নির্দিষ্ট করা ইটারেশন কাউন্টে না পৌঁছানো পর্যন্ত সময়কাল-ভিত্তিক অ্যানিমেশন (যেমন tween বা keyframes) বারবার রান করে। অ্যানিমেশনটি শুরু থেকে (RepeatMode.Restart) নাকি শেষ থেকে (RepeatMode.Reverse) পুনরাবৃত্তি করা উচিত তা নির্দিষ্ট করতে আপনি repeatMode প্যারামিটারটি পাস করতে পারেন।

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 ব্যবহার করে অ্যানিমেশনের ভগ্নাংশ অ্যাডজাস্ট করে। এটি অ্যানিমেটিং ভ্যালুকে ধ্রুবক হারে সরানোর পরিবর্তে দ্রুত এবং ধীর করতে দেয়। ভগ্নাংশ হল ০ (শুরু) এবং ১.০ (শেষ)-এর মধ্যে একটি মান যা অ্যানিমেশনের বর্তমান পয়েন্ট নির্দেশ করে।

ইজিং আসলে একটি ফাংশন যা ০ এবং ১.০-এর মধ্যে একটি ভগ্নাংশ মান নেয় এবং একটি ফ্লোট রিটার্ন করে। ফেরত দেওয়া ভ্যালু সীমার বাইরে হতে পারে যা ওভারশুট বা আন্ডারশুটকে দেখায়। নিচে দেখানো কোডের মতো কাস্টম ইজিং তৈরি করা যেতে পারে।

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 ফাংশন আছে যা বেশিরভাগ ব্যবহারের ক্ষেত্রে কাজে লাগে। আপনার পরিস্থিতির উপর নির্ভর করে কোন ইজিং ব্যবহার করবেন সেই সম্পর্কে আরও তথ্যের জন্য স্পিড - মেটেরিয়াল ডিজাইন দেখুন।

AnimationVector-এ এবং থেকে কনভার্ট করে কাস্টম ডেটার ধরন অ্যানিমেট করুন

বেশিরভাগ Compose অ্যানিমেশন API ডিফল্ট হিসেবে অ্যানিমেশন ভ্যালু হিসেবে Float, Color, Dp এবং অন্যান্য বেসিক ডেটা টাইপ সাপোর্ট করে, তবে কখনও কখনও আপনাকে কাস্টম ডেটা টাইপ সহ অন্যান্য ডেটা টাইপ অ্যানিমেট করতে হতে পারে। অ্যানিমেশন চলাকালীন, যেকোনও অ্যানিমেটিং ভ্যালু AnimationVector হিসেবে দেখানো হয়। ভ্যালুটি AnimationVector-এ কনভার্ট করা হয় এবং TwoWayConverter-এর মাধ্যমে এর বিপরীতটি করা হয় যাতে কোর অ্যানিমেশন সিস্টেম এগুলি একইরকমভাবে ম্যানেজ করতে পারে। যেমন, একটি 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 তৈরি করে 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 অন্তর্ভুক্ত আছে: