【问题标题】:Another time source for QML animations?QML 动画的另一个时间来源?
【发布时间】:2015-11-08 19:40:45
【问题描述】:

我正在考虑构建一个 gstreamer 插件,该插件可以渲染动画 QML 图形,以便以后叠加到正在播放的视频上。到目前为止,使用 QML 的想法对我来说看起来很有希望,除了一个问题。我需要能够在视频中进行搜索,并且动画还必须倒带并跳转到所需的时间点。现在我阅读了 QML 文档,发现所有动画通常都是有时间限制的。

所以我的问题是:是否可以将 QML 动画绑定到一些“时间源”,而不是现实世界的时间,这可能不是单调的(实际上,它可以由应用程序操纵)。或者,更一般地说,我可以将 QML 动画绑定到一个数值 X,这样当它发生变化时,我的动画就会进行,并且 X 和动画状态之间存在严格的关系。我希望你能明白。

【问题讨论】:

  • QML 内部设计通常不是很灵活,好像动画组件也不例外。根据您想要做什么,可能会有不同的方法来解决这个问题。您可以轻松实现自定义动画,并且不必遵循内置的设计。您可能只需要一些状态调整。

标签: qt animation qml


【解决方案1】:

此答案仅适用于 NumberAnimation 对象。可能类似的方法也可以用于替换其他Animation 对象。

正如ddriver 已经指出的那样,除了变通之外别无他法。

这是我对问题的解决方案。它可能看起来很复杂,但我可以保证它很容易使用。在此答案的末尾,我使用此代码放置了指向示例项目源代码的链接。你可以试试看。

将这些文件添加到您的项目中:

  • easingvalueforprogress.h

#ifndef EASINGVALUEFORPROGRESS_H
#define EASINGVALUEFORPROGRESS_H

#include <QObject>
#include <QEasingCurve>

class EasingValueForProgress : public QObject
{
    Q_OBJECT
public:
    explicit EasingValueForProgress(QObject *parent = 0);

    Q_INVOKABLE double getValue(int easingEnum, double progress){
        QEasingCurve easing((QEasingCurve::Type)easingEnum);
        return easing.valueForProgress(progress);
    }

signals:

public slots:
};

#endif // EASINGVALUEFORPROGRESS_H
  • easingvalueforprogress.cpp

#include "easingvalueforprogress.h"

EasingValueForProgress::EasingValueForProgress(QObject *parent) : QObject(parent)
{

}
  • XValueAnimation.qml

import QtQuick 2.0

Item {
    id: xValueAnimator

    property Item target
    property string targetProperty
    property double from
    property double to
    property int easing: Easing.Linear
    property double xValue

    onXValueChanged: {
        if (target.hasOwnProperty(targetProperty)) {
            target[targetProperty] = calculateCurrentValue(
                        from, to, easing, xValue);
        }
        else
            console.error("XValueAnimator: target:", target,
                          "does not have property", targetProperty)
    }

    function calculateCurrentValue(
        defaultFrom, defaultTo, animationEasing, xValue) {

        return defaultFrom + (defaultTo - defaultFrom)
                * easingValueForProgress.getValue(animationEasing, xValue)
    }
}

将此添加到您的 main.cpp:

#include <QQmlContext>
#include "easingvalueforprogress.h"

    EasingValueForProgress easingValueForProgress;
    engine.rootContext()->setContextProperty(
                "easingValueForProgress", &easingValueForProgress);

现在你可以像这样使用它(而不是NumberAnimation对象):

XValueAnimator {
    target: object_you_want_to_affect     // for example id of the object
    targetProperty: "property_to_affect"  // for example "x"
    from: 100
    to: 500
    easing: Easing.OutQuad                // omit to use Easing.Linear
    xValue: myXValue                      // your property holding values from 0 to 1
}


Here我提供了工作示例项目。欢迎下载并测试它。

【讨论】:

  • 谢谢 Filip,我将您的回答标记为已接受。但是,随着时间的推移,我有更多的时间去思考这一切,我相信我不会走 QML 路线。但如果我接受它,我会使用你的答案。再次感谢!
猜你喜欢
  • 2021-07-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-24
  • 2010-10-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多