Easing: esensi, fungsi pelunakan dalam animasi mobile

Penulis: IT Sectr Diterbitkan: 2026-03-02 Waktu membaca: 8 mnt
Easing (fungsi pelunakan) — kurva matematika yang menentukan kecepatan perubahan parameter animasi dari waktu ke waktu. Alih-alih gerakan linear yang dipercepat secara seragam, easing meniru perilaku fisik: objek dapat mempercepat (ease-in), memperlambat (ease-out), atau melakukan keduanya (ease-in-out). Di iOS, easing diimplementasikan melalui kelas CAMediaTimingFunction (Core Animation) dan modifier SwiftUI (Animation.easeInOut). Di Android — melalui PathInterpolator dan TimeInterpolator. Menurut Dokumentasi Apple Developer, kurva easing yang dipilih dengan tepat mengurangi waktu animasi yang dirasakan sebesar 20–35% tanpa mengubah durasi sebenarnya. Di IT Sectr, kami telah menstandarisasi kurva ease-in-out (0.42, 0.0, 0.58, 1.0) sebagai standar korporat untuk semua proyek mobile.

Poin-poin utama

  • Easing — fungsi kecepatan animasi yang meniru gerakan fisik: percepatan, perlambatan, atau kombinasi.
  • CAMediaTimingFunction — kelas iOS Core Animation dengan 5 kurva yang telah ditentukan sebelumnya dan Bézier kubik kustom.
  • SwiftUI Animation — modifier .easeIn, .easeOut, .easeInOut, .spring dan .timingCurve untuk easing deklaratif.
  • PathInterpolator — analog easing di Android dengan kurva Bézier kubik melalui dua titik kontrol.
  • Bézier kubik — format universal untuk mendefinisikan kurva easing, umum untuk iOS, Android, dan web.

Apa itu Easing?

Easing (fungsi pelunakan) — fungsi matematika f(t) yang memetakan jalur linear waktu t ∈ [0,1] ke nilai animasi non-linear. Jika animasi mengubah posisi objek dari A ke B dalam 500 ms, easing menentukan bagaimana objek bergerak di antara titik-titik ini pada setiap saat. Easing linear (f(t) = t) berarti kecepatan konstan — objek bergerak secara mekanis. Easing non-linear — alami: objek mempercepat (ease-in), memperlambat (ease-out), atau memiliki awal dan akhir yang halus (ease-in-out).

Fungsi easing digambarkan dengan kurva Bézier kubik (Cubic Bézier), di mana sumbu X adalah waktu yang dinormalisasi dan sumbu Y adalah kemajuan yang dinormalisasi. Dua titik kontrol (P1, P2) menentukan bentuk kurva. Kurva standar ditetapkan oleh spesifikasi CSS: 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). Nilai yang sama digunakan dalam CAMediaTimingFunction di iOS dan PathInterpolator di Android. Menurut pedoman Material Design Motion, kurva easing harus sesuai dengan konteks: untuk kemunculan — ease-out (start cepat), untuk penghilangan — ease-in (finish cepat).

Easing di iOS: CAMediaTimingFunction

Di iOS, pekerjaan utama dengan easing dilakukan melalui kelas CAMediaTimingFunction dari Core Animation. Kelas ini menerima kurva Bézier kubik dalam bentuk dua titik kontrol (c1x, c1y, c2x, c2y) dan diterapkan ke CAAnimation (CABasicAnimation, CAKeyframeAnimation). CAMediaTimingFunction mendukung 5 fungsi yang telah ditentukan: linear, easeIn, easeOut, easeInEaseOut, dan default (setara dengan easeInEaseOut).

CAMediaTimingFunction bekerja pada tingkat CALayer — animasi dijalankan dalam proses terpisah, render server, yang menjamin 60fps bahkan pada transformasi yang kompleks. Untuk animasi properti UIView (frame, alpha, transform), UIKit menggunakan UIView.animate dengan parameter options: .curveEaseInOut, yang secara internal juga membuat CAMediaTimingFunction dengan kurva yang sesuai. Di iOS 17+, telah ditambahkan UIViewAnimationCurve.custom dengan BlockParameters untuk Bézier kustom — ini menghilangkan kebutuhan untuk menulis CAAnimation sendiri. CAMediaTimingFunction juga digunakan di UIKit Dynamics dan UIScrollView untuk deselerasi (UIScrollViewDecelerationRate).

Easing di SwiftUI

Di SwiftUI, easing didefinisikan melalui struktur Animation dengan modifier .easeIn, .easeOut, .easeInOut, .spring dan .interpolatingSpring. Berbeda dengan UIKit di mana animasi bersifat prosedural (beginAnimations/commitAnimations), SwiftUI menggunakan pendekatan deklaratif: animasi adalah properti status yang berubah dan framework sendiri yang menentukan cara menganimasikan transisi.

Modifier .timingCurve(c0x, c0y, c1x, c1y) menerima langsung titik kontrol Bézier kubik — ini adalah analog lengkap dari CAMediaTimingFunction. SwiftUI Animation mendukung kurva yang telah ditentukan sebagai properti statis: Animation.easeInOut setara dengan ease-in-out (0.42, 0.0, 0.58, 1.0). Untuk animasi pegas, digunakan Animation.spring(response:dampingFraction:blendDuration), di mana dampingFraction < 1 menciptakan efek pegas dengan redaman. Di WWDC 2023, Apple memperkenalkan Animation.keyframes — animasi bingkai demi bingkai dengan easing kustom pada setiap bingkai kunci, yang memberikan kontrol penuh atas lintasan.

Easing di Android: PathInterpolator

Di Android, easing diimplementasikan melalui PathInterpolator (API 21+) — kelas yang menerima objek Path dengan kurva Bézier kubik. Titik kontrol didefinisikan melalui Path.cubicTo(x1, y1, x2, y2, x3, y3), di mana (x1,y1) adalah titik kontrol pertama, (x2,y2) kedua, (x3,y3) titik akhir (selalu 1,1). PathInterpolator wajib jika diperlukan kurva kustom; untuk skenario standar, tersedia AccelerateDecelerateInterpolator (ease-in-out), AccelerateInterpolator (ease-in), dan DecelerateInterpolator (ease-out).

Di Jetpack Compose, easing didefinisikan melalui objek Easing dari paket androidx.compose.animation. Tersedia FastOutSlowInEasing, LinearOutSlowInEasing, FastOutLinearInEasing, serta Easing kustom melalui CubicBezierEasing. Compose Easing diterapkan di animate*AsState, AnimatedVisibility, dan AnimatedContent. Perbedaan utama dari sistem View: Compose menginterpolasi easing di sisi Kotlin (bukan di RenderNode), yang memberikan fleksibilitas lebih untuk animasi kustom, tetapi memerlukan optimasi pada layar 120Hz.

Contoh kode

iOS: CAMediaTimingFunction dengan CABasicAnimation

Animasi dasar posisi layer dengan kurva ease-in-out kustom. CAMediaTimingFunction menerima titik kontrol Bézier kubik yang mendefinisikan awal dan akhir gerakan yang halus.

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

Titik kontrol (0.42, 0.0, 0.58, 1.0) mendefinisikan kurva standar ease-in-out. SwiftUI menggunakan titik yang sama untuk Animation.easeInOut. Untuk ease-in, gunakan (0.42, 0.0, 1.0, 1.0), untuk ease-out — (0.0, 0.0, 0.58, 1.0). Core Animation menjalankan animasi di render server dengan frekuensi 60/120 fps.

SwiftUI: Easing dengan timingCurve

Animasi deklaratif di SwiftUI dengan kurva kustom dan efek pegas. Modifier animation terikat pada perubahan isAnimated.

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

Modifier .timingCurve(c0x, c0y, c1x, c1y, duration) membuat animasi easing kustom di SwiftUI. Parameter value menghubungkan animasi dengan status tertentu — saat isAnimated berubah, SwiftUI secara otomatis menerapkan kurva. Untuk animasi pegas, gunakan .spring(response: 0.4, dampingFraction: 0.6) sebagai pengganti timingCurve.

Android: PathInterpolator dengan easing kustom

Ekuivalen ease-in-out di Android melalui PathInterpolator. Titik kontrol (0.42, 0.0, 0.58, 1.0) mendefinisikan kurva yang sama seperti di iOS.

kotlin
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 dengan titik kontrol (0.42, 0.0, 0.58, 1.0) identik dengan CAMediaTimingFunction ease-in-out di iOS. Untuk proyek lintas platform, gunakan titik kontrol yang sama — ini menjamin perilaku animasi yang identik secara visual. Material Design merekomendasikan FastOutSlowInInterpolator (0.4, 0.0, 0.2, 1.0) sebagai alternatif untuk antarmuka khusus Android.

Jetpack Compose: Easing dengan CubicBezierEasing

Di Compose, easing didefinisikan melalui CubicBezierEasing dengan titik kontrol yang sama. Hasilnya — kemunculan elemen yang halus dengan transparansi dan pergeseran.

kotlin
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 di Compose menerima 4 parameter titik kontrol yang sama. animateFloatAsState secara otomatis menginterpolasi nilai alpha dengan kurva yang diberikan. Sebagai perbandingan: FastOutSlowInEasing di Compose setara dengan (0.4, 0.0, 0.2, 1.0) — kurva standar Material Design 3. Kurva kustom melalui CubicBezierEasing memberikan kontrol penuh untuk animasi merek.

Pertanyaan yang sering diajukan

Apa perbedaan easing dengan interpolator?

Easing — konsep umum fungsi pelunakan, digunakan di iOS (CAMediaTimingFunction), web (CSS ease-in-out) dan desain. Interpolator — implementasi konsep ini di Android (TimeInterpolator). Pada dasarnya ini hal yang sama — kurva matematika kecepatan animasi. Perbedaannya hanya pada nama dan API platform. Dalam proyek lintas platform, istilah easing digunakan sebagai istilah universal.

Fungsi easing apa yang tersedia di iOS?

iOS menyediakan CAMediaTimingFunction dengan 5 fungsi yang telah ditentukan: linear, easeIn, easeOut, easeInEaseOut, dan custom (Bézier kubik). Di SwiftUI tersedia Animation.easeIn, Animation.easeOut, Animation.easeInOut, Animation.spring dan Animation.interpolatingSpring. Untuk kurva kustom, gunakan Animation.timingCurve(c0x, c0y, c1x, c1y, duration:).

Bisakah saya menggunakan fungsi easing yang sama di iOS dan Android?

Ya, jika Anda mengatur kurva Bézier kubik yang sama. CAMediaTimingFunction di iOS dan PathInterpolator di Android menerima titik kontrol Bézier kubik (x1, y1, x2, y2). Misalnya, kurva ease-in-out (0.42, 0.0, 0.58, 1.0) akan memberikan perilaku yang identik di kedua platform. Material Design menggunakan pendekatan ini untuk animasi lintas platform.

Bagaimana cara memilih kurva easing yang tepat untuk aplikasi saya?

Gunakan pedoman Material Design Motion: untuk kemunculan elemen — ease-out (start cepat, finish halus), untuk penghilangan — ease-in (finish cepat), untuk perpindahan antar layar — ease-in-out. Gunakan animasi pegas untuk elemen interaktif (tombol, kartu). Hindari linear — terlihat tidak alami.

Mengapa animasi saya dengan easing terlihat tersendat?

Tersendat (jank) terjadi ketika animasi tidak mencapai 60fps. Periksa: apakah Anda menggunakan CAMediaTimingFunction (bukan timer) di iOS, PathInterpolator (bukan Handler.post) di Android. Perhitungan berat di thread utama, hierarki layer yang kompleks, atau drawable besar dapat menyebabkan hilangnya bingkai. Di iOS, gunakan Core Animation dengan shouldRasterize untuk layer yang kompleks; di Android — Hardware Acceleration dan GPU rendering.

Kesimpulan

  • Easing — fungsi kecepatan animasi yang membuat gerakan menjadi alami melalui perubahan parameter non-linear dari waktu ke waktu.
  • iOS CAMediaTimingFunction dan SwiftUI Animation.timingCurve mengimplementasikan easing melalui kurva Bézier kubik dengan dua titik kontrol.
  • Android PathInterpolator dan Compose CubicBezierEasing — analog lengkap iOS untuk kurva pelunakan kustom.
  • Kurva easing lintas platform didefinisikan dengan titik kontrol yang identik — dasar unifikasi animasi.
  • Material Design 3 merekomendasikan fast-out-slow-in untuk kemunculan, linear-out-slow-in untuk penghilangan.
  • Animasi pegas di SwiftUI (Animation.spring) dan Compose (spring()) menciptakan efek pegas fisik dengan dampingFraction.
  • Easing linear tidak direkomendasikan untuk animasi antarmuka — terlihat tidak alami dan mekanis.

Kami akan mengembangkan aplikasi seluler turnkey

IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.

Diskusikan proyek

Baca juga