package com.example.compose_anim_01 import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import androidx.compose.animation.animateColor import androidx.compose.animation.core.LinearEasing import androidx.compose.animation.core.RepeatMode import androidx.compose.animation.core.animateFloat import androidx.compose.animation.core.infiniteRepeatable import androidx.compose.animation.core.rememberInfiniteTransition import androidx.compose.animation.core.tween import androidx.compose.foundation.Canvas import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.padding import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.geometry.Offset import androidx.compose.ui.graphics.Color import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import com.example.compose_anim_01.ui.theme.ComposeAnim01Theme class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() setContent { ComposeAnim01Theme { Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding -> //SingleSnowflakeDemo(Modifier.padding(innerPadding)) Greeting( name = "Android", modifier = Modifier.padding(innerPadding) ) } } } } } @Composable fun Greeting(name: String, modifier: Modifier = Modifier) { val infiniteTransition = rememberInfiniteTransition(label = "infinite") // 1) Barva textu val color by infiniteTransition.animateColor( initialValue = Color.Red, targetValue = Color.Green, animationSpec = infiniteRepeatable( animation = tween(1000, easing = LinearEasing), repeatMode = RepeatMode.Reverse ), label = "color" ) // 2) Velikost textu val fontSize by infiniteTransition.animateFloat( initialValue = 24f, targetValue = 40f, animationSpec = infiniteRepeatable( animation = tween(1000, easing = LinearEasing), repeatMode = RepeatMode.Reverse ), label = "fontSize" ) // 3) Pozice textu (letí doprava a zpět) val offsetX by infiniteTransition.animateFloat( initialValue = 0f, targetValue = 200f, animationSpec = infiniteRepeatable( animation = tween(2000, easing = LinearEasing), repeatMode = RepeatMode.Reverse ), label = "offsetX" ) Text( text = "Hello $name!", modifier = modifier.offset(x = offsetX.dp, y = 0.dp), color = color, fontSize = fontSize.sp ) } @Composable fun SingleSnowflakeDemo(modifier: Modifier = Modifier) { val infiniteTransition = rememberInfiniteTransition(label = "snow") // Animovaná hodnota progress od 0f do 1f, která se pořád dokola opakuje. // Můžeme ji používat jako „čas“ pádu vločky z horního okraje dolů. val progress by infiniteTransition.animateFloat( initialValue = 0f, // start animace (0 % dráhy) targetValue = 1f, // konec animace (100 % dráhy) animationSpec = infiniteRepeatable( // Jedno „spuštění“ pádu trvá 4000 ms, průběh je lineární. animation = tween(durationMillis = 4000, easing = LinearEasing), // Po dosažení targetValue se animace znovu restartuje od initialValue. repeatMode = RepeatMode.Restart ), label = "progress" ) // Zde může být Canvas + drawCircle pro nízkoúrovňové vykreslování navázané na animovanou hodnotu progress. // Nápověda: // 1. Použijt je možné Canvas(modifier = modifier.fillMaxSize()) { ... } // 2. Uvnitř spočítejte y = size.height * progress // 3. Vykreslete kruh pomocí drawCircle() } @Preview(showBackground = true) @Composable fun GreetingPreview() { ComposeAnim01Theme { Greeting("Android") } }