2017-09-26 67 views
1

使用QtQuick,我在中繼器中有一行5個圖像。我想在懸停上實現一個類似於MacOS Dock動畫的動畫。下面是引用圖片:QML中的MacOS dock類組件

MacOS Dock

爲了進一步打破它,這裏就是我試圖完成。這些圖片,懸停時,應採取行動如下:

  • 徘徊圖像擴大
  • 相鄰圖像擴大,但稍微少
  • 鏡像不能在擴展

這裏重疊是代碼我至今

Row { 
    spacing: 2 
    anchors.bottom: parent.bottom 
    anchors.bottomMargin: 30 
    anchors.horizontalCenter: parent.horizontalCenter 

    Repeater { 
     id: iconRepeater 
     model: iconColors() 
     Image { 
     source: "icons/" + modelData + ".png" 
     scale: mouseArea.containsMouse ? 1.5 : 1.0 
     MouseArea { 
      id: mouseArea 
      anchors.fill: parent 
      hoverEnabled: true 
      onClicked: endTimer() 
     } 
     Behavior on scale { 
      PropertyAnimation { 
      duration: 75 
      } 
     } 
     } 
    } 
    } 

這擴大你將鼠標懸停在圖片,但我似乎不能也影響了巾幗不讓鬚眉ghbors。任何建議表示讚賞!

+0

呀,這不是因爲行會工作使用間距的寬度,改變比例不會改變寬度。 – dtech

回答

5

我建議稍微更強大的解決方案,那就是你有過縮放係數和控制的影響的進一步蔓延和腐敗:

enter image description here

Column { 
    Slider { 
     id: foff 
     from: 1 
     to: 5 
     stepSize: 1 
     value: 2 
     snapMode: Slider.SnapAlways 
    } 
    Slider { 
     id: sf 
     from: 0.5 
     to: 2.5 
     stepSize: 0.5 
     value: 0.5 
     snapMode: Slider.SnapAlways 
    } 
    Slider { 
     id: dmp 
     from: 1 
     to: 5 
     stepSize: 1 
     value: 1 
     snapMode: Slider.SnapAlways 
    } 
    } 

    Row { 
    id: row 
    anchors.bottom: parent.bottom 
    anchors.bottomMargin: 30 
    anchors.horizontalCenter: parent.horizontalCenter 

    property int falloff: foff.value // how many adjacent elements are affected 
    property int current: -1 
    property real scaleFactor: sf.value // that's how much extra it scales 
    property real damp: dmp.value // decay of influence 

    Repeater { 
     id: iconRepeater 
     model: 10 
     Rectangle { 
     width: 50 * pseudoScale 
     height: width 
     anchors.bottom: parent.bottom 
     color: "red" 
     border.color: "black" 
     property real pseudoScale: { 
      if (row.current == -1) return 1 
      else { 
      var diff = Math.abs(index - row.current) 
      diff = Math.max(0, row.falloff - diff) 
      var damp = row.falloff - Math.max(1, diff) 
      var sc = row.scaleFactor 
      if (damp) sc /= damp * row.damp 
      diff = diff/row.falloff * sc + 1 
      return diff 
      } 
     } 
     MouseArea { 
      id: mouseArea 
      anchors.fill: parent 
      hoverEnabled: true 
      onContainsMouseChanged: row.current = containsMouse ? index : -1 
     } 
     Behavior on pseudoScale { 
      PropertyAnimation { 
      duration: 150 
      } 
     } 
     } 
    } 
    } 
+0

太棒了!謝謝!有沒有簡單的方法來增加矩形之間的空間? –

+2

我建議不要在行上使用間距,因爲這會在可能會出現車的項目之間創建死區。取而代之的是將一個空的「Item」作爲每個委託的根,然後將圖像放在裏面並略小一些以創建視覺間隙,而不會產生鼠標輸入間隙。 – dtech

1

這可能是沿着這一線的東西:

Row { 
    anchors { 
     bottom: parent.bottom 
     left: parent.left 
     right: parent.right 
    } 

    Repeater { 
     id: rep 
     model: ['red', 'yellow', 'pink', 'green', 'teal', 'orchid', 'blue', 'orange'] 
     property int currentIndex: -10 

     delegate: Rectangle { 
      anchors.bottom: parent.bottom 
      // Calculate the width depending on the currently hovered element 
      width: (rep.currentIndex === index ? 100 : ((rep.currentIndex - index) === 1 || (rep.currentIndex - index) === -1 ? 80 : 50)) 
      height: width 
      radius: width/2 
      color: modelData 
      MouseArea { 
       anchors.fill: parent 
       hoverEnabled: true 
       // onEntered/Exited did not react. This will work. 
       onContainsMouseChanged: { 
        if (containsMouse) rep.currentIndex = index 
        else rep.currentIndex = -10 // -10 is safe 
       } 
      } 
      // Makes the movement smooth 
      Behavior on width { 
       NumberAnimation {} 
      } 
     } 
    } 
} 

我試圖把必要的解釋相關的代碼中的註釋。 唯一需要一些tweeking的是,當第一次調整大小發生時,這些點將首先移位。把它放在一個可以滑動的位置上,並且一些手工操作可以解決這個問題。基本上,當鼠標進入時,需要將寬度變化的一半(在我的情況下約爲55左右)移動到左側,當它再次離開時,將其右移到右側。

你也可以使用ListView來做到這一點,很可能,但是由於估計的背景大小不斷變化,可能會更加挑剔地獲得定位權。