动画属性与多个动画的属性绑定

时间:2017-03-06 15:48:06

标签: qt animation qml qtquick2

考虑这个例子:

import QtQuick 2.7
import QtQuick.Controls 2.0

ApplicationWindow {
    id: appWindow
    width: 1024
    height: 800
    visible: true

    Rectangle {
        id: rect1
        property bool active: true
        opacity: active ? 1 : 0
        height: 300 * opacity
        width: 300 * opacity
        Behavior on opacity { NumberAnimation { duration: 1000 } }
        MouseArea { anchors.fill: parent; onClicked: parent.active = false }
        color: 'cornflowerblue'
    }

    Rectangle {
        id: rect2
        property bool active: true
        x: 305
        opacity: active ? 1 : 0
        height: active ? 300 : 0
        width: active ? 300 : 0
        Behavior on opacity { NumberAnimation { duration: 1000 } }
        Behavior on height { NumberAnimation { duration: 1000 } }
        Behavior on width { NumberAnimation { duration: 1000 } }
        MouseArea { anchors.fill: parent; onClicked: parent.active = false }
        color: 'steelblue'
    }
}

我有两个Rectangle具有相同的可观察行为:点击后,它们会以不透明度和大小淡化。

在内部,它同时运行的Animation s的数量不同 - 1或3: 1 or 3 animations

截至目前,我主要使用模式格式rect1,并且仅在绑定不必要的情况下使用复杂rect2。但是我想知道,如果动画系统有一些魔力,那么优化单个属性的动画,而绑定可能性能较差。

在哪些用例中使用模式rect1以及何时使用rect2的方法更明智?

编辑还有第三个选项可以通过OpacityAnimator移动到渲染线程。现在我不能再绑定到不透明度,因为它会在动画结束时跳转到0。

Rectangle {
        id: rect3
        property bool active: true
        opacity: active ? 1 : 0
        height: active ? 300 : 0
        x: 610
        width: height
        Behavior on opacity { OpacityAnimator { duration: 1000 } }
        Behavior on height { NumberAnimation { duration: 1000 } }
        MouseArea { anchors.fill: parent; onClicked: parent.active = false }
        color: 'dodgerblue'
    }

编辑2 要解决 Ansh Kumar 的答案: enter image description here 这是QML Profiler的摘录。您可以看到,rect2动画期间既没有绑定也没有JavaScript运行,这与heightwidth (有效)绑定的时间不同opacity中的rect1width (有效)绑定到height中的rect3

此外,动画的来源显示JS的痕迹很少。我无法将其检查到所有深度,但似乎只有ScriptAction获得QQMLScriptString,其余只有将输入从var转换为右边的成本type(如果通过使用NumberAnimation等具体动画指定类型。) 此外,据我所知,每个动画都没有循环,但所有动画都有某种update() - 函数左右,通过单个循环调用(运行/注册时)({ {1}})。但这是我不确定的地方。

现在问题仍然存在:动画的实现是否比优化的JS环境更有效,尤其是在创建多个对象和其他东西时。

1 个答案:

答案 0 :(得分:1)

QML中有两种类型的绑定:优化绑定和非优化绑定。保持绑定表达式尽可能简单是一个好主意,因为QML引擎使用优化的绑定表达式求值程序,它可以评估简单的绑定表达式,而无需切换到完整的JavaScript执行环境。与更复杂(非优化)的绑定相比,这些优化的绑定的评估效率更高。优化绑定的基本要求是访问的每个符号的类型信息必须在编译时知道

当绑定知道它们正在使用的对象和属性的类型时,它们是最快的。动画属性将导致重新评估引用该属性的任何绑定。通常,这是所期望的。 opacity中的heightwidthrect2会重新评估为完整的JavaScript执行环境,而rect1则会被重新评估。 widthheight经过优化的绑定表达式求值程序并进行了优化,以提供更高效的绑定,因为它们的对象类型在编译时是已知的。查看bindinganimations了解详情。

修改

在C ++环境中进行评估是正确的。我找到了以下信息。

渲染引擎应该实现一致的每秒60帧的刷新率。 60 FPS意味着在可以进行处理的每个帧之间有大约16毫秒(正好是16.6667毫秒),其中包括将绘图基元上传到图形硬件所需的处理。 This表示动画与垂直刷新同步,因此每16.66毫秒一次,恰好是一帧帧。

while (animationIsRunning) {
    processEvents();
    advanceAnimations();
    paintQMLScene();
    swapAndBlockForNextVSync();
}

因此,在rect1中,您已设置duration: 1000并将heightopacity height: 300 * opacity绑定width opacity QML profiler那么绑定应该被调用大约60次?如果您看到statistics的{​​{1}}输出,您会找到以下内容

binding1

预期的通话次数约为60(正好是63)。现在,如果您将持续时间更改为2000,则呼叫次数将加倍。

binding2

由于必须计算300 * opacity,因此QML应调用JavaScript环境约60次(duration: 1000时)

java

正如预期的那样,大约被召唤了60次。

NumberAnimation怎么样,是用JavaScript还是C ++实现的?当然,你用C ++实现它是正确的,Here是它的声明的链接。因此,在rect1中我们曾使用NumberAnimation一次,而rect2我们已经使用了3次。因此,应创建总共4个NumberAnimation个实例。

create

因此,rect1总共有大约120个绑定和JavaScript调用,而在rect2中没有绑定和JavaScript调用,因此rect2的动画应该更快,但是问题是,会有任何重大改进吗?由于QtCreator的免费版本没有配备CPU分析器,我无法研究问题的这一部分(CPU Usage Qt)。如果有人有Qt的商业版,请更新我的假设。我认为rect2最适合使用,因为呼叫次数减少了。