Easing: Mobil Animasyonda Yumuşatma Fonksiyonları

Yazar: IT Sectr Yayınlanma: 2026-03-02 Okuma süresi: 8 dk
Easing (yumuşatma fonksiyonu), bir animasyon parametresinin zaman içindeki değişim hızını belirleyen matematiksel bir eğridir. Doğrusal düzgün hızlanan hareket yerine, easing fiziksel davranışı taklit eder: bir nesne hızlanabilir (ease-in), yavaşlayabilir (ease-out) veya her ikisini de yapabilir (ease-in-out). iOS'ta easing, CAMediaTimingFunction sınıfı (Core Animation) ve SwiftUI değiştiricileri (Animation.easeInOut) aracılığıyla uygulanır. Android'de — PathInterpolator ve TimeInterpolator aracılığıyla. Apple Developer Documentation'a göre, doğru seçilmiş bir easing eğrisi, gerçek süreyi değiştirmeden algılanan animasyon süresini %20–35 oranında azaltır. IT Sectr'da, ease-in-out eğrisini (0.42, 0.0, 0.58, 1.0) tüm mobil projeler için kurumsal standart olarak standartlaştırdık.

Anahtar Noktalar

  • Easing — fiziksel hareketi taklit eden bir animasyon hız fonksiyonu: hızlanma, yavaşlama veya kombinasyon.
  • CAMediaTimingFunction — 5 ön tanımlı eğri ve özel kübik Bézier ile iOS Core Animation sınıfı.
  • SwiftUI Animation — bildirimsel easing için .easeIn, .easeOut, .easeInOut, .spring ve .timingCurve değiştiricileri.
  • PathInterpolator — iki kontrol noktası aracılığıyla kübik Bézier eğrisi ile Android'de easing eşdeğeri.
  • Kübik Bézier — iOS, Android ve web'de ortak olan, easing eğrilerini belirtmek için evrensel bir biçim.

Easing Nedir?

Easing (yumuşatma fonksiyonu), doğrusal zaman t ∈ [0,1]'i doğrusal olmayan bir animasyon değerine eşleyen matematiksel bir f(t) fonksiyonudur. Bir animasyon 500 ms'de bir nesnenin konumunu A'dan B'ye değiştiriyorsa, easing nesnenin zamanın her anında bu noktalar arasında nasıl hareket ettiğini belirler. Doğrusal easing (f(t) = t) sabit hız anlamına gelir — nesne mekanik olarak hareket eder. Doğrusal olmayan easing doğaldır: nesne hızlanır (ease-in), yavaşlar (ease-out) veya pürüzsüz bir başlangıç ve bitişe sahiptir (ease-in-out).

Easing fonksiyonları, X ekseninin normalize edilmiş zaman ve Y ekseninin normalize edilmiş ilerleme olduğu kübik Bézier eğrileriyle tanımlanır. İki kontrol noktası (P1, P2) eğri şeklini belirler. Standart eğriler CSS şartnamesi tarafından sabitlenmiştir: 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). Bu aynı değerler iOS'ta CAMediaTimingFunction ve Android'de PathInterpolator'da kullanılır. Material Design Hareket Yönergeleri'ne göre, easing eğrileri bağlama uygun olmalıdır: görünme için — ease-out (hızlı başlangıç), kaybolma için — ease-in (hızlı bitiş).

iOS'ta Easing: CAMediaTimingFunction

iOS'ta easing esas olarak Core Animation'daki CAMediaTimingFunction sınıfı aracılığıyla çalışır. İki kontrol noktası (c1x, c1y, c2x, c2y) olarak kübik bir Bézier eğrisi kabul eder ve CAAnimation'a (CABasicAnimation, CAKeyframeAnimation) uygulanır. CAMediaTimingFunction 5 ön tanımlı fonksiyonu destekler: linear, easeIn, easeOut, easeInEaseOut ve default (easeInEaseOut'a eşdeğer).

CAMediaTimingFunction CALayer düzeyinde çalışır — animasyon, karmaşık dönüşümlerde bile 60fps'yi garanti eden ayrı bir işleme sunucusu sürecinde çalışır. UIView özelliklerinin (frame, alpha, transform) animasyonu için UIKit, options parametresi .curveEaseInOut ile UIView.animate'i kullanır ve bu da dahili olarak ilgili eğriyle bir CAMediaTimingFunction oluşturur. iOS 17+'da, özel Bézier için UIViewAnimationCurve.custom, BlockParameters ile eklendi — bu, özel CAAnimation yazma ihtiyacını ortadan kaldırır. CAMediaTimingFunction, UIKit Dynamics ve UIScrollView'de yavaşlama (UIScrollViewDecelerationRate) için de kullanılır.

SwiftUI'da Easing

SwiftUI'da easing, .easeIn, .easeOut, .easeInOut, .spring ve .interpolatingSpring değiştiricileriyle Animation yapısı aracılığıyla ayarlanır. Animasyonun prosedürel (beginAnimations/commitAnimations) olduğu UIKit'in aksine, SwiftUI bildirimsel bir yaklaşım kullanır: animasyon değişen bir durum özelliğidir ve çerçeve, geçişi nasıl canlandıracağını kendisi belirler.

.timingCurve(c0x, c0y, c1x, c1y) değiştiricisi, kübik Bézier kontrol noktalarını doğrudan kabul eder — bu, CAMediaTimingFunction'ın tam bir benzeridir. SwiftUI Animation, ön tanımlı eğrileri statik özellikler olarak destekler: Animation.easeInOut, ease-in-out (0.42, 0.0, 0.58, 1.0) ile eşdeğerdir. Yay animasyonu için, dampingFraction < 1'in sönümlemeli bir yay etkisi yarattığı Animation.spring(response:dampingFraction:blendDuration) kullanılır. WWDC 2023'te Apple, her ana karede özel easing ile kare kare animasyon sağlayan ve yörünge üzerinde tam kontrol veren Animation.keyframes'i tanıttı.

Android'de Easing: PathInterpolator

Android'de easing, kübik Bézier eğrisine sahip bir Path nesnesini kabul eden PathInterpolator (API 21+) aracılığıyla uygulanır. Kontrol noktaları, Path.cubicTo(x1, y1, x2, y2, x3, y3) aracılığıyla belirtilir; burada (x1,y1) ilk kontrol noktası, (x2,y2) ikinci ve (x3,y3) bitiş noktasıdır (her zaman 1,1). Özel bir eğri gerekiyorsa PathInterpolator zorunludur; standart senaryolar için AccelerateDecelerateInterpolator (ease-in-out), AccelerateInterpolator (ease-in) ve DecelerateInterpolator (ease-out) mevcuttur.

Jetpack Compose'da easing, androidx.compose.animation paketindeki Easing nesnesi aracılığıyla ayarlanır. FastOutSlowInEasing, LinearOutSlowInEasing, FastOutLinearInEasing ve CubicBezierEasing aracılığıyla özel Easing mevcuttur. Compose Easing, animate*AsState, AnimatedVisibility ve AnimatedContent'te uygulanır. View sisteminden temel fark: Compose, easing'i Kotlin tarafında enterpole eder (RenderNode'da değil), bu da özel animasyonlar için daha fazla esneklik sağlar ancak 120Hz ekranlarda optimizasyon gerektirir.

Kod Örnekleri

iOS: CABasicAnimation ile CAMediaTimingFunction

Özel bir ease-in-out eğrisiyle temel katman konum animasyonu. CAMediaTimingFunction, hareketin pürüzsüz başlangıcını ve bitişini tanımlayan kübik Bézier kontrol noktalarını kabul eder.

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

Kontrol noktaları (0.42, 0.0, 0.58, 1.0) standart ease-in-out eğrisini tanımlar. SwiftUI, Animation.easeInOut için aynı noktaları kullanır. Ease-in için (0.42, 0.0, 1.0, 1.0); ease-out için — (0.0, 0.0, 0.58, 1.0) kullanın. Core Animation, animasyonu işleme sunucusunda 60/120 fps'de yürütür.

SwiftUI: timingCurve ile Easing

Özel bir eğri ve yay etkisiyle SwiftUI'da bildirimsel animasyon. Animasyon değiştiricisi, isAnimated değişikliğine bağlanır.

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

.timingCurve(c0x, c0y, c1x, c1y, duration) değiştiricisi, SwiftUI'da özel bir easing animasyonu oluşturur. value parametresi, animasyonu belirli bir duruma bağlar — isAnimated değiştiğinde, SwiftUI otomatik olarak eğriyi uygular. Yay animasyonu için timingCurve yerine .spring(response: 0.4, dampingFraction: 0.6) kullanın.

Android: Özel Easing ile PathInterpolator

PathInterpolator aracılığıyla Android'de ease-in-out eşdeğeri. Kontrol noktaları (0.42, 0.0, 0.58, 1.0), iOS'takiyle aynı eğriyi tanımlar.

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

Kontrol noktaları (0.42, 0.0, 0.58, 1.0) ile PathInterpolator, iOS'taki CAMediaTimingFunction ease-in-out ile aynıdır. Platformlar arası projeler için aynı kontrol noktalarını kullanın — bu, görsel olarak aynı animasyon davranışını garanti eder. Material Design, Android'e özel arayüzler için alternatif olarak FastOutSlowInInterpolator'u (0.4, 0.0, 0.2, 1.0) önerir.

Jetpack Compose: CubicBezierEasing ile Easing

Compose'da easing, aynı kontrol noktalarıyla CubicBezierEasing aracılığıyla ayarlanır. Sonuç, şeffaflık ve ofset ile pürüzsüz bir öğe görünümüdür.

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

Compose'da CubicBezierEasing aynı 4 kontrol noktası parametresini kabul eder. animateFloatAsState, belirtilen eğriyle alpha değerini otomatik olarak enterpole eder. Karşılaştırma için: Compose'da FastOutSlowInEasing, (0.4, 0.0, 0.2, 1.0) — standart Material Design 3 eğrisi — ile eşdeğerdir. CubicBezierEasing aracılığıyla özel eğriler, marka animasyonları için tam kontrol sağlar.

Sıkça Sorulan Sorular

Easing, interpolator'dan nasıl farklıdır?

Easing, iOS'ta (CAMediaTimingFunction), web'de (CSS ease-in-out) ve tasarımda kullanılan bir yumuşatma fonksiyonunun genel bir kavramıdır. Interpolator, bu kavramın Android'deki (TimeInterpolator) uygulamasıdır. Özünde aynı şeydir — animasyon hızının matematiksel bir eğrisi. Fark yalnızca ad ve platform API'sindedir. Platformlar arası projelerde, easing terimi evrensel olarak kullanılır.

iOS'ta hangi easing fonksiyonları mevcuttur?

iOS, 5 ön tanımlı fonksiyonla CAMediaTimingFunction sağlar: linear, easeIn, easeOut, easeInEaseOut ve custom (kübik Bézier). SwiftUI'da Animation.easeIn, Animation.easeOut, Animation.easeInOut, Animation.spring ve Animation.interpolatingSpring mevcuttur. Özel eğriler için Animation.timingCurve(c0x, c0y, c1x, c1y, duration:) kullanın.

iOS ve Android'de aynı easing fonksiyonu kullanılabilir mi?

Evet, aynı kübik Bézier eğrisi ayarlanırsa. iOS'ta CAMediaTimingFunction ve Android'de PathInterpolator, kübik Bézier kontrol noktalarını (x1, y1, x2, y2) kabul eder. Örneğin, ease-in-out (0.42, 0.0, 0.58, 1.0) eğrisi her iki platformda da aynı davranışı gösterecektir. Material Design, platformlar arası animasyonlar için bu yaklaşımı kullanır.

Uygulamam için doğru easing eğrisini nasıl seçerim?

Material Design Hareket Yönergeleri'ni kullanın: öğe görünümü için — ease-out (hızlı başlangıç, pürüzsüz bitiş), kaybolma için — ease-in (hızlı bitiş), ekranlar arası hareket için — ease-in-out. Etkileşimli öğeler (düğmeler, kartlar) için yay animasyonu kullanın. Linear'dan kaçının — doğal görünmez.

Easing animasyonum neden kesikli görünüyor?

Kesiklilik (jank), animasyon 60fps'ye ulaşamadığında oluşur. Şunları kontrol edin: iOS'ta CAMediaTimingFunction (zamanlayıcı değil) kullanıyor musunuz? Android'de PathInterpolator (Handler.post değil) kullanıyor musunuz? Ana iç iplikteki ağır hesaplamalar, karmaşık katman hiyerarşisi veya büyük bir drawable, kare düşüklerine neden olabilir. iOS'ta karmaşık katmanlar için shouldRasterize ile Core Animation kullanın; Android'de — Donanım Hızlandırma ve GPU işleme kullanın.

Özet

  • Easing, zaman içinde doğrusal olmayan parametre değişiklikleriyle hareketi doğal hale getiren bir animasyon hız fonksiyonudur.
  • iOS CAMediaTimingFunction ve SwiftUI Animation.timingCurve, iki kontrol noktalı kübik Bézier eğrisi aracılığıyla easing uygular.
  • Android PathInterpolator ve Compose CubicBezierEasing, özel yumuşatma eğrileri için iOS'un tam benzerleridir.
  • Platformlar arası easing eğrileri aynı kontrol noktalarıyla tanımlanır — animasyon birleştirmenin temeli.
  • Material Design 3, görünme için fast-out-slow-in, kaybolma için linear-out-slow-in önerir.
  • SwiftUI (Animation.spring) ve Compose'da (spring()) yay animasyonu, dampingFraction ile fiziksel bir yay etkisi yaratır.
  • Doğrusal easing, arayüz animasyonları için önerilmez — doğal olmayan ve mekanik görünür.

Anahtar teslim bir mobil uygulama geliştireceğiz

IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.

Projeyi tartış

Ayrıca okuyun