属性 绑定动画 属性 与多个动画
Property Binding on Animated Property vs Multiple Animations
考虑这个例子:
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
的数量不同,即同时 运行 - 1 或 3:
截至目前,我主要使用模式形式 rect1
,并且仅在绑定变得不必要地复杂的情况下使用 rect2
。但是我想知道,如果动画系统有一些魔力,可以优化单个 属性 的动画,而绑定的性能可能会较低。
在哪些用例中使用模式 rect1
是有益的,什么时候使用 rect2
的方法更明智?
EDIT 还有第三个选项,它尽可能通过 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 的答案:
这是 QML Profiler
的节选。你可以看到,在 rect2
的动画期间既没有绑定也没有 JavaScript 运行,不像 height
和 width
是 [=57] =](有效地) 绑定到 rect1
中的 opacity
或 width
是 (有效地) 绑定到 height
在 rect3
.
此外,动画源几乎没有 JS
的踪迹。我无法深入研究它,但似乎只有 ScriptAction
得到 QQMLScriptString
,其余的只有将输入从 var
转换为正确的成本类型(如果使用具体动画指定类型,例如NumberAnimation
)。
此外,据我所知,每个动画都没有一个循环,但是所有动画都具有某种 update()
左右的功能,即(当 running/registered 时)由单个循环调用(AnimationTimer
)。但这是我已经不确定的地方。
现在问题仍然存在:动画的实现是否比优化的 JS 环境更有效,尤其是在创建多个对象和填充时。
QML 中有两种类型的绑定:优化绑定和 non-optimized 绑定。保持绑定表达式尽可能简单是个好主意,因为 QML 引擎使用优化的绑定表达式评估器,它可以评估简单的绑定表达式,而无需切换到完整的 JavaScript 执行环境。与更复杂的 (non-optimized) 绑定相比,这些优化绑定的评估效率要高得多。绑定优化的基本要求是编译时必须知道每个访问的符号的类型信息。
当他们知道他们正在使用的对象和属性的类型时,绑定是最快的。动画化 属性 将导致任何引用 属性 的绑定成为 re-evaluated。通常,这是需要的。 opacity
、height
和 width
在 rect2
中 re-evaluated 进入完整的 JavaScript 执行环境,而在 rect1
中; width
和 height
通过优化的绑定表达式求值器并进行优化以提供更有效的绑定,因为它们的对象类型在编译时是已知的。查看 binding and also animations 了解更多详情。
编辑
您关于在 C++ 环境中进行评估的说法是正确的。我找到了以下信息。
渲染引擎应达到一致的 60 frames-per-second 刷新率。 60 FPS 意味着每帧之间大约有 16 毫秒(正好是 16.6667 毫秒)可以进行处理,其中包括将绘图图元上传到图形硬件所需的处理。 This 显示动画与垂直刷新同步,因此每 16.66 毫秒一次,并且正好是 pr 帧一次。
while (animationIsRunning) {
processEvents();
advanceAnimations();
paintQMLScene();
swapAndBlockForNextVSync();
}
因此,在 rect1
中,您已设置 duration: 1000
并将 height
与 opacity
(height: 300 * opacity
) 绑定,类似地 width
与 opacity
,所以绑定应该调用 60 次左右?如果您看到 statistics
的 QML profiler
输出,您会发现以下
正如预期的那样,调用次数约为 60(正好是 63)。现在,如果您将持续时间更改为 2000,调用次数将增加一倍。
因为300 * opacity
需要计算,所以QML
应该调用JavaScript环境60次左右(当duration: 1000
)
正如预期的那样,它被调用了大约 60 次。
NumberAnimation
是用 JavaScript 还是 C++ 实现的?当然,您关于它在 C++ 中实现的说法是正确的,Here 是其声明的 link。因此,在 rect1
中我们使用了 NumberAnimation
一次,在 rect2
中我们使用了 3 次。因此,总共应创建 4 个 NumberAnimation
实例。
因此,rect1
总共有大约 120 个绑定和 JavaScript 调用,而在 rect2
中没有绑定和 JavaScript 调用,因此 rect2
应该会更快,但问题是,会有什么明显的改进吗?因为,QtCreator 的免费版本不附带 CPU 分析器,所以我无法研究问题的那部分 (CPU Usage Qt)。如果有人有 Qt 的商业版本,请告诉我我的假设。我真的认为 rect2
最适合使用,因为调用次数减少了。
考虑这个例子:
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
的数量不同,即同时 运行 - 1 或 3:
截至目前,我主要使用模式形式 rect1
,并且仅在绑定变得不必要地复杂的情况下使用 rect2
。但是我想知道,如果动画系统有一些魔力,可以优化单个 属性 的动画,而绑定的性能可能会较低。
在哪些用例中使用模式 rect1
是有益的,什么时候使用 rect2
的方法更明智?
EDIT 还有第三个选项,它尽可能通过 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 的答案:
QML Profiler
的节选。你可以看到,在 rect2
的动画期间既没有绑定也没有 JavaScript 运行,不像 height
和 width
是 [=57] =](有效地) 绑定到 rect1
中的 opacity
或 width
是 (有效地) 绑定到 height
在 rect3
.
此外,动画源几乎没有 JS
的踪迹。我无法深入研究它,但似乎只有 ScriptAction
得到 QQMLScriptString
,其余的只有将输入从 var
转换为正确的成本类型(如果使用具体动画指定类型,例如NumberAnimation
)。
此外,据我所知,每个动画都没有一个循环,但是所有动画都具有某种 update()
左右的功能,即(当 running/registered 时)由单个循环调用(AnimationTimer
)。但这是我已经不确定的地方。
现在问题仍然存在:动画的实现是否比优化的 JS 环境更有效,尤其是在创建多个对象和填充时。
QML 中有两种类型的绑定:优化绑定和 non-optimized 绑定。保持绑定表达式尽可能简单是个好主意,因为 QML 引擎使用优化的绑定表达式评估器,它可以评估简单的绑定表达式,而无需切换到完整的 JavaScript 执行环境。与更复杂的 (non-optimized) 绑定相比,这些优化绑定的评估效率要高得多。绑定优化的基本要求是编译时必须知道每个访问的符号的类型信息。
当他们知道他们正在使用的对象和属性的类型时,绑定是最快的。动画化 属性 将导致任何引用 属性 的绑定成为 re-evaluated。通常,这是需要的。 opacity
、height
和 width
在 rect2
中 re-evaluated 进入完整的 JavaScript 执行环境,而在 rect1
中; width
和 height
通过优化的绑定表达式求值器并进行优化以提供更有效的绑定,因为它们的对象类型在编译时是已知的。查看 binding and also animations 了解更多详情。
编辑
您关于在 C++ 环境中进行评估的说法是正确的。我找到了以下信息。
渲染引擎应达到一致的 60 frames-per-second 刷新率。 60 FPS 意味着每帧之间大约有 16 毫秒(正好是 16.6667 毫秒)可以进行处理,其中包括将绘图图元上传到图形硬件所需的处理。 This 显示动画与垂直刷新同步,因此每 16.66 毫秒一次,并且正好是 pr 帧一次。
while (animationIsRunning) {
processEvents();
advanceAnimations();
paintQMLScene();
swapAndBlockForNextVSync();
}
因此,在 rect1
中,您已设置 duration: 1000
并将 height
与 opacity
(height: 300 * opacity
) 绑定,类似地 width
与 opacity
,所以绑定应该调用 60 次左右?如果您看到 statistics
的 QML profiler
输出,您会发现以下
正如预期的那样,调用次数约为 60(正好是 63)。现在,如果您将持续时间更改为 2000,调用次数将增加一倍。
因为300 * opacity
需要计算,所以QML
应该调用JavaScript环境60次左右(当duration: 1000
)
正如预期的那样,它被调用了大约 60 次。
NumberAnimation
是用 JavaScript 还是 C++ 实现的?当然,您关于它在 C++ 中实现的说法是正确的,Here 是其声明的 link。因此,在 rect1
中我们使用了 NumberAnimation
一次,在 rect2
中我们使用了 3 次。因此,总共应创建 4 个 NumberAnimation
实例。
因此,rect1
总共有大约 120 个绑定和 JavaScript 调用,而在 rect2
中没有绑定和 JavaScript 调用,因此 rect2
应该会更快,但问题是,会有什么明显的改进吗?因为,QtCreator 的免费版本不附带 CPU 分析器,所以我无法研究问题的那部分 (CPU Usage Qt)。如果有人有 Qt 的商业版本,请告诉我我的假设。我真的认为 rect2
最适合使用,因为调用次数减少了。