Timeline — basis, beheer van animatietijd in apps

Auteur: IT Sectr Gepubliceerd: 2026-03-02 Leestijd: 8 min
Timeline (tijdlijn) — een fundamenteel concept van animatie dat bepaalt hoe lang een animatie duurt, in welke volgorde de fasen worden uitgevoerd en hoe tijd wordt weerspiegeld in de voortgang. In de ontwikkeling van mobiele apps wordt de timeline beheerd via duur (duration), vertraging (delay), herhaling (repeat) en tijdstempels. In iOS wordt de animatie-timeline geïmplementeerd via CACurrentMediaTime en CAMediaTiming, in Android — via ValueAnimator en Animator met parameters duration, startDelay en repeatCount. Volgens Apple Documentatie is nauwkeurig beheer van de tijdlijn cruciaal voor synchronisatie van animaties: desynchronisatie van zelfs 16 ms (één frame bij 60fps) wordt door de gebruiker ervaren als schokkerigheid. Bij IT Sectr hebben we het gebruik van de timeline gestandaardiseerd via ValueAnimator in Android en CABasicAnimation met CAMediaTiming in iOS — dit zorgt voor uniform tijdbeheer in alle projecten.

Belangrijkste

  • Timeline — concept van tijdbeheer in animatie: duration, delay, repeat, weerspiegeling van tijd in voortgang.
  • CAMediaTiming — iOS Core Animation protocol voor timeline-beheer: duration, beginTime, repeatCount, speed, timeOffset.
  • ValueAnimator — centrale Android-klasse voor het werken met de animatie-tijdlijn via duration, startDelay, repeatCount.
  • CACurrentMediaTime — iOS-functie voor het verkrijgen van absolute tijd in seconden, gebruikt voor synchronisatie.
  • TimeInterval — gegevenstype in iOS (Double) dat een tijdsinterval voor animatieberekeningen vertegenwoordigt.

Wat is een Timeline?

Timeline — is een tijdsmodel van animatie dat bepaalt wanneer een animatie begint, hoe lang deze duurt en hoe het verloop van de tijd wordt omgezet in een verandering van de geanimeerde parameter. In tegenstelling tot frame-voor-frame animatie (frame-by-frame), waarbij elk frame handmatig wordt ingesteld, wordt timeline-animatie beschreven met parameters: duration — totale duur, startDelay — vertraging voor start, repeatCount — aantal herhalingen, en timingFunction — snelheidscurve.

De tijdlijn werkt in een genormaliseerde ruimte [0, 1] — local time of progress. De waarde nul komt overeen met het begin van de animatie, één met het einde. De easing-functie zet lineaire local time om in werkelijke animatievoortgang. Als repeatCount > 1 is, wordt de timeline cyclisch gereset (RESTART) of omgekeerd (REVERSE). In iOS voegt CAMediaTiming parameters speed (afspeelsnelheid, >1 versnelt) en timeOffset (verschuiving van de tijdlijn) toe. In Android gebruikt Animator setCurrentPlayTime() voor direct beheer van de positie op de tijdlijn. Volgens Material Design worden animaties korter dan 100 ms niet als animatie waargenomen, en langer dan 500 ms — beginnen te irriteren. De optimale duur voor interface-animaties is 200–350 ms.

Timeline in iOS: CAMediaTiming en CACurrentMediaTime

In iOS wordt het beheer van de animatie-tijdlijn uitgevoerd via het protocol CAMediaTiming, dat wordt geïmplementeerd door CAAnimation en CALayer. Het biedt de eigenschappen: duration (duur in seconden), beginTime (starttijd ten opzichte van de bovenliggende timeline), repeatCount (aantal herhalingen), repeatDuration (totale duur van herhalingen), autoreverses (automatische omgekeerde beweging), fillMode (gedrag voor/na animatie), speed (afspeelsnelheid) en timeOffset (verschuiving op de as).

CACurrentMediaTime() — functie die de absolute tijd in seconden teruggeeft sinds de laatste herstart van het apparaat. Gebruikt als basistijdstempel voor synchronisatie van meerdere animaties: stel beginTime = CACurrentMediaTime() + offset in om een groep animaties met exacte vertraging te starten. CAMediaTiming ondersteunt ook de hiërarchie van timeline — de bovenliggende laag kan alle onderliggende animaties versnellen/vertragen via de eigenschap speed. In UIKit abstraheert UIViewPropertyAnimator (iOS 10+) de tijdlijn via de eigenschappen duration, delay en callbacks startAnimation/pauseAnimation/stopAnimation. In SwiftUI biedt de structuur Animation duration als onderdeel van de animatiespecificatie, maar direct beheer van de tijdlijn is verborgen — voor een aangepaste timeline gebruikt u TimelineView (iOS 15+) met uw eigen scheduler.

Timeline in Android: Animator en duration

In Android is het beheer van de tijdlijn gecentraliseerd in de klasse Animator en zijn subklassen (ValueAnimator, ObjectAnimator). De belangrijkste eigenschappen van de timeline: duration (duur in milliseconden), startDelay (vertraging voor start), repeatCount (aantal herhalingen), repeatMode (RESTART of REVERSE). De methode setCurrentPlayTime(long) maakt het mogelijk om naar elke gewenste positie op de tijdlijn te gaan.

ValueAnimator voegt een abstractielaag toe: het genereert waarden van 0 tot 1 (normalized time) op basis van duration en geeft ze door aan TimeInterpolator. AnimatorSet maakt het mogelijk om meerdere Animator-objecten te combineren in één tijdlijn met sequentiële (playSequentially) of parallelle (playTogether) uitvoering. In Jetpack Compose wordt de tijdlijn beheerd via AnimationSpec: tween (durationMillis, delayMillis, easing), spring (dampingRatio, stiffness) en keyframes (punten op de tijdlijn met aangepaste easing voor elk segment). Compose AnimatedContent gebruikt de timeline voor transitionSpec — de ontwikkelaar beschrijft hoe inhoud verschijnt/verdwijnt met tijdsverschuivingen. Volgens Android Performance moet de animatie-tijdlijn een veelvoud zijn van 16 ms (vsync-cyclus) voor 60fps — een onjuiste duur kan frameverlies veroorzaken door incompatibiliteit met de verversingssnelheid van het scherm.

Compositie van animaties in de tijd

De tijdlijn wordt vooral belangrijk bij de compositie van meerdere animaties. Drie basispatronen: cascade — animaties worden sequentieel gestart met een verschuiving (elke volgende begint na een offset van de vorige), parallel — alle animaties worden gelijktijdig gestart met dezelfde timeline, en stagger — animaties worden met overlapping gestart (de tweede begint voordat de eerste is afgelopen).

In iOS wordt de cascade geïmplementeerd via beginTime van elke CAAnimation = vorige beginTime + vorige duration. Voor stagger wordt CAAnimationGroup gebruikt met verschillende beginTime in geneste animaties. In Android ondersteunt AnimatorSet playSequentially en playTogether; stagger wordt gecreëerd door startDelay in te stellen voor elke Animator. In Compose gebruikt AnimatedVisibility met enter/exitTransition stagger in de variant staggerChildren voor het trapsgewijs verschijnen van lijstelementen. Op WWDC en Google I/O 2024 presenteerden beide platforms tools voor timeline-visualisatie: Xcode Animations Inspector en Android Studio Animations Timeline — ze tonen de werkelijke tijdlijn en overgeslagen frames in realtime.

Codevoorbeelden

iOS: CABasicAnimation met CAMediaTiming

Voorbeeld van een animatie met aangepaste timeline: vertraging 0,3 sec, duur 0,6 sec, autoreverse en oneindige herhaling. CAMediaTiming beheert alle tijdelijke parameters.

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 geeft een vertraging van 300 ms. autoreverses = true zorgt dat de animatie na elke cyclus in tegengestelde richting gaat. repeatCount = .infinity creëert een oneindige lus van het “adembalend” effect. speed = 1,0 — normale snelheid; versnel de animatie 2 keer met waarde 2,0.

iOS: TimelineView voor aangepaste tijdlijn

SwiftUI TimelineView (iOS 15+) biedt toegang tot de systeem-timeline voor aangepaste animatie. De weergave wordt bij elke tik van de scheduler bijgewerkt.

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 met .periodic scheduler genereert ticks elke 0,1 sec. In de closure, context.date — de huidige tijd die wordt omgezet in de fase van een sinusoïde. De grootte van de cirkel pulseert met een frequentie van 1 Hz. TimelineView is de enige manier om een animatie met een eigen tijdlijn te maken in SwiftUI zonder Animation API.

Android: ValueAnimator met aangepaste timeline

ValueAnimator met volledig beheer van de tijdlijn: vertraging, duur, herhaling. De methode setCurrentPlayTime maakt springen op de tijdlijn mogelijk.

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 — vertraging voor start. repeatMode = REVERSE brengt de animatie terug naar de beginwaarde. animatedFraction geeft de voortgang van 0 tot 1, rekening houdend met repeatMode. addUpdateListener wordt elk frame aangeroepen (meestal 16 ms). Gebruik pause() / resume() om te pauzeren.

Android: AnimatorSet voor compositie van timeline

AnimatorSet maakt het mogelijk om complexe tijdlijnen te maken van meerdere animaties. In het voorbeeld — sequentiële uitvoering met overlapping (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 start alle animaties parallel, maar elke heeft zijn eigen startDelay — dit creëert het staggering-effect: fadeIn start als eerste (0 ms), slideUp na 100 ms, scale na 200 ms. Resulterende tijdlijn: 0 — 100 — 200 — 600 ms. Gebruik playSequentially voor sequentiële uitvoering.

Veelgestelde vragen

Wat is het verschil tussen Animator en ValueAnimator in Android?

Animator — abstracte basisklasse voor alle animaties. ValueAnimator — zijn subklasse die numerieke waarden animeert zonder binding aan een object. ObjectAnimator (inherit van ValueAnimator) animeert een specifieke eigenschap van een object (bijv. alpha of translationY). Gebruik voor timeline ValueAnimator als universele timer met callback via addUpdateListener.

Hoe synchroniseer ik animaties op verschillende apparaten?

Gebruik systeemklokken (CACurrentMediaTime in iOS, System.nanoTime in Android) voor het berekenen van de voortgang, niet het aantal frames. Gebruik voor netwerksynchronisatie een NTP-gebaseerde timer met offsetcorrectie. iOS ondersteunt AVAudioSession voor synchronisatie van audio-video timeline met millisecondenauwkeurigheid. Vermijd synchronisatie op frames — de framerate varieert van 30 tot 120 fps.

Wat zijn startOffset en repeatCount in Animator?

startOffset — vertraging voor het begin van de animatie in milliseconden. Gebruikt voor cascade- en stagger-effecten. repeatCount — aantal herhalingen: 0 = geen herhaling, ValueAnimator.INFINITE = oneindige lus. repeatMode bepaalt de richting: RESTART (reset naar begin) of REVERSE (omgekeerde beweging). In iOS heet startOffset beginTime (in combinatie met CACurrentMediaTime), repeatCount — de gelijknamige eigenschap van CABasicAnimation.

Wat is de optimale duur van een animatie?

Material Design beveelt 200–350 ms aan voor interface-animaties. Animaties korter dan 100 ms worden niet als animatie waargenomen, langer dan 500 ms — irriteren. Voor in/uit van elementen: 200–300 ms. Voor overgangen tussen schermen: 300–400 ms. Gebruik kortere duren voor kleine elementen (100–200 ms) en langere voor grote (400–500 ms).

Waarom schokt de animatie tijdens het afspelen?

Schokkerigheid (jank) ontstaat door: langdurige bewerkingen in de hoofdthread (blokkeren rendering), complexe View/Layer-hiërarchie met overdraw, of onjuist gebruik van de timeline (duur is geen veelvoud van vsync — 16ms voor 60fps, 8ms voor 120fps). Gebruik Xcode Instruments Animations of Android Studio Profiler om overgeslagen frames te detecteren. Gebruik in Compose Modifier.drawWithCache voor caching van complexe tekeningen.

Samenvatting

  • Timeline — tijdsmodel van animatie met parameters duration, startDelay, repeatCount, repeatMode, die het verloop van de animatie bepalen.
  • iOS CAMediaTiming protocol beheert de tijdlijn via duration, beginTime, speed, timeOffset, repeatCount, fillMode.
  • Android Animator en ValueAnimator bieden duration, startDelay, repeatCount, repeatMode en setCurrentPlayTime voor direct beheer.
  • AnimatorSet in Android en CAAnimationGroup in iOS maken het mogelijk animaties te combineren in één tijdlijn.
  • TimelineView in SwiftUI (iOS 15+) biedt toegang tot de systeem-scheduler voor aangepaste tijdlijnen zonder Animation API.
  • CACurrentMediaTime() in iOS en System.nanoTime in Android — basistijdstempels voor synchronisatie van animaties.
  • Optimale duur van interface-animaties — 200-350 ms volgens aanbevelingen van Material Design en HIG.

We ontwikkelen een mobiele applicatie turnkey

IT Sectr creëert sinds 2017 iOS- en Android-applicaties voor startups en bedrijven. We adviseren u en stellen de beste oplossing voor.

Bespreek het project

Lees ook