tabs: nicer indicator anim

This commit is contained in:
end-4
2025-05-16 23:50:20 +02:00
parent 11087142af
commit 84f28f6411
3 changed files with 55 additions and 50 deletions
@@ -52,38 +52,39 @@ ColumnLayout {
root.enableIndicatorAnimation = true root.enableIndicatorAnimation = true
} }
} }
Rectangle { Rectangle {
id: indicator
property int tabCount: root.tabButtonList.length
property real fullTabSize: root.width / tabCount;
property real targetWidth: tabBar.contentItem.children[0].children[tabBar.currentIndex].tabContentWidth
implicitWidth: targetWidth
anchors {
top: parent.top
bottom: parent.bottom
}
x: tabBar.currentIndex * fullTabSize + (fullTabSize - targetWidth) / 2
color: Appearance.m3colors.m3primary color: Appearance.m3colors.m3primary
radius: Appearance.rounding.full radius: Appearance.rounding.full
z: 2
anchors.fill: parent Behavior on x {
// TODO: make the end point in the moving direction go first NumberAnimation {
anchors.leftMargin: { duration: Appearance.animation.elementMove.duration
const tabCount = root.tabButtonList.length easing.type: Appearance.animation.elementMove.type
const targetWidth = tabBar.contentItem.children[0].children[tabBar.currentIndex].tabContentWidth easing.bezierCurve: Appearance.animation.elementMove.bezierCurve
const fullTabSize = root.width / tabCount; }
return fullTabSize * root.externalTrackedTab + (fullTabSize - targetWidth) / 2;
} }
anchors.rightMargin: {
const tabCount = root.tabButtonList.length Behavior on implicitWidth {
const targetWidth = tabBar.contentItem.children[0].children[tabBar.currentIndex].tabContentWidth NumberAnimation {
const fullTabSize = root.width / tabCount; duration: Appearance.animation.elementMove.duration
return fullTabSize * (tabCount - root.externalTrackedTab - 1) + (fullTabSize - targetWidth) / 2; easing.type: Appearance.animation.elementMove.type
easing.bezierCurve: Appearance.animation.elementMove.bezierCurve
}
} }
Behavior on anchors.leftMargin {
enabled: root.enableIndicatorAnimation
SmoothedAnimation {
velocity: Appearance.animation.positionShift.velocity
}
}
Behavior on anchors.rightMargin {
enabled: root.enableIndicatorAnimation
SmoothedAnimation {
velocity: Appearance.animation.positionShift.velocity
}
}
} }
} }
@@ -70,7 +70,7 @@ TabButton {
ColorAnimation { ColorAnimation {
duration: Appearance.animation.elementMove.duration duration: Appearance.animation.elementMove.duration
easing.type: Appearance.animation.elementMove.type easing.type: Appearance.animation.elementMove.type
easing.bezierCurve: Appearance.animation.elementMove.bezierCurve easing.bezierCurve: Appearance.animation.elementMove.bezierCurve
} }
} }
} }
@@ -79,37 +79,41 @@ Item {
tabIndicator.enableIndicatorAnimation = true tabIndicator.enableIndicatorAnimation = true
} }
} }
Rectangle { Rectangle {
id: indicator
property int tabCount: root.tabButtonList.length
property real fullTabSize: root.width / tabCount;
property real targetWidth: tabBar.contentItem.children[0].children[tabBar.currentIndex].tabContentWidth
implicitWidth: targetWidth
anchors {
top: parent.top
bottom: parent.bottom
}
x: tabBar.currentIndex * fullTabSize + (fullTabSize - targetWidth) / 2
color: Appearance.m3colors.m3primary color: Appearance.m3colors.m3primary
radius: Appearance.rounding.full radius: Appearance.rounding.full
z: 2
anchors.fill: parent Behavior on x {
anchors.leftMargin: {
const tabCount = root.tabButtonList.length
const targetWidth = tabBar.contentItem.children[0].children[tabBar.currentIndex].tabContentWidth
const fullTabSize = tabBar.width / tabCount;
return fullTabSize * currentTab + (fullTabSize - targetWidth) / 2;
}
anchors.rightMargin: {
const tabCount = root.tabButtonList.length
const targetWidth = tabBar.contentItem.children[0].children[tabBar.currentIndex].tabContentWidth
const fullTabSize = tabBar.width / tabCount;
return fullTabSize * (tabCount - currentTab - 1) + (fullTabSize - targetWidth) / 2;
}
Behavior on anchors.leftMargin {
enabled: tabIndicator.enableIndicatorAnimation enabled: tabIndicator.enableIndicatorAnimation
SmoothedAnimation { NumberAnimation {
velocity: Appearance.animation.positionShift.velocity duration: Appearance.animation.elementMove.duration
} easing.type: Appearance.animation.elementMove.type
easing.bezierCurve: Appearance.animation.elementMove.bezierCurve
}
} }
Behavior on anchors.rightMargin {
Behavior on implicitWidth {
enabled: tabIndicator.enableIndicatorAnimation enabled: tabIndicator.enableIndicatorAnimation
SmoothedAnimation { NumberAnimation {
velocity: Appearance.animation.positionShift.velocity duration: Appearance.animation.elementMove.duration
} easing.type: Appearance.animation.elementMove.type
easing.bezierCurve: Appearance.animation.elementMove.bezierCurve
}
} }
} }
} }