32.qt quick-模仿QQ登入介面實現3D旋轉(Rotation、Flipable)

諾謙發表於2021-06-21

 要想模仿QQ登入介面的3D旋轉,我們需要學習Rotation和Flipable.由於沒找到QQ的資源圖,所以我們以兩個圖片為例模仿QQ的3D旋轉,如下圖所示:

最終效果如下所示:

 

1.Rotation介紹

Rotation型別提供了一種通過旋轉型別轉換旋轉Item的方法。

它允許(z軸)相對於任意點進行旋轉,還提供了一種為item指定類似3d的旋轉的方法。這比旋轉屬性提供了更多對專案旋轉的控制。

它的引數如下所示:

  • origin.x、origin.y : real,旋轉的原點,預設情況下,原點是(0,0),父物件的左上角
  • axis.x、axis.y、axis.z : real,要旋轉的軸,如果你想實現一個類似3d的旋轉,你必須指定origin原點和軸。對於一個2D旋轉其實就是 (axis { x: 0; y: 0; z: 1 }).
  • angle : real,順時針方向旋轉的角度。

大家可以參考如下圖所示:

設定原點為中心點,且axis { x: 0; y: 1; z: 0 }時, 那麼此時就是3D旋轉如下圖所示:

 

大家如果還沒理解的話,並且可能會懵逼為什麼2D旋轉是 "axis { x: 0; y: 0; z: 1 }"的話.

可以看以下程式碼,如下所示:

Row {
          x: 10; y: 10

          spacing: 10

          anchors.centerIn: parent

          Image { source: "qrc:/head.jpg"; antialiasing: true; rotation: 30}

          Image {
              id: image
              source: "qrc:/head.jpg"
              antialiasing: true
              transform: Rotation {
                  origin.x: image.sourceSize.width/2;
                  origin.y: image.sourceSize.height/2;
                  axis { x: 0; y: 0; z: 1 }
                  angle: 30
              }
          }
}

效果如下所示:

 

 

可以看到axis { x: 0; y: 0; z: 1 }其實和rotation沒區別,都是2D旋轉

這是因為"axis { x: 0; y: 0; z: 1 }"設定的軸線是z座標的,所以旋轉的時候只有xy座標進行轉換.如下圖所示:

 

2.Flipable介紹
Flipable可以明顯地“翻轉”在其前後兩側,就像一張卡片。它可以與Rotation、State和Transition型別一起使用,以產生翻轉效果。
它的引數如下所示:

  • front : Item,指定反轉前的頁面
  • back : Item,指定反轉後的頁面
  • side : enumeration ,只讀屬性,讀出目前的頁面是反轉前的還是反轉後的,可以是Flipable.Front 或者 Flipable.Back

最終程式碼如下所示:

import QtQuick 2.12
import QtQuick.Window 2.12
Window {
    id: wind
    visible: true
    width: flipable.width
    height: flipable.height * 1.3
    flags: Qt.Window | Qt.FramelessWindowHint
    property var angleVlue : 0
    color: "#00000000"

    Flipable {
       id: flipable
       width: 426
       height: 327
       y:  (wind.height - height) /2
       property bool flipped: false

       front: Image {
           id: frontImage
           anchors.fill: flipable
           source: "qrc:/1.png"
           smooth: true
           antialiasing: true

       }
       back: Image {
           id: backImage
           anchors.fill: flipable
           source: "qrc:/2.png"
           smooth: true
           antialiasing: true
       }


       transform: Rotation {
           id: rotation
           origin.x: flipable.width/2
           origin.y: flipable.height/2
           axis { x: 0; y: 1; z: 0 }     // set axis.y to 1 to rotate around y-axis
           angle: 0    // the default angle

       }

       states: State {
           name: "back"
           PropertyChanges { target: rotation; angle: 180 }
           when: flipable.flipped
       }

       transitions: Transition {
           NumberAnimation { target: rotation; property: "angle"; duration: 1000 ; easing.type: Easing.OutQuad}
       }

       MouseArea {
           anchors.fill: parent
           onClicked: {
               flipable.flipped = !flipable.flipped
           }
       }
    }
}

 

該文章demo已上傳群檔案,需要的自行下載 

 

 

 

 

 

相關文章