macosqtqmlqt-quickdock

MacOS dock-like component in QML


Using QtQuick, I have a row of 5 images in a repeater. I'd like to implement an animation on hover that's similar to the MacOS dock animation. Here's a picture for reference:

MacOS Dock

To further break it down, here's what I'm trying to accomplish. These images, on hover, should act as follows:

Here is the code I have so far

  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
          }
        }
      }
    }
  }

This expands the image you hover over, but I cannot seem to also effect the neighbors. Any advice is appreciated!


Solution

  • I'd suggest a little more robust solution, where you have control over the zoom factor and the spread and decay of influence:

    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
              }
            }
          }
        }
      }