Timeline — mga batayan, pamamahala ng oras ng animasyon sa mga aplikasyon

May-akda: IT Sectr Nai-publish: 2026-03-02 Oras ng pagbabasa: 8 min
Timeline (time line) — ang pangunahing konsepto ng animasyon na tumutukoy kung gaano katagal ang isang animasyon, sa anong pagkakasunod-sunod isinasagawa ang mga yugto nito at kung paano ang oras ay inilalarawan sa progreso. Sa pag-develop ng mga mobile application, ang timeline ay pinamamahalaan sa pamamagitan ng tagal (duration), pagkaantala (delay), pag-uulit (repeat) at mga timestamp. Sa iOS, ang timeline ng animasyon ay ipinapatupad sa pamamagitan ng CACurrentMediaTime at CAMediaTiming, sa Android — sa pamamagitan ng ValueAnimator at Animator na may mga parameter na duration, startDelay at repeatCount. Ayon sa Dokumentasyon ng Apple, ang tumpak na pamamahala ng timeline ay kritikal para sa pag-synchronize ng mga animasyon: ang desynchronization kahit na 16 ms (isang frame sa 60fps) ay nararamdaman ng gumagamit bilang pag-jerk. Sa IT Sectr, na-standardize namin ang paggamit ng timeline sa pamamagitan ng ValueAnimator sa Android at CABasicAnimation na may CAMediaTiming sa iOS — tinitiyak nito ang pare-parehong pamamahala ng oras sa lahat ng proyekto.

Mga pangunahing punto

  • Timeline — konsepto ng pamamahala ng oras ng animasyon: duration, delay, repeat, paglalarawan ng oras sa progreso.
  • CAMediaTiming — iOS Core Animation protocol para sa pamamahala ng timeline: duration, beginTime, repeatCount, speed, timeOffset.
  • ValueAnimator — sentral na klase ng Android para sa pagtatrabaho sa timeline ng animasyon sa pamamagitan ng duration, startDelay, repeatCount.
  • CACurrentMediaTime — iOS function para sa pagkuha ng absolute na oras sa segundo, ginagamit para sa pag-synchronize.
  • TimeInterval — uri ng data sa iOS (Double) na kumakatawan sa interval ng oras para sa mga kalkulasyon ng animasyon.

Ano ang Timeline?

Timeline — ay ang modelo ng oras ng animasyon na tumutukoy kung kailan magsisimula ang animasyon, gaano ito katagal at kung paano ang pagdaan ng oras ay nababago sa pagbabago ng parameter na ina-animate. Hindi tulad ng frame-by-frame na animasyon, kung saan ang bawat frame ay manu-manong itinatakda, ang timeline animation ay inilalarawan ng mga parameter: duration — kabuuang tagal, startDelay — pagkaantala bago magsimula, repeatCount — bilang ng mga pag-uulit at timingFunction — kurba ng bilis.

Ang timeline ay gumagana sa normalized na espasyo [0, 1] — local time o progress. Ang zero value ay tumutugma sa simula ng animasyon, isa — sa pagkumpleto. Ang easing function ay nagko-convert ng linear local time sa aktwal na progreso ng animasyon. Kung ang repeatCount > 1, ang timeline ay paikot na nire-reset (RESTART) o binabaligtad (REVERSE). Sa iOS, ang CAMediaTiming ay nagdaragdag ng mga parameter na speed (bilis ng pag-playback, >1 nagpapabilis) at timeOffset (paglipat ng timeline). Sa Android, ang Animator ay gumagamit ng setCurrentPlayTime() para sa direktang kontrol ng posisyon sa timeline. Ayon sa Material Design, ang mga animasyon na mas maikli sa 100 ms ay hindi napapansin bilang mga animasyon, at mas mahaba sa 500 ms — nagsisimulang makairita. Ang optimal na tagal para sa mga interface animation ay 200–350 ms.

Timeline sa iOS: CAMediaTiming at CACurrentMediaTime

Sa iOS, ang pamamahala ng timeline ng animasyon ay isinasagawa sa pamamagitan ng protocol na CAMediaTiming, na ipinapatupad ng CAAnimation at CALayer. Nagbibigay ito ng mga property: duration (tagal sa segundo), beginTime (oras ng pagsisimula kaugnay ng parent timeline), repeatCount (bilang ng pag-uulit), repeatDuration (kabuuang tagal ng pag-uulit), autoreverses (awtomatikong pagbaliktad), fillMode (pag-uugali bago/pagkatapos ng animasyon), speed (bilis ng pag-playback) at timeOffset (paglipat sa timeline).

CACurrentMediaTime() — function na nagbabalik ng absolute na oras sa segundo mula noong huling pag-restart ng device. Ginagamit bilang batayang timestamp para sa pag-synchronize ng maraming animasyon: itakda ang beginTime = CACurrentMediaTime() + offset upang ilunsad ang isang grupo ng mga animasyon na may tumpak na pagkaantala. Sinusuportahan din ng CAMediaTiming ang hierarchy ng timeline — ang parent layer ay maaaring bumilis/bagalan ang lahat ng child animation sa pamamagitan ng speed property. Sa UIKit, ang UIViewPropertyAnimator (iOS 10+) ay nag-abstrak ng timeline sa pamamagitan ng duration, delay properties at callbacks na startAnimation/pauseAnimation/stopAnimation. Sa SwiftUI, ang Animation structure ay nagbibigay ng duration bilang bahagi ng specification ng animasyon, ngunit ang direktang kontrol ng timeline ay nakatago — para sa custom na timeline gamitin ang TimelineView (iOS 15+) na may sarili mong scheduler.

Timeline sa Android: Animator at duration

Sa Android, ang pamamahala ng timeline ay sentralisado sa klase na Animator at mga subclass nito (ValueAnimator, ObjectAnimator). Ang mga pangunahing property ng timeline: duration (tagal sa millisecond), startDelay (pagkaantala bago magsimula), repeatCount (bilang ng pag-uulit), repeatMode (RESTART o REVERSE). Ang pamamaraang setCurrentPlayTime(long) ay nagpapahintulot ng paggalaw sa kahabaan ng timeline sa anumang posisyon.

Ang ValueAnimator ay nagdaragdag ng antas ng abstraction: bumubuo ng mga halaga mula 0 hanggang 1 (normalized time) batay sa duration at ipinapasa ang mga ito sa TimeInterpolator. Ang AnimatorSet ay nagpapahintulot ng pagsasama-sama ng maraming Animator sa iisang timeline na may sunud-sunod (playSequentially) o parallel (playTogether) na pagpapatupad. Sa Jetpack Compose, ang timeline ay pinamamahalaan sa pamamagitan ng AnimationSpec: tween (durationMillis, delayMillis, easing), spring (dampingRatio, stiffness) at keyframes (mga punto sa timeline na may custom na easing para sa bawat segment). Ang Compose AnimatedContent ay gumagamit ng timeline para sa transitionSpec — inilalarawan ng developer kung paano lumilitaw/nawawala ang nilalaman na may mga paglipat ng oras. Ayon sa Android Performance, ang timeline ng animasyon ay dapat na multiple ng 16 ms (vsync cycle) para sa 60fps — ang maling tagal ay maaaring magdulot ng pagkawala ng frame dahil sa hindi pagkakatugma sa refresh rate ng display.

Komposisyon ng mga animasyon sa oras

Ang timeline ay nagiging lalong mahalaga sa komposisyon ng maraming animasyon. Tatlong pangunahing pattern: kaskada — ang mga animasyon ay inilulunsad nang sunud-sunod na may paglipat (bawat susunod ay magsisimula pagkatapos ng offset mula sa nauna), parallel — lahat ng animasyon ay inilulunsad nang sabay-sabay na may parehong timeline at stagger — ang mga animasyon ay inilulunsad na may overlap (ang pangalawa ay magsisimula bago matapos ang una).

Sa iOS, ang kaskada ay ipinapatupad sa pamamagitan ng beginTime ng bawat CAAnimation = nakaraang beginTime + nakaraang duration. Para sa stagger, ginagamit ang CAAnimationGroup na may iba't ibang beginTime sa mga nested animation. Sa Android, ang AnimatorSet ay sumusuporta sa playSequentially at playTogether; ang stagger ay nilikha sa pamamagitan ng pagtatakda ng startDelay para sa bawat Animator. Sa Compose, ang AnimatedVisibility na may enter/exitTransition ay gumagamit ng stagger sa variant na staggerChildren para sa cascading na paglitaw ng mga elemento ng listahan. Sa WWDC at Google I/O 2024, ang parehong platform ay nagpakilala ng mga tool sa visualization ng timeline: Xcode Animations Inspector at Android Studio Animations Timeline — ipinapakita nila ang aktwal na timeline at mga nalaglag na frame sa real-time.

Mga halimbawa ng code

iOS: CABasicAnimation na may CAMediaTiming

Halimbawa ng animasyon na may custom na timeline: pagkaantala 0.3 segundo, tagal 0.6 segundo, autoreverse at walang katapusang pag-uulit. Ang CAMediaTiming ay namamahala sa lahat ng parameter ng oras.

swift
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 ay nagbibigay ng pagkaantala ng 300 ms. autoreverses = true ay nagiging sanhi ng animasyon na tumakbo sa reverse direksyon pagkatapos ng bawat cycle. repeatCount = .infinity ay lumilikha ng walang katapusang loop ng „paghinga" na epekto. speed = 1.0 — normal na bilis; pabilisin ang animasyon ng 2 beses sa halagang 2.0.

iOS: TimelineView para sa custom na timeline

Ang SwiftUI TimelineView (iOS 15+) ay nagbibigay ng access sa system timeline para sa custom na animasyon. Ang view ay ina-update sa bawat tick ng scheduler.

swift
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 na may .periodic scheduler ay bumubuo ng mga tick bawat 0.1 segundo. Sa closure, ang context.date — kasalukuyang oras na na-convert sa phase ng sinusoid. Ang laki ng bilog ay pumipintig na may frequency na 1 Hz. Ang TimelineView ay ang tanging paraan upang lumikha ng animasyon na may sariling timeline sa SwiftUI nang walang Animation API.

Android: ValueAnimator na may custom na timeline

ValueAnimator na may buong kontrol ng timeline: pagkaantala, tagal, pag-uulit. Ang pamamaraang setCurrentPlayTime ay nagpapahintulot ng pagtalon sa kahabaan ng timeline.

kotlin
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 — pagkaantala bago magsimula. repeatMode = REVERSE ay nagbabalik ng animasyon sa paunang halaga. Ang animatedFraction ay nagbibigay ng progreso mula 0 hanggang 1 na isinasaalang-alang ang repeatMode. Ang addUpdateListener ay nagti-trigger bawat frame (karaniwang 16 ms). Para sa pag-pause, gamitin ang pause() / resume().

Android: AnimatorSet para sa komposisyon ng timeline

Ang AnimatorSet ay nagpapahintulot ng paglikha ng mga kumplikadong timeline mula sa maraming animasyon. Sa halimbawa — sunud-sunod na pagpapatupad na may overlap (stagger).

kotlin
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 ay nagpapatakbo ng lahat ng animasyon nang parallel, ngunit bawat isa ay may sariling startDelay — ito ay lumilikha ng stagger effect: ang fadeIn ay unang nagsisimula (0 ms), slideUp pagkatapos ng 100 ms, scale pagkatapos ng 200 ms. Panghuling timeline: 0 — 100 — 200 — 600 ms. Para sa sunud-sunod na pagpapatupad, gamitin ang playSequentially.

Mga madalas itanong

Ano ang pagkakaiba ng Animator at ValueAnimator sa Android?

Ang Animator — abstract na base class para sa lahat ng animasyon. Ang ValueAnimator ay subclass nito na nag-a-animate ng mga numerikong halaga nang walang pagkakatali sa isang bagay. Ang ObjectAnimator (tagapagmana ng ValueAnimator) ay nag-a-animate ng partikular na property ng isang bagay (hal. alpha o translationY). Para sa timeline, gamitin ang ValueAnimator bilang unibersal na timer na may callback sa pamamagitan ng addUpdateListener.

Paano mag-synchronize ng mga animasyon sa iba't ibang device?

Gamitin ang mga orasan ng system (CACurrentMediaTime sa iOS, System.nanoTime sa Android) para sa pagkalkula ng progreso, hindi ang bilang ng mga frame. Para sa network synchronization, mag-apply ng NTP-based timer na may correction ng offset. Sinusuportahan ng iOS ang AVAudioSession para sa pag-synchronize ng audio-video timeline na may katumpakan ng millisecond. Iwasan ang pag-synchronize batay sa frame — ang frame rate ay nag-iiba mula 30 hanggang 120 fps.

Ano ang startOffset at repeatCount sa Animator?

startOffset — pagkaantala bago magsimula ang animasyon sa millisecond. Ginagamit para sa cascade at stagger effect. repeatCount — bilang ng pag-uulit: 0 = walang pag-uulit, ValueAnimator.INFINITE = walang katapusang loop. Ang repeatMode ay tumutukoy sa direksyon: RESTART (reset sa simula) o REVERSE (reverse na paggalaw). Sa iOS, ang startOffset ay tinatawag na beginTime (sa kombinasyon sa CACurrentMediaTime), repeatCount — ang parehong pangalan na property ng CABasicAnimation.

Ano ang optimal na tagal ng animasyon?

Inirerekomenda ng Material Design ang 200–350 ms para sa mga interface animation. Ang mga animasyon na mas maikli sa 100 ms ay hindi napapansin bilang mga animasyon, mas mahaba sa 500 ms — nakakairita. Para sa pagpasok/paglabas ng mga elemento: 200–300 ms. Para sa mga transisyon sa pagitan ng mga screen: 300–400 ms. Gumamit ng mas maikling tagal para sa maliliit na elemento (100–200 ms) at mas mahaba para sa malalaki (400–500 ms).

Bakit kumikibot ang animasyon habang nagpe-play?

Ang pagkikibot (jank) ay nangyayari dahil sa: mahabang operasyon sa pangunahing thread (humaharang sa rendering), kumplikadong hierarchy ng View/Layer na may overdraw, o maling paggamit ng timeline (tagal ay hindi multiple ng vsync — 16ms para sa 60fps, 8ms para sa 120fps). Gamitin ang Xcode Instruments Animations o Android Studio Profiler para sa pag-detect ng mga nalaglag na frame. Sa Compose, mag-apply ng Modifier.drawWithCache para sa pag-cache ng mga kumplikadong drawing.

Buod

  • Timeline — modelo ng oras ng animasyon na may mga parameter na duration, startDelay, repeatCount, repeatMode, na tumutukoy sa takbo ng animasyon.
  • Ang iOS CAMediaTiming protocol ay namamahala ng timeline sa pamamagitan ng duration, beginTime, speed, timeOffset, repeatCount, fillMode.
  • Ang Android Animator at ValueAnimator ay nagbibigay ng duration, startDelay, repeatCount, repeatMode at setCurrentPlayTime para sa direktang kontrol.
  • Ang AnimatorSet sa Android at CAAnimationGroup sa iOS ay nagpapahintulot ng pagsasama-sama ng mga animasyon sa iisang timeline.
  • Ang TimelineView sa SwiftUI (iOS 15+) ay nagbibigay ng access sa system scheduler para sa mga custom na timeline nang walang Animation API.
  • Ang CACurrentMediaTime() sa iOS at System.nanoTime sa Android — batayang timestamp para sa pag-synchronize ng mga animasyon.
  • Optimal na tagal ng mga interface animation — 200-350 ms ayon sa mga rekomendasyon ng Material Design at HIG.

Gagawa kami ng mobile application na turnkey

Gumagawa ang IT Sectr ng mga iOS at Android application para sa mga startup at negosyo mula noong 2017. Magpapayo kami sa iyo at magmumungkahi ng pinakamahusay na solusyon.

Pag-usapan ang proyekto

Basahin din