Belangrijkste punten
Easing (verzachtingsfunctie) — een wiskundige functie f(t) die het lineaire verloop van tijd t ∈ [0,1] afbeeldt op een niet-lineaire animatiewaarde. Als een animatie de positie van een object van A naar B verandert in 500 ms, bepaalt easing hoe het object tussen deze punten beweegt op elk moment. Lineaire easing (f(t) = t) betekent constante snelheid — het object beweegt mechanisch. Niet-lineaire easing — natuurlijk: het object versnelt (ease-in), vertraagt (ease-out) of heeft een vloeiend begin en einde (ease-in-out).
Easing-functies worden beschreven door kubische Bézier-curves (Cubic Bézier), waarbij de X-as de genormaliseerde tijd is en de Y-as de genormaliseerde voortgang. Twee controlepunt (P1, P2) bepalen de vorm van de curve. Standaardcurves zijn vastgelegd door de CSS-specificatie: ease (0.25, 0.1, 0.25, 1.0), ease-in (0.42, 0.0, 1.0, 1.0), ease-out (0.0, 0.0, 0.58, 1.0), ease-in-out (0.42, 0.0, 0.58, 1.0). Deze zelfde waarden worden gebruikt in CAMediaTimingFunction in iOS en PathInterpolator in Android. Volgens Material Design Motion-richtlijnen moeten easing-curves overeenkomen met de context: voor verschijnen — ease-out (snelle start), voor verdwijnen — ease-in (snelle finish).
In iOS gebeurt het belangrijkste werk met easing via de klasse CAMediaTimingFunction uit Core Animation. Deze ontvangt een kubische Bézier-curve in de vorm van twee controlepunt (c1x, c1y, c2x, c2y) en wordt toegepast op CAAnimation (CABasicAnimation, CAKeyframeAnimation). CAMediaTimingFunction ondersteunt 5 vooraf gedefinieerde functies: linear, easeIn, easeOut, easeInEaseOut en default (equivalent van easeInEaseOut).
CAMediaTimingFunction werkt op het niveau van CALayer — de animatie wordt uitgevoerd in een apart proces, de render server, wat 60fps garandeert, zelfs bij complexe transformaties. Voor de animatie van UIView-eigenschappen (frame, alpha, transform) gebruikt UIKit UIView.animate met de parameter options: .curveEaseInOut, die intern ook CAMediaTimingFunction met de bijbehorende curve aanmaakt. In iOS 17+ is UIViewAnimationCurve.custom met BlockParameters voor aangepaste Bézier toegevoegd — dit elimineert de noodzaak om een eigen CAAnimation te schrijven. CAMediaTimingFunction wordt ook gebruikt in UIKit Dynamics en UIScrollView voor deceleratie (UIScrollViewDecelerationRate).
In SwiftUI wordt easing gedefinieerd via de structuur Animation met modifiers .easeIn, .easeOut, .easeInOut, .spring en .interpolatingSpring. In tegenstelling tot UIKit, waar animatie procedureel is (beginAnimations/commitAnimations), gebruikt SwiftUI een declaratieve benadering: animatie is een toestandseigenschap die verandert en het framework bepaalt zelf hoe de overgang te animeren.
De modifier .timingCurve(c0x, c0y, c1x, c1y) ontvangt rechtstreeks de controlepunt van de kubische Bézier — dit is de volledige analogie van CAMediaTimingFunction. SwiftUI Animation ondersteunt vooraf gedefinieerde curves als statische eigenschappen: Animation.easeInOut is equivalent aan ease-in-out (0.42, 0.0, 0.58, 1.0). Voor veeranimatie wordt Animation.spring(response:dampingFraction:blendDuration) gebruikt, waarbij dampingFraction < 1 een veereffect met demping creëert. Op WWDC 2023 introduceerde Apple Animation.keyframes — frame-voor-frame animatie met aangepaste easing op elk sleutelframe, wat volledige controle over het traject geeft.
In Android wordt easing geïmplementeerd via PathInterpolator (API 21+) — een klasse die een Path-object met een kubische Bézier-curve ontvangt. De controlepunt worden gedefinieerd via Path.cubicTo(x1, y1, x2, y2, x3, y3), waarbij (x1,y1) het eerste controlepunt is, (x2,y2) het tweede en (x3,y3) het eindpunt (altijd 1,1). PathInterpolator is verplicht als een aangepaste curve nodig is; voor standaard scenario's zijn AccelerateDecelerateInterpolator (ease-in-out), AccelerateInterpolator (ease-in) en DecelerateInterpolator (ease-out) beschikbaar.
In Jetpack Compose wordt easing gedefinieerd via het object Easing uit het pakket androidx.compose.animation. FastOutSlowInEasing, LinearOutSlowInEasing, FastOutLinearInEasing en ook aangepaste Easing via CubicBezierEasing zijn beschikbaar. Compose Easing wordt toegepast in animate*AsState, AnimatedVisibility en AnimatedContent. Het belangrijkste verschil met het View-systeem: Compose interpoleert easing aan de Kotlin-kant (niet in RenderNode), wat meer flexibiliteit biedt voor aangepaste animaties, maar optimalisatie vereist bij 120Hz-schermen.
Basisanimatie van de laagpositie met een aangepaste ease-in-out-curve. CAMediaTimingFunction ontvangt de controlepunt van de kubische Bézier, die een vloeiend begin en einde van de beweging definiëren.
import UIKit
func animateLayerPosition() {
let animation = CABasicAnimation(keyPath: "position")
animation.fromValue = CGPoint(x: 0, y: 0)
animation.toValue = CGPoint(x: 300, y: 400)
animation.duration = 0.8
let easing = CAMediaTimingFunction(
controlPoints: 0.42, 0.0, 0.58, 1.0
)
animation.timingFunction = easing
animation.fillMode = .forwards
animation.isRemovedOnCompletion = false
layer.add(animation, forKey: "positionAnimation")
}
De controlepunt (0.42, 0.0, 0.58, 1.0) definiëren de standaard ease-in-out-curve. SwiftUI gebruikt dezelfde punten voor Animation.easeInOut. Voor ease-in gebruikt u (0.42, 0.0, 1.0, 1.0), voor ease-out — (0.0, 0.0, 0.58, 1.0). Core Animation voert de animatie uit in de render server met een frequentie van 60/120 fps.
Declaratieve animatie in SwiftUI met een aangepaste curve en veereffect. De animation-modifier is gekoppeld aan de verandering van isAnimated.
import SwiftUI
struct EasingExampleView: View {
@State private var isAnimated = false
var body: some View {
VStack {
Circle()
.fill(Color.blue)
.frame(width: 60, height: 60)
.offset(x: isAnimated ? 100 : 0, y: 0)
.animation(
.timingCurve(0.42, 0.0, 0.58, 1.0, duration: 0.6),
value: isAnimated
)
Button("Toggle") {
isAnimated.toggle()
}
}
}
}
De modifier .timingCurve(c0x, c0y, c1x, c1y, duration) creëert een aangepaste easing-animatie in SwiftUI. De parameter value koppelt de animatie aan een specifieke toestand — bij wijziging van isAnimated past SwiftUI automatisch de curve toe. Gebruik voor veeranimatie .spring(response: 0.4, dampingFraction: 0.6) in plaats van timingCurve.
Equivalent van ease-in-out in Android via PathInterpolator. De controlepunt (0.42, 0.0, 0.58, 1.0) definiëren dezelfde curve als in iOS.
import android.animation.ObjectAnimator
import android.graphics.Path
import android.view.animation.PathInterpolator
import android.view.View
fun View.fadeInWithEase() {
val path = Path().apply {
cubicTo(0.42f, 0.0f, 0.58f, 1.0f, 1.0f, 1.0f)
}
val interpolator = PathInterpolator(path)
ObjectAnimator.ofFloat(this, "alpha", 0f, 1f).apply {
duration = 500
interpolator = interpolator
start()
}
}
PathInterpolator met controlepunt (0.42, 0.0, 0.58, 1.0) is identiek aan CAMediaTimingFunction ease-in-out op iOS. Gebruik voor cross-platform projecten dezelfde controlepunt — dit garandeert visueel identiek animatiegedrag. Material Design beveelt FastOutSlowInInterpolator (0.4, 0.0, 0.2, 1.0) aan als alternatief voor Android-specifieke interfaces.
In Compose wordt easing gedefinieerd via CubicBezierEasing met dezelfde controlepunt. Het resultaat — een vloeiende verschijning van een element met transparantie en verschuiving.
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.CubicBezierEasing
import androidx.compose.animation.core.tween
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
@Composable
fun EasingComposable() {
var visible by remember { mutableStateOf(false) }
val easing = CubicBezierEasing(0.42f, 0.0f, 0.58f, 1.0f)
val alpha by animateFloatAsState(
targetValue = if (visible) 1f else 0f,
animationSpec = tween(durationMillis = 500, easing = easing)
)
Column {
Button(onClick = { visible = !visible }) {
Text("Toggle")
}
Box(
modifier = Modifier
.size(100.dp)
.graphicsLayer(alpha = alpha)
.background(MaterialTheme.colorScheme.primary)
)
}
}
CubicBezierEasing in Compose ontvangt dezelfde 4 parameters van de controlepunt. animateFloatAsState interpoleert automatisch de alpha-waarde met de gegeven curve. Ter vergelijking: FastOutSlowInEasing in Compose is equivalent aan (0.4, 0.0, 0.2, 1.0) — de standaardcurve van Material Design 3. Aangepaste curves via CubicBezierEasing bieden volledige controle voor merk-animaties.
Veelgestelde vragen
Easing — het algemene concept van een verzachtingsfunctie, gebruikt in iOS (CAMediaTimingFunction), web (CSS ease-in-out) en design. Interpolator — de implementatie van dit concept in Android (TimeInterpolator). In wezen is het hetzelfde — een wiskundige curve van animatiesnelheid. Het verschil zit alleen in de naam en het platform-API. In cross-platform projecten wordt de term easing als universeel gebruikt.
iOS biedt CAMediaTimingFunction met 5 vooraf gedefinieerde functies: linear, easeIn, easeOut, easeInEaseOut en custom (kubische Bézier). In SwiftUI zijn Animation.easeIn, Animation.easeOut, Animation.easeInOut, Animation.spring en Animation.interpolatingSpring beschikbaar. Gebruik voor aangepaste curves Animation.timingCurve(c0x, c0y, c1x, c1y, duration:).
Ja, als u dezelfde kubische Bézier-curve instelt. CAMediaTimingFunction in iOS en PathInterpolator in Android accepteren de controlepunt van de kubische Bézier (x1, y1, x2, y2). Bijvoorbeeld, de curve ease-in-out (0.42, 0.0, 0.58, 1.0) geeft identiek gedrag op beide platforms. Material Design gebruikt deze benadering voor cross-platform animaties.
Gebruik de Material Design Motion-richtlijnen: voor verschijnen van elementen — ease-out (snelle start, vloeiende finish), voor verdwijnen — ease-in (snelle finish), voor verplaatsing tussen schermen — ease-in-out. Gebruik veeranimatie voor interactieve elementen (knoppen, kaarten). Vermijd linear — het ziet er onnatuurlijk uit.
Schokkerigheid (jank) treedt op wanneer de animatie geen 60fps haalt. Controleer: gebruikt u CAMediaTimingFunction (geen timer) in iOS, PathInterpolator (geen Handler.post) in Android. Zware berekeningen in de hoofdthread, complexe laaghiërarchie of een grote drawable kunnen frameverlies veroorzaken. Gebruik in iOS Core Animation met shouldRasterize voor complexe lagen; in Android — Hardware Acceleration en GPU rendering.
Samenvatting
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.
Lees ook