Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. How to animate a widget like discord 'zoom animation'

How to animate a widget like discord 'zoom animation'

Scheduled Pinned Locked Moved Unsolved General and Desktop
5 Posts 3 Posters 834 Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    Marcia3x
    wrote on 16 Jan 2023, 01:51 last edited by
    #1

    How to create this kind of animation in qt?
    I mean the 'zoom-out' animation when I click on the 'User Settings' button and at the Esc button
    https://youtu.be/Z6Q-QUDLZ8E

    The animation at a slower speed:
    https://youtu.be/bcPs_kILo10

    1 Reply Last reply
    0
    • J Offline
      J Offline
      jeremy_k
      wrote on 16 Jan 2023, 05:44 last edited by
      #2

      https://doc.qt.io/qt-5/animation-overview.html

      The video looks like a combination of opacity and scale animations.

      Asking a question about code? http://eel.is/iso-c++/testcase/

      1 Reply Last reply
      1
      • M Offline
        M Offline
        Marcia3x
        wrote on 17 Jan 2023, 11:33 last edited by
        #3

        What properties is used to create scale?

        J 1 Reply Last reply 17 Jan 2023, 11:54
        0
        • M Marcia3x
          17 Jan 2023, 11:33

          What properties is used to create scale?

          J Offline
          J Offline
          jsulm
          Lifetime Qt Champion
          wrote on 17 Jan 2023, 11:54 last edited by
          #4

          @Marcia3x In the link @jeremy_k gave you there is an example:

          QPushButton button("Animated Button");
          button.show();
          
          QPropertyAnimation animation(&button, "geometry");
          animation.setDuration(10000);
          animation.setStartValue(QRect(0, 0, 100, 30));
          animation.setEndValue(QRect(250, 250, 100, 30));
          
          animation.start();
          

          Just do not change x/y, only change width/height.

          https://forum.qt.io/topic/113070/qt-code-of-conduct

          M 1 Reply Last reply 19 Jan 2023, 01:07
          0
          • J jsulm
            17 Jan 2023, 11:54

            @Marcia3x In the link @jeremy_k gave you there is an example:

            QPushButton button("Animated Button");
            button.show();
            
            QPropertyAnimation animation(&button, "geometry");
            animation.setDuration(10000);
            animation.setStartValue(QRect(0, 0, 100, 30));
            animation.setEndValue(QRect(250, 250, 100, 30));
            
            animation.start();
            

            Just do not change x/y, only change width/height.

            M Offline
            M Offline
            Marcia3x
            wrote on 19 Jan 2023, 01:07 last edited by Marcia3x
            #5

            @jsulm said in How to animate a widget like discord 'zoom animation':

            @Marcia3x In the link @jeremy_k gave you there is an example:

            QPushButton button("Animated Button");
            button.show();
            
            QPropertyAnimation animation(&button, "geometry");
            animation.setDuration(10000);
            animation.setStartValue(QRect(0, 0, 100, 30));
            animation.setEndValue(QRect(250, 250, 100, 30));
            
            animation.start();
            

            Just do not change x/y, only change width/height.

            After a lot of search and effort, I did something:

            // stackedwidget.h
            class StackedWidget : public QStackedWidget
            {
            
                Q_OBJECT
            public:
            
                enum QEasingCurve::Type m_animationtype = QEasingCurve::Type::OutQuart;
                int m_speed = 1000;
                int m_now;
                int m_next;
                bool animation_active = false;
                QPoint m_pnow;
                QParallelAnimationGroup* animgroup;
            
                StackedWidget(QWidget* parent) : QStackedWidget(parent)
                {
                    QWidget* widget = new QWidget();
                    QGridLayout* widget_layout = new QGridLayout();
            	    widget->setLayout(widget_layout);
            
                    QPushButton* button;
                    for (size_t i = 0; i < 10; i++)
                    {
                        button = new QPushButton();
                        button->setText("Button " + QString::number(i));
                        button->setStyleSheet(R"(
            	            background-color:  #3c3f45;
                            border-radius: 4px;            
            	            color: rgba(255, 255, 255, 0.4);
            	            font-size: 15px;
            	            font-weight: 600;	
                        )");
                        widget_layout->addWidget(button);
                    }
            
                    button->setText("Change Page");
            
                    connect(button, &QPushButton::clicked, [=]
                    {
                        animimateToPage(1);
                    });  
            
            
            
                    QWidget* widget_2 = new QWidget();
                    QGridLayout* widget_layout_2 = new QGridLayout();
            	    widget_2->setLayout(widget_layout_2);
            
                    for (size_t i = 0; i < 10; i++)
                    {
                        button = new QPushButton();
                        button->setText("================ " + QString::number(i));
                        button->setStyleSheet(R"(
            	            background-color:  #3c3f45;
                            border-radius: 4px;            
            	            color: rgba(255, 255, 255, 0.4);
            	            font-size: 15px;
            	            font-weight: 600;	
                        )");
                        widget_layout_2->addWidget(button);
                    }
            
                    button->setText("return");
                    
                    connect(button, &QPushButton::clicked, [this]
                    {
                        animimateToPage(0);
                    });  
            
            
            
                    addWidget(widget);
                    addWidget(widget_2);
                }
            
            
            
                void animimateToPage(int index)
                {
            
                    if (animation_active)
                        return;
            
                    animation_active = true;
            
                    int now = currentIndex();
                    int next = indexOf(widget(index));
            
                    int offsetx = frameRect().width();
                    int offsety = frameRect().height();
            
                    widget(next)->setGeometry(0, 0, offsetx, offsety);
            
                    QPoint pnext = widget(next)->pos();
                    QPoint pnow = widget(now)->pos();
                    m_pnow = pnow;
                    //widget(next)->move(pnext.x() - offsetx, pnext.y() - offsety);
            
                    QRect rnext = widget(next)->geometry();
                    QRect rnow = widget(now)->geometry();
            
                    int addw = 300;
                    int addh = 100;
            
                    widget(next)->show();
                    widget(next)->raise();
            
                    QPropertyAnimation* animnow = new QPropertyAnimation(widget(now), "geometry");
                    animnow->setDuration(m_speed);
                    animnow->setEasingCurve(m_animationtype);
                    animnow->setStartValue(QRect(0, 0, rnow.width(), rnow.height()));
                    animnow->setEndValue(QRect(0, 0, rnow.width() - addw, rnow.height() - addh));
            
                    QGraphicsOpacityEffect* animnow_op_eff = new QGraphicsOpacityEffect();
                    widget(now)->setGraphicsEffect(animnow_op_eff);
                    QPropertyAnimation* animnow_op = new QPropertyAnimation(animnow_op_eff, "opacity");
                    animnow_op->setDuration(m_speed);
                    animnow_op->setStartValue(1);
                    animnow_op->setEndValue(0);
            
            
            
                    QPropertyAnimation* animnext = new QPropertyAnimation(widget(next), "geometry");
                    animnext->setDuration(m_speed);
                    animnext->setEasingCurve(m_animationtype);
                    animnext->setStartValue(QRect(0, 0, rnext.width() - addw, rnext.height() - addh));
                    animnext->setEndValue(QRect(0, 0, rnext.width(), rnext.height()));
            
                    QGraphicsOpacityEffect* animnext_op_eff = new QGraphicsOpacityEffect();
                    animnext_op_eff->setOpacity(0);
                    widget(next)->setGraphicsEffect(animnext_op_eff);
                    QPropertyAnimation* animnext_op = new QPropertyAnimation(animnext_op_eff, "opacity");
                    animnext_op->setDuration(m_speed);
                    animnext_op->setStartValue(0);
                    animnext_op->setEndValue(1);
            
            
            
                    animgroup = new QParallelAnimationGroup;
                    animgroup->addAnimation(animnow);
                    animgroup->addAnimation(animnext);
                    animgroup->addAnimation(animnow_op);
                    animgroup->addAnimation(animnext_op);
            
            
            
                    QObject::connect(animgroup, &QParallelAnimationGroup::finished, this, &StackedWidget::animationDoneSlot);
                    m_next = next;
                    m_now = now;
                            
                    animgroup->start(QAbstractAnimation::DeleteWhenStopped);
                }
            
            
            
                void animationDoneSlot()
                {
                    setCurrentIndex(m_next);
                    widget(m_now)->hide();
                    widget(m_now)->move(m_pnow);
            
                    widget(m_now)->setGraphicsEffect(nullptr);
                    widget(m_next)->setGraphicsEffect(nullptr);
            
                    animation_active = false;
                }
            };
            

            #include "stackedwidget.h"
            
            MainWindow::MainWindow(QWidget *parent)
                : QMainWindow(parent)
            {
                ui.setupUi(this);
            
                ui.centralWidget->setStyleSheet("#centralWidget { background-color: #36393f; }");
            
                QGridLayout* layout = new QGridLayout();
                ui.centralWidget->setLayout(layout);
            
                StackedWidget* stacked_widget = new StackedWidget(this);    
                layout->addWidget(stacked_widget);
            
                return;
            }
            

            I have added some random buttons which colors similar to those seen in discord just to help check if the
            animation is 'correct'.

            Result:
            QtWidgetsApplication9_UPCjEsBztG.gif

            Looks like there's any kind of flickering in the animation, and I'm struggling with how to calculate the values to use in
            start/end of the geometry animation.

            The animation I'm referring to:
            https://i.imgur.com/fC2cTCY.gif (i reduced the speed of the animation, also, click on the image to enlarge it)
            https://imgur.com/a/nUuOGSn (default speed)

            1 Reply Last reply
            0

            5/5

            19 Jan 2023, 01:07

            • Login

            • Login or register to search.
            5 out of 5
            • First post
              5/5
              Last post
            0
            • Categories
            • Recent
            • Tags
            • Popular
            • Users
            • Groups
            • Search
            • Get Qt Extensions
            • Unsolved