動畫慣性
效果
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiZpdmLwAjNxQjMzMjMxEzNwAjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.gif)
收下來和展開會有一個慣性的效果,這個使用QPropertyAnimation可以實作的,是通過設定setEasingCurve來實作的
我們來看看這個函數,傳參是傳QEasingCurve的類型,根據官方文檔的介紹,QEasingCurve類提供用于控制動畫的緩動曲線,我們上面效果的動畫就是有現成的緩動曲線,QEasingCurve總共支援一下的緩動曲線
這些緩動的效果幫助文檔都寫有相關的曲線,下面我們結合這個例子來看一下
上面的例子我們使用到了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
我們來看這兩種的曲線:
對于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
動畫過程
效果
代碼
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資源下載下傳處下載下傳
下載下傳位址