Compose笔记(七十五)--withFrameNanos

这一节主要了解一下Compose中使用withFrameNanos,withFrameNanos是一个用于精确控制动画帧回调的核心函数,属于Compose动画系统的API。它允许使用者在每一帧动画渲染时获取当前时间戳,并基于时间计算动画进度,从而手动实现高性能的自定义动画逻辑。

API:

withFrameNanos:是一个挂起函数,用于在协程中以帧级精度执行动画逻辑,并返回当前帧的时间戳

栗子:

Kotlin 复制代码
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.drawscope.translate

@Composable
fun WithFrameNanosDemo() {
    var xPosition by remember { mutableStateOf(0f) }

    LaunchedEffect(Unit) {
        var lastFrameTime = 0L
        while (true) {
            withFrameNanos { frameTime ->
                if (lastFrameTime != 0L) {
                    val deltaTime = (frameTime - lastFrameTime) / 1_000_000_000f
                    xPosition += 300 * deltaTime
                    if (xPosition > 1000f) xPosition = 0f
                }
                lastFrameTime = frameTime
            }
        }
    }

    Canvas(modifier = Modifier.fillMaxSize()) {
        translate(left = xPosition) {
            drawCircle(Color.Cyan, radius = 60f, center = Offset(200f, size.height / 2))
        }
    }
}
Kotlin 复制代码
import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.drawscope.translate
import androidx.compose.ui.unit.dp

@Composable
fun PhysicsWithFrameNanosDemo() {
    data class BallState(
        val x: Float = 100f,
        val y: Float = 200f,
        val vx: Float = 12f,
        val vy: Float = 0f,
    )

    val ball = remember { mutableStateOf(BallState()) }
    val radius = 40.dp.value

    LaunchedEffect(Unit) {
        var lastTime = 0L
        val gravity = 9.8f * 50
        val bounce = 0.8f

        while (true) {
            withFrameNanos { frameTime ->
                if (lastTime == 0L) {
                    lastTime = frameTime
                    return@withFrameNanos
                }

                val dt = (frameTime - lastTime) / 1_000_000_000f
                lastTime = frameTime
                var (x, y, vx, vy) = ball.value
                vy += gravity * dt
                x += vx
                y += vy

                val maxX = 1000f - radius * 2
                val maxY = 2000f - radius * 2

                if (x < 0 || x > maxX) vx *= -bounce
                if (y > maxY) {
                    vy *= -bounce
                    y = maxY
                }

                ball.value = BallState(x, y, vx, vy)
            }
        }
    }

    Canvas(modifier = Modifier.fillMaxSize()) {
        translate(ball.value.x, ball.value.y) {
            drawCircle(Color.Magenta, radius)
        }
    }
}

注意

1 必须在协程中调用

2 避免阻塞主线程

3 时间单位转换 frameTimeNanos是纳秒(1e-9 秒),通常需要转换为毫秒或秒

相关推荐
.Hypocritical.7 小时前
Maven笔记——2
java·笔记·maven
乐橙开放平台7 小时前
养殖 SaaS 笔记:乐橙 IoT 物模型管环境,视频 OpenAPI 管回看
数据库·笔记·物联网·mysql·音视频
love530love16 小时前
【笔记】AutoClaw NSIS 安装器卡死、进程杀不掉、目录删不了?我是这么解决的
人工智能·windows·笔记·agent
谙弆悕博士18 小时前
系统集成项目管理工程师教程(第3版)笔记——第2章:信息技术发展
笔记·计算机网络·信息安全·学习方法·业界资讯·软考·系统分析师
吃着火锅x唱着歌19 小时前
Effective C++ 学习笔记 条款37 绝不重新定义继承而来的缺省参数值
c++·笔记·学习
风曦Kisaki19 小时前
# Linux笔记:操作系统优化与资源管理
linux·运维·服务器·笔记
阿米亚波20 小时前
【C++】流式数据输入处理(不完全整理)
开发语言·c++·笔记
zhangrelay21 小时前
笔记本轻量高品质延寿工具完整分系统清单
运维·笔记·学习
巴巴媛66621 小时前
STM32学习笔记【38.DHT11实验】
笔记·stm32·学习
caimouse1 天前
MM 学习笔记 01:miarm.h 核心头文件分析
笔记·学习·reactos