天天看點

【Qt】動畫使用及慣性效果

動畫慣性

效果

【Qt】動畫使用及慣性效果

收下來和展開會有一個慣性的效果,這個使用QPropertyAnimation可以實作的,是通過設定setEasingCurve來實作的

我們來看看這個函數,傳參是傳QEasingCurve的類型,根據官方文檔的介紹,QEasingCurve類提供用于控制動畫的緩動曲線,我們上面效果的動畫就是有現成的緩動曲線,QEasingCurve總共支援一下的緩動曲線

【Qt】動畫使用及慣性效果

這些緩動的效果幫助文檔都寫有相關的曲線,下面我們結合這個例子來看一下

上面的例子我們使用到了InBack和OutBack兩種。

代碼

m_maxRect = QRect(0, 12, 48, 438);
m_middleRect = QRect(0, 150, 48, 300);
m_minRect = QRect(0, 384, 48, 66);

m_pAnimal = new QPropertyAnimation(this, "geometry", this);
m_pAnimal->setDuration(1000);

m_pAnimal->setStartValue(m_maxRect);
m_pAnimal->setEndValue(m_middleRect);
m_pAnimal->setDirection(m_middleDirection);
if(m_middleDirection == QPropertyAnimation::Forward) {
     m_pAnimal->setEasingCurve(QEasingCurve::OutBack);
     m_middleDirection = QPropertyAnimation::Backward;
     m_pAnimal->setDuration(800);
}
else {
     m_pAnimal->setEasingCurve(QEasingCurve::InBack);
     m_middleDirection = QPropertyAnimation::Forward;
     m_pAnimal->setDuration(1100);
}
           

這裡隻貼出部分代碼,向下收起使用的是OutBack,向上展開使用的是InBack

我們來看這兩種的曲線:

【Qt】動畫使用及慣性效果
【Qt】動畫使用及慣性效果

對于OutBack,縱坐标value相當于動畫設定的屬性值,我們例子中就是geometry值,當縱坐标的值從小到大變化時,後半部分的值會比最終值大再變成最終值。例子中點選收起來的時候,geometry的y值是從小到大變化的,最後比有一段往下沉的動畫再回到最終設定的位置。

對于InBack曲線,同樣的,當縱坐标的值從小到大變化時,一開始會有一部分小于初始值,最後變成最終值;反過來看,就是從最終值回到初始值,在回到初始值之前值會比初始值小。例子中點選展開的時候,y值是從大變小的,是以我們要反過來看,就是回到初始值之前會有向上伸出的效果,就是y值要比初始值小。

是以我們選用曲線的時候,要看我們的屬性值是從小到大變化還是大到小變化,根據曲線來選我們想要的緩動效果

相關的Qt官方例子:

1.animatedtiles

2.blurpicker

動畫組

上面的動畫效果中,我們看到展開的時候,上面的三個按鈕是逐漸顯現出來的,這個效果就是用到動畫組,串行動畫組QSequentialAnimationGroup,就是多個動畫逐漸執行。

代碼

//串行動畫組
    m_pBtnShowAnimal = new QSequentialAnimationGroup(this);
    QList<QAbstractButton*> btnList = m_pBtnGroup->buttons();
    for(int i = 2; i >= 0; --i) {
        QAbstractButton *btn = btnList.at(i);
        QPropertyAnimation *btnAnimal = addBtnHideAnimal(btn, btn->pos());
        m_pBtnShowAnimal->addAnimation(btnAnimal);
    }

QPropertyAnimation * MainWindow::addBtnHideAnimal(QWidget *item, QPoint pos)
{
    QPropertyAnimation *animation = new QPropertyAnimation(item, "geometry", this);
    animation->setDuration(200);
    animation->setStartValue(QRect(qobject_cast<QWidget *>(item->parent())->width()/2,         
    item->y() + item->height()/2, 0, 0));
    animation->setEndValue(QRect(pos, item->size()));
    return animation;
}
           

執行的循序和添加的循序一樣,用法很簡單。

與串行動畫組相對應的是并行動畫組QParallelAnimationGroup

動畫過程

效果

【Qt】動畫使用及慣性效果

代碼

m_pBtnStopAnimal = new QPropertyAnimation(m_pBtnGroup->button(6), "geometry", this);
    m_pBtnStopAnimal->setDuration(800);
    QRect originRect = m_pBtnGroup->button(6)->geometry();
    m_pBtnStopAnimal->setKeyValueAt(0, originRect);
    m_pBtnStopAnimal->setKeyValueAt(0.2, QRect(originRect.x() - 6, originRect.y() - 6,
                                                 originRect.width() + 12, originRect.height() + 12));
    m_pBtnStopAnimal->setKeyValueAt(0.6, QRect(originRect.x() - 6, originRect.y() - 6,
                                                 originRect.width() + 12, originRect.height() + 12));
    m_pBtnStopAnimal->setKeyValueAt(0.7, originRect);
    m_pBtnStopAnimal->setKeyValueAt(0.9, QRect(originRect.x() - 3, originRect.y() - 3,
                                                 originRect.width() + 6, originRect.height() + 6));
    m_pBtnStopAnimal->setKeyValueAt(1, originRect);
    static int animalcout = 0;
    connect(m_pBtnStopAnimal, &QPropertyAnimation::finished, this, [=](){
        ++animalcout;
        //執行2次
        if(animalcout < 3){
            QThread::msleep(300);
            m_pBtnStopAnimal->start();
        }
        else {
            animalcout = 0;
        }
    });
           

這個效果我們使用的是setKeyValueAt給動畫設定更細的步驟,差別于一般的設定初始值和最終值,動畫效果是按鈕變最大,有個停頓的時間,回到初始大小,又變到稍微大,最後回到初始大小這麼一個效果,就是這麼幾個過程,其中變到最大停頓一下,通過設定連續兩個狀态0.2和0.6都是最大狀态,那這部分時間都會維持最大的狀态,看起來就像停頓了一下。

結尾

一個小小的例子用到qt動畫的很多東西,還是有一定的參考價值的。

完整的代碼可到我的csdn資源下載下傳處下載下傳

下載下傳位址

繼續閱讀