মূল বিষয়
Timeline একটি অ্যানিমেশন সময় মডেল যা নির্ধারণ করে কখন একটি অ্যানিমেশন শুরু হয়, এটি কতক্ষণ স্থায়ী হয় এবং সময়ের অগ্রগতি কীভাবে অ্যানিমেটেড প্যারামিটারের পরিবর্তনে রূপান্তরিত হয়। ফ্রেম-বাই-ফ্রেম অ্যানিমেশনের বিপরীতে, যেখানে প্রতিটি ফ্রেম ম্যানুয়ালি সেট করা হয়, টাইমলাইন অ্যানিমেশন প্যারামিটার দ্বারা বর্ণিত হয়: duration — মোট সময়কাল, startDelay — শুরুর আগে বিলম্ব, repeatCount — পুনরাবৃত্তির সংখ্যা, এবং timingFunction — গতি বক্ররেখা।
টাইমলাইন সাধারণীকৃত স্থান [0, 1] — স্থানীয় সময় বা অগ্রগতিতে কাজ করে। শূন্য মান অ্যানিমেশনের শুরুর সাথে মিলে যায়, এক সম্পূর্ণতার সাথে। একটি ইজিং ফাংশন রৈখিক স্থানীয় সময়কে প্রকৃত অ্যানিমেশন অগ্রগতিতে রূপান্তর করে। যদি repeatCount > 1 হয়, টাইমলাইন চক্রাকারে ঘুরে (RESTART) বা উল্টে যায় (REVERSE)। iOS-এ, CAMediaTiming speed (প্লেব্যাক হার, >1 গতি বাড়ায়) এবং timeOffset (টাইমলাইন স্থানান্তর) যোগ করে। Android-এ, Animator সরাসরি টাইমলাইন অবস্থান নিয়ন্ত্রণের জন্য setCurrentPlayTime() ব্যবহার করে। Material Design অনুসারে, 100 ms-এর চেয়ে ছোট অ্যানিমেশনগুলি অ্যানিমেশন হিসাবে ধরা পড়ে না, যখন 500 ms-এর বেশি দীর্ঘ অ্যানিমেশনগুলি বিরক্তিকর হতে শুরু করে। ইন্টারফেস অ্যানিমেশনের জন্য অনুকূল সময়কাল 200–350 ms।
iOS-এ, অ্যানিমেশন টাইমলাইন ব্যবস্থাপনা CAMediaTiming প্রোটোকলের মাধ্যমে পরিচালিত হয়, যা CAAnimation এবং CALayer দ্বারা বাস্তবায়িত হয়। এটি বৈশিষ্ট্য প্রদান করে: duration (সেকেন্ডে), beginTime (প্যারেন্ট টাইমলাইনের সাপেক্ষে শুরুর সময়), repeatCount (পুনরাবৃত্তির সংখ্যা), repeatDuration (মোট পুনরাবৃত্তি সময়কাল), autoreverses (স্বয়ংক্রিয় বিপরীত), fillMode (অ্যানিমেশনের আগে/পরে আচরণ), speed (প্লেব্যাক হার), এবং timeOffset (টাইমলাইন স্থানান্তর)।
CACurrentMediaTime() একটি ফাংশন যা ডিভাইসের শেষ রিবুট থেকে সেকেন্ডে পরম সময় ফেরত দেয়। এটি একাধিক অ্যানিমেশন সিঙ্ক্রোনাইজ করার জন্য বেস টাইমস্ট্যাম্প হিসাবে ব্যবহৃত হয়: সঠিক বিলম্বের সাথে অ্যানিমেশনের একটি গ্রুপ শুরু করতে beginTime = CACurrentMediaTime() + offset সেট করুন। CAMediaTiming টাইমলাইন শ্রেণিবিন্যাসও সমর্থন করে — একটি প্যারেন্ট লেয়ার speed বৈশিষ্ট্যের মাধ্যমে সমস্ত চাইল্ড অ্যানিমেশন দ্রুত/ধীর করতে পারে। UIKit-এ, UIViewPropertyAnimator (iOS 10+) duration, delay বৈশিষ্ট্য এবং startAnimation/pauseAnimation/stopAnimation কলব্যাকের মাধ্যমে টাইমলাইনকে বিমূর্ত করে। SwiftUI-তে, Animation স্ট্রাকচার অ্যানিমেশন স্পেসিফিকেশনের অংশ হিসাবে duration প্রদান করে, কিন্তু সরাসরি টাইমলাইন নিয়ন্ত্রণ লুকানো থাকে — কাস্টম টাইমলাইনের জন্য কাস্টম scheduler সহ TimelineView (iOS 15+) ব্যবহার করুন।
Android-এ, টাইমলাইন ব্যবস্থাপনা Animator ক্লাস এবং এর সাবক্লাস (ValueAnimator, ObjectAnimator) এ কেন্দ্রীভূত। প্রধান টাইমলাইন বৈশিষ্ট্য: duration (মিলিসেকেন্ডে), startDelay (শুরুর আগে বিলম্ব), repeatCount (পুনরাবৃত্তির সংখ্যা), repeatMode (RESTART বা REVERSE)। setCurrentPlayTime(long) পদ্ধতি টাইমলাইনের যেকোনো অবস্থানে নেভিগেট করার অনুমতি দেয়।
ValueAnimator একটি বিমূর্ত স্তর যোগ করে: এটি duration-এর উপর ভিত্তি করে 0 থেকে 1 (সাধারণীকৃত সময়) মান তৈরি করে এবং সেগুলি TimeInterpolator-এ প্রেরণ করে। AnimatorSet ক্রমিক (playSequentially) বা সমান্তরাল (playTogether) নির্বাহের সাথে একাধিক Animator-কে একটি একক টাইমলাইনে একত্রিত করার অনুমতি দেয়। Jetpack Compose-এ, টাইমলাইন AnimationSpec-এর মাধ্যমে পরিচালিত হয়: tween (durationMillis, delayMillis, easing), spring (dampingRatio, stiffness), এবং keyframes (প্রতিটি সেগমেন্টের জন্য কাস্টম easing সহ টাইমলাইনের বিন্দু)। Compose AnimatedContent transitionSpec-এর জন্য টাইমলাইন ব্যবহার করে — ডেভেলপার বর্ণনা করে কিভাবে সময় অফসেট সহ বিষয়বস্তু প্রদর্শিত/অদৃশ্য হয়। Android Performance অনুসারে, 60fps-এর জন্য অ্যানিমেশন টাইমলাইন 16 ms (vsync চক্র) এর গুণিতক হওয়া উচিত — ভুল সময়কাল ডিসপ্লে রিফ্রেশ হারের সাথে অমিলের কারণে ফ্রেম ড্রপের কারণ হতে পারে।
একাধিক অ্যানিমেশন কম্পোজ করার সময় টাইমলাইন বিশেষভাবে গুরুত্বপূর্ণ হয়ে ওঠে। তিনটি মৌলিক প্যাটার্ন: ক্যাসকেড — অ্যানিমেশনগুলি অফসেট সহ ক্রমিকভাবে শুরু হয় (প্রতিটি পরবর্তীটি আগেরটি থেকে অফসেটের পরে শুরু হয়), সমান্তরাল — সমস্ত অ্যানিমেশন একই টাইমলাইনের সাথে একই সাথে শুরু হয়, এবং স্ট্যাগার — অ্যানিমেশনগুলি ওভারল্যাপ সহ শুরু হয় (দ্বিতীয়টি প্রথমটি সম্পূর্ণ হওয়ার আগে শুরু হয়)।
iOS-এ, ক্যাসকেড প্রতিটি CAAnimation-এর beginTime = পূর্ববর্তী beginTime + পূর্ববর্তী duration-এর মাধ্যমে বাস্তবায়িত হয়। স্ট্যাগারের জন্য, নেস্টেড অ্যানিমেশনে বিভিন্ন beginTime মান সহ CAAnimationGroup ব্যবহার করা হয়। Android-এ, AnimatorSet playSequentially এবং playTogether সমর্থন করে; প্রতিটি Animator-এর জন্য startDelay সেট করে স্ট্যাগার তৈরি করা হয়। Compose-এ, AnimatedVisibility enter/exitTransition সহ তালিকা আইটেমের ক্যাসকেডিং প্রদর্শনের জন্য staggerChildren ভেরিয়েন্টে স্ট্যাগার ব্যবহার করে। WWDC এবং Google I/O 2024-এ, উভয় প্ল্যাটফর্ম টাইমলাইন ভিজুয়ালাইজেশন টুল চালু করেছে: Xcode Animations Inspector এবং Android Studio Animations Timeline — এগুলি রিয়েল টাইমে প্রকৃত টাইমলাইন এবং ড্রপ করা ফ্রেম দেখায়।
কাস্টম টাইমলাইন সহ অ্যানিমেশনের একটি উদাহরণ: 0.3 সেকেন্ড বিলম্ব, 0.6 সেকেন্ড সময়কাল, অটোরিভার্স এবং অসীম পুনরাবৃত্তি। CAMediaTiming সমস্ত সময়ের প্যারামিটার নিয়ন্ত্রণ করে।
import UIKit
func breathingAnimation(layer: CALayer) {
let animation = CABasicAnimation(keyPath: "opacity")
animation.duration = 0.6
animation.beginTime = CACurrentMediaTime() + 0.3
animation.fromValue = 1.0
animation.toValue = 0.3
animation.autoreverses = true
animation.repeatCount = .infinity
animation.speed = 1.0
animation.fillMode = .both
layer.add(animation, forKey: "breathing")
}
beginTime = CACurrentMediaTime() + 0.3 একটি 300 ms বিলম্ব প্রদান করে। autoreverses = true প্রতিটি চক্রের পরে অ্যানিমেশনটিকে বিপরীতে চালায়। repeatCount = .infinity “শ্বাস” প্রভাবের একটি অসীম লুপ তৈরি করে। speed = 1.0 — সাধারণ গতি; 2.0 মান দিয়ে অ্যানিমেশনটি 2x গতি বাড়ান।
SwiftUI TimelineView (iOS 15+) কাস্টম অ্যানিমেশনের জন্য সিস্টেম টাইমলাইনে অ্যাক্সেস প্রদান করে। ভিউ প্রতিটি scheduler টিকে আপডেট হয়।
import SwiftUI
struct TimelineViewExample: View {
var body: some View {
TimelineView(.periodic(from: .now, by: 0.1)) { context in
let seconds = context.date.timeIntervalSinceReferenceDate
let phase = sin(seconds * 2 * .pi)
Circle()
.fill(Color.blue)
.frame(width: 60 + 30 * phase)
.animation(.linear(duration: 0), value: phase)
}
}
}
TimelineView .periodic scheduler সহ প্রতি 0.1 সেকেন্ডে টিক তৈরি করে। ক্লোজারে, context.date বর্তমান সময়, যা সাইন ওয়েভ ফেজে রূপান্তরিত হয়। বৃত্তের আকার 1 Hz ফ্রিকোয়েন্সিতে স্পন্দিত হয়। TimelineView হল Animation API ছাড়া SwiftUI-তে নিজস্ব টাইমলাইন সহ অ্যানিমেশন তৈরি করার একমাত্র উপায়।
সম্পূর্ণ টাইমলাইন নিয়ন্ত্রণ সহ ValueAnimator: বিলম্ব, সময়কাল, পুনরাবৃত্তি। setCurrentPlayTime পদ্ধতি টাইমলাইন বরাবর লাফ দেওয়ার অনুমতি দেয়।
import android.animation.ValueAnimator
import android.view.animation.AccelerateDecelerateInterpolator
import android.view.View
fun View.timelineAnimation() {
ValueAnimator.ofFloat(0f, 1f).apply {
duration = 400
startDelay = 200
repeatCount = 2
repeatMode = ValueAnimator.REVERSE
interpolator = AccelerateDecelerateInterpolator()
addUpdateListener { animator ->
val progress = animator.animatedFraction
alpha = progress
translationX = progress * 100f
}
start()
}
}
startDelay = 200 ms — শুরুর আগে বিলম্ব। repeatMode = REVERSE অ্যানিমেশনটিকে প্রাথমিক মানে ফিরিয়ে দেয়। animatedFraction repeatMode বিবেচনা করে 0 থেকে 1 পর্যন্ত অগ্রগতি দেয়। addUpdateListener প্রতিটি ফ্রেমে (সাধারণত 16 ms) ফায়ার হয়। বিরাম দেওয়ার জন্য pause() / resume() ব্যবহার করুন।
AnimatorSet একাধিক অ্যানিমেশন থেকে জটিল টাইমলাইন তৈরি করার অনুমতি দেয়। উদাহরণটি ওভারল্যাপ (স্ট্যাগার) সহ ক্রমিক নির্বাহ প্রদর্শন করে।
import android.animation.AnimatorSet
import android.animation.ObjectAnimator
import android.view.View
fun View.staggerAnimation() {
val fadeIn = ObjectAnimator.ofFloat(this, "alpha", 0f, 1f).apply {
duration = 300
}
val slideUp = ObjectAnimator.ofFloat(this, "translationY", 100f, 0f).apply {
duration = 400
startDelay = 100
}
val scale = ObjectAnimator.ofFloat(this, "scaleX", 0.8f, 1f).apply {
duration = 250
startDelay = 200
}
AnimatorSet().apply {
playTogether(fadeIn, slideUp, scale)
start()
}
}
playTogether সমস্ত অ্যানিমেশন সমান্তরালভাবে শুরু করে, কিন্তু প্রতিটির নিজস্ব startDelay রয়েছে — এটি একটি স্ট্যাগার প্রভাব তৈরি করে: fadeIn প্রথমে শুরু হয় (0 ms), slideUp 100 ms পরে, scale 200 ms পরে। ফলস্বরূপ টাইমলাইন: 0 — 100 — 200 — 600 ms। ক্রমিক নির্বাহের জন্য, playSequentially ব্যবহার করুন।
সচরাচর জিজ্ঞাসিত প্রশ্ন
Animator হল সমস্ত অ্যানিমেশনের জন্য একটি বিমূর্ত বেস ক্লাস। ValueAnimator হল এর সাবক্লাস যা কোনো বস্তুর সাথে আবদ্ধ না হয়ে সংখ্যাসূচক মান অ্যানিমেট করে। ObjectAnimator (ValueAnimator-এর সাবক্লাস) একটি বস্তুর নির্দিষ্ট বৈশিষ্ট্য (যেমন alpha বা translationY) অ্যানিমেট করে। টাইমলাইনের জন্য, addUpdateListener-এর মাধ্যমে কলব্যাক সহ ValueAnimator-কে একটি সার্বজনীন টাইমার হিসাবে ব্যবহার করুন।
অগ্রগতি গণনার জন্য ফ্রেম সংখ্যার পরিবর্তে সিস্টেম ঘড়ি (iOS-এ CACurrentMediaTime, Android-এ System.nanoTime) ব্যবহার করুন। নেটওয়ার্ক সিঙ্ক্রোনাইজেশনের জন্য, অফসেট সংশোধন সহ NTP-ভিত্তিক টাইমার ব্যবহার করুন। iOS মিলিসেকেন্ড নির্ভুলতার সাথে অডিও-ভিডিও টাইমলাইন সিঙ্ক্রোনাইজেশনের জন্য AVAudioSession সমর্থন করে। ফ্রেম-ভিত্তিক সিঙ্ক্রোনাইজেশন এড়িয়ে চলুন — ফ্রেম রেট 30 থেকে 120 fps পর্যন্ত পরিবর্তিত হয়।
startOffset হল মিলিসেকেন্ডে অ্যানিমেশন শুরুর আগে বিলম্ব। ক্যাসকেড এবং স্ট্যাগার প্রভাবের জন্য ব্যবহৃত। repeatCount হল পুনরাবৃত্তির সংখ্যা: 0 = কোন পুনরাবৃত্তি নয়, ValueAnimator.INFINITE = অসীম লুপ। repeatMode দিক নির্ধারণ করে: RESTART (শুরুতে রিসেট) বা REVERSE (বিপরীত দিক)। iOS-এ, startOffset-কে beginTime বলা হয় (CACurrentMediaTime-এর সাথে সমন্বয়ে), repeatCount হল CABasicAnimation-এর একই বৈশিষ্ট্য।
Material Design ইন্টারফেস অ্যানিমেশনের জন্য 200–350 ms সুপারিশ করে। 100 ms-এর চেয়ে ছোট অ্যানিমেশনগুলি অ্যানিমেশন হিসাবে ধরা পড়ে না, যখন 500 ms-এর বেশি দীর্ঘ অ্যানিমেশনগুলি বিরক্তিকর। উপাদানের প্রবেশ/প্রস্থানের জন্য: 200–300 ms। স্ক্রিনের মধ্যে পরিবর্তনের জন্য: 300–400 ms। ছোট উপাদানের জন্য ছোট সময়কাল (100–200 ms) এবং বড় উপাদানের জন্য দীর্ঘ সময়কাল (400–500 ms) ব্যবহার করুন।
ঝাঁকুনি (jank) নিম্নলিখিত কারণে ঘটে: প্রধান থ্রেডে দীর্ঘস্থায়ী অপারেশন (রেন্ডারিং ব্লক করা), ওভারড্র সহ জটিল View/Layer শ্রেণিবিন্যাস, বা ভুল টাইমলাইন ব্যবহার (সময়কাল vsync-এর গুণিতক নয় — 60fps-এর জন্য 16ms, 120fps-এর জন্য 8ms)। ড্রপ করা ফ্রেম সনাক্ত করতে Xcode Instruments Animations বা Android Studio Profiler ব্যবহার করুন। Compose-এ, জটিল অঙ্কন ক্যাশ করতে Modifier.drawWithCache ব্যবহার করুন।
সারাংশ
আমরা একটি মোবাইল অ্যাপ্লিকেশন টার্নকি তৈরি করব
IT Sectr 2017 সাল থেকে স্টার্টআপ এবং ব্যবসার জন্য iOS এবং Android অ্যাপ্লিকেশন তৈরি করে। আমরা আপনাকে পরামর্শ দেব এবং সেরা সমাধান প্রস্তাব করব।
আরও পড়ুন