关于qml 动画性能问题分析,做流畅动画
发布日期:2021-05-17 19:30:19 浏览次数:12 分类:精选文章

本文共 3211 字,大约阅读时间需要 10 分钟。

QML动画性能优化:流畅动画的实现方法

在开发过程中,动画功能是无处不在的。对于台式PC而言,动画效果可能显得流畅无缝,但在资源受限的嵌入式设备上,动画性能就显得尤为重要。优化动画性能,能够显著提升用户体验。本文将详细分析两种常见的动画实现方式,并探讨如何实现流畅动画。


背景

在嵌入式设备上,动画的流畅度直接关系到用户体验。如果动画实现不当,不仅会影响用户满意度,还可能导致设备性能过负。本文将从两种常见动画实现方式入手,分析其优缺点,并提出优化建议。


动画实现方式一:频繁读取图片资源

方法原理:这种方法通过频繁从存储器读取图片资源,来实现动画效果。每次需要显示下一帧时,都会从存储器加载相应的图片文件。

优缺点分析

  • 优点:实现简单,无需预处理。
  • 缺点
    • 加载时间长,尤其是在存储器速度较慢时。
    • 内存占用大,尤其是对大量帧数的动画而言。
    • 需要频繁的GPU刷新,增加对硬件的负担,导致帧率下降。

典型代码示例

Item {    id: root    width: 1920    height: 720    property int carMoveIndex: -1    Component.onCompleted: {        moveTimer.start();    }    Timer {        id: moveTimer        interval: 40        running: false        repeat: true        onTriggered: {            if (carMoveIndex < 24) {                carMoveIndex++;            }            if (carMoveIndex === 24) {                moveTimer.stop();            }        }    }    Image {        id: car_move        source: qsTr(":/move_%1.png").arg(carMoveIndex)    }}

优化建议:对于这种方法,可以通过预加载技术,提前将所有帧的图片资源预存入内存,这样可以减少加载时间并降低内存占用。


动画实现方式二:使用 AnimatedSprite

方法原理:这种方法通过使用 AnimatedSprite 组件一次性加载所有帧的图片资源,实现动画效果。在运行时,按照预设的帧率和帧数,自动播放动画。

优点

  • 内存优化:所有帧的图片资源在初始化时一次性加载到内存中,减少了运行时的加载开销。
  • 流畅性能:运行时动画流畅,硬件加速效果显著,尤其在嵌入式设备上表现优异。

注意事项

  • 必须设置属性:确保 widthheightframeWidthframeHeight 等属性的正确设置,否则可能导致图片显示错误。
  • 帧率设置frameRate 必须避免设置为 0,否则会导致浮点运算异常,程序退出。
  • 插帧处理:默认情况下,AnimatedSprite 会启用插帧功能(interpolate: true)。如果帧数大于 frameCount,插帧可能导致帧数不符,与设计不匹配,进而引发帧率下降或闪烁效果。建议在需要时关闭插帧功能(interpolate: false)。
  • 典型代码示例

    AnimatedSprite {    id: carMovingAnimated    width: 999    height: 397    source: ":/modeRoad/car_moving_combine_h.png"    frameWidth: 999    frameHeight: 397    frameCount: 25    frameRate: 10    running: false    frameX: 0    frameY: 0}

    动画渲染:Animation 和 Animator 的区别

    在 QtQuick 中,动画渲染可以通过 AnimationAnimator 来实现,它们分别运行在不同的线程:

    • Animation:运行在 GUI 主线程。如果主线程发生卡顿,动画也会随之卡顿。
    • Animator:运行在渲染线程。由于渲染线程独立于主线程,主线程卡顿不会影响动画效果。

    代码对比示例

    /* Animation 和它的派生类运行在 GUI 线程,卡顿 */import QtQuick 2.6import QtQuick.Window 2.2Window {    visible: true    width: 600    height: 400    Rectangle {        //--紫色受控Animation,卡顿        id: rectangle1        x: 50        y: 50        width: 100        height: 100        color: "#ff00ff"    }    Rectangle {        //--黄色,受控Animator,流畅        id: rectangle2        x: 50        y: 250        width: 100        height: 100        color: "#ffff00"    }    NumberAnimation {        id: animation        target: rectangle1        property: "x"        from: 50        to: 450        duration: 1000    }    XAnimator {        id: animator        target: rectangle2        from: 50        to: 450        duration: 1000    }    Timer {        id: timer        interval: 100        repeat: true        running: animation chạy        onTriggered: {            var last = Date.now();            while (Date.now() - last < 50) {                // 模拟主线程耗时任务            }        }    }    MouseArea {        anchors.fill: parent        onClicked: {            animation chạy            animator chạy            timer chạy        }    }}

    效果对比

    • Animation:运行在 GUI 主线程,容易因主线程卡顿而导致动画卡顿。
    • Animator:运行在渲染线程,不受主线程卡顿影响,动画流畅。

    总结

    在嵌入式设备上实现流畅动画,关键在于选择合适的动画实现方式,并通过优化技术提升性能。在选择 AnimatedSprite 时,注意设置相关属性,避免插帧问题;在选择 AnimationAnimator 时,根据线程运行特性进行权衡。通过上述方法,可以显著提升动画性能,提升用户体验。

    上一篇:ubuntu 18.04LTS + MATLAB2018b启动opengl 硬件加速
    下一篇:解决 libstdc++.so.6: version `GLIBCXX_3.4.14' not found 问题

    发表评论

    最新留言

    不错!
    [***.144.177.141]2025年04月27日 08时02分42秒