fix: state layer ripple

Also improve ripple anim
This commit is contained in:
2 * r + 2 * t 2026-04-19 19:53:58 +10:00
parent d97bbb34a6
commit b0d5700be1
6 changed files with 86 additions and 24 deletions

View file

@ -37,6 +37,10 @@ MouseArea {
return (pressX - x) ** 2 + (pressY - y) ** 2;
}
function clamp(r: real): real {
return Math.max(0, Math.min(r, width / 2, height / 2));
}
function press(x: real, y: real): void {
pressX = x;
pressY = y;
@ -52,6 +56,8 @@ MouseArea {
cursorShape: disabled ? undefined : Qt.PointingHandCursor
hoverEnabled: true
onPressed: e => press(e.x, e.y)
onPressedChanged: {
if (!pressed && !rippleAnim.running && circle.opacity > 0)
fadeAnim.start();
@ -69,8 +75,8 @@ MouseArea {
target: root
property: "circleRadius"
to: root.endRadius
easing: Tokens.anim.standardDecel
duration: Tokens.anim.durations.normal * 2
easing: Tokens.anim.expressiveSlowEffects
duration: Tokens.anim.durations.expressiveSlowEffects * 2
}
Anim {
@ -79,6 +85,8 @@ MouseArea {
target: circle
property: "opacity"
to: 0
easing: Tokens.anim.expressiveSlowEffects
duration: Tokens.anim.durations.expressiveSlowEffects
}
StyledRect {
@ -123,53 +131,56 @@ MouseArea {
}
}
startX: base.topLeftRadius
startX: root.clamp(base.topLeftRadius)
startY: 0
PathLine {
x: root.width - base.topLeftRadius
x: root.width - root.clamp(base.topLeftRadius)
y: 0
}
PathArc {
relativeX: base.topLeftRadius
relativeY: base.topLeftRadius
radiusX: base.topLeftRadius
radiusY: base.topLeftRadius
relativeX: root.clamp(base.topLeftRadius)
relativeY: root.clamp(base.topLeftRadius)
radiusX: root.clamp(base.topLeftRadius)
radiusY: root.clamp(base.topLeftRadius)
}
PathLine {
x: root.width
y: root.height - base.bottomRightRadius
y: root.height - root.clamp(base.bottomRightRadius)
}
PathArc {
relativeX: -base.bottomRightRadius
relativeY: base.bottomRightRadius
radiusX: base.bottomRightRadius
radiusY: base.bottomRightRadius
relativeX: -root.clamp(base.bottomRightRadius)
relativeY: root.clamp(base.bottomRightRadius)
radiusX: root.clamp(base.bottomRightRadius)
radiusY: root.clamp(base.bottomRightRadius)
}
PathLine {
x: base.bottomLeftRadius
x: root.clamp(base.bottomLeftRadius)
y: root.height
}
PathArc {
relativeX: -base.bottomLeftRadius
relativeY: -base.bottomLeftRadius
radiusX: base.bottomLeftRadius
radiusY: base.bottomLeftRadius
relativeX: -root.clamp(base.bottomLeftRadius)
relativeY: -root.clamp(base.bottomLeftRadius)
radiusX: root.clamp(base.bottomLeftRadius)
radiusY: root.clamp(base.bottomLeftRadius)
}
PathLine {
x: 0
y: base.topLeftRadius
y: root.clamp(base.topLeftRadius)
}
PathArc {
x: base.topLeftRadius
x: root.clamp(base.topLeftRadius)
y: 0
radiusX: base.topLeftRadius
radiusY: base.topLeftRadius
radiusX: root.clamp(base.topLeftRadius)
radiusY: root.clamp(base.topLeftRadius)
}
}
}
Behavior on stateOpacity {
Anim {}
Anim {
easing: Tokens.anim.expressiveDefaultEffects
duration: Tokens.anim.durations.expressiveDefaultEffects
}
}
}

View file

@ -45,6 +45,18 @@ QEasingCurve AnimTokens::expressiveSlowSpatial() const {
return m_expressiveSlowSpatial;
}
QEasingCurve AnimTokens::expressiveFastEffects() const {
return m_expressiveFastEffects;
}
QEasingCurve AnimTokens::expressiveDefaultEffects() const {
return m_expressiveDefaultEffects;
}
QEasingCurve AnimTokens::expressiveSlowEffects() const {
return m_expressiveSlowEffects;
}
AnimDurations* AnimTokens::durations() const {
return m_durations;
}
@ -78,6 +90,9 @@ void AnimTokens::rebuildCurves() {
m_expressiveFastSpatial = buildCurve(m_curves->expressiveFastSpatial());
m_expressiveDefaultSpatial = buildCurve(m_curves->expressiveDefaultSpatial());
m_expressiveSlowSpatial = buildCurve(m_curves->expressiveSlowSpatial());
m_expressiveFastEffects = buildCurve(m_curves->expressiveFastEffects());
m_expressiveDefaultEffects = buildCurve(m_curves->expressiveDefaultEffects());
m_expressiveSlowEffects = buildCurve(m_curves->expressiveSlowEffects());
emit curvesChanged();
}

View file

@ -24,6 +24,9 @@ class AnimTokens : public QObject {
Q_PROPERTY(QEasingCurve expressiveFastSpatial READ expressiveFastSpatial NOTIFY curvesChanged)
Q_PROPERTY(QEasingCurve expressiveDefaultSpatial READ expressiveDefaultSpatial NOTIFY curvesChanged)
Q_PROPERTY(QEasingCurve expressiveSlowSpatial READ expressiveSlowSpatial NOTIFY curvesChanged)
Q_PROPERTY(QEasingCurve expressiveFastEffects READ expressiveFastEffects NOTIFY curvesChanged)
Q_PROPERTY(QEasingCurve expressiveDefaultEffects READ expressiveDefaultEffects NOTIFY curvesChanged)
Q_PROPERTY(QEasingCurve expressiveSlowEffects READ expressiveSlowEffects NOTIFY curvesChanged)
Q_PROPERTY(caelestia::config::AnimDurations* durations READ durations NOTIFY durationsChanged)
@ -42,6 +45,9 @@ public:
[[nodiscard]] QEasingCurve expressiveFastSpatial() const;
[[nodiscard]] QEasingCurve expressiveDefaultSpatial() const;
[[nodiscard]] QEasingCurve expressiveSlowSpatial() const;
[[nodiscard]] QEasingCurve expressiveFastEffects() const;
[[nodiscard]] QEasingCurve expressiveDefaultEffects() const;
[[nodiscard]] QEasingCurve expressiveSlowEffects() const;
[[nodiscard]] AnimDurations* durations() const;
signals:
@ -64,6 +70,9 @@ private:
QEasingCurve m_expressiveFastSpatial;
QEasingCurve m_expressiveDefaultSpatial;
QEasingCurve m_expressiveSlowSpatial;
QEasingCurve m_expressiveFastEffects;
QEasingCurve m_expressiveDefaultEffects;
QEasingCurve m_expressiveSlowEffects;
};
} // namespace caelestia::config

View file

@ -168,4 +168,16 @@ int AnimDurations::expressiveSlowSpatial() const {
return m_tokens ? static_cast<int>(m_tokens->expressiveSlowSpatial() * m_scale) : 0;
}
int AnimDurations::expressiveFastEffects() const {
return m_tokens ? static_cast<int>(m_tokens->expressiveFastEffects() * m_scale) : 0;
}
int AnimDurations::expressiveDefaultEffects() const {
return m_tokens ? static_cast<int>(m_tokens->expressiveDefaultEffects() * m_scale) : 0;
}
int AnimDurations::expressiveSlowEffects() const {
return m_tokens ? static_cast<int>(m_tokens->expressiveSlowEffects() * m_scale) : 0;
}
} // namespace caelestia::config

View file

@ -180,6 +180,9 @@ class AnimDurations : public ConfigObject {
Q_PROPERTY(int expressiveFastSpatial READ expressiveFastSpatial NOTIFY valuesChanged)
Q_PROPERTY(int expressiveDefaultSpatial READ expressiveDefaultSpatial NOTIFY valuesChanged)
Q_PROPERTY(int expressiveSlowSpatial READ expressiveSlowSpatial NOTIFY valuesChanged)
Q_PROPERTY(int expressiveFastEffects READ expressiveFastEffects NOTIFY valuesChanged)
Q_PROPERTY(int expressiveDefaultEffects READ expressiveDefaultEffects NOTIFY valuesChanged)
Q_PROPERTY(int expressiveSlowEffects READ expressiveSlowEffects NOTIFY valuesChanged)
public:
explicit AnimDurations(QObject* parent = nullptr)
@ -194,6 +197,9 @@ public:
[[nodiscard]] int expressiveFastSpatial() const;
[[nodiscard]] int expressiveDefaultSpatial() const;
[[nodiscard]] int expressiveSlowSpatial() const;
[[nodiscard]] int expressiveFastEffects() const;
[[nodiscard]] int expressiveDefaultEffects() const;
[[nodiscard]] int expressiveSlowEffects() const;
signals:
void valuesChanged();

View file

@ -20,6 +20,9 @@ class AnimCurves : public ConfigObject {
CONFIG_GLOBAL_PROPERTY(QList<qreal>, expressiveFastSpatial)
CONFIG_GLOBAL_PROPERTY(QList<qreal>, expressiveDefaultSpatial)
CONFIG_GLOBAL_PROPERTY(QList<qreal>, expressiveSlowSpatial)
CONFIG_GLOBAL_PROPERTY(QList<qreal>, expressiveFastEffects)
CONFIG_GLOBAL_PROPERTY(QList<qreal>, expressiveDefaultEffects)
CONFIG_GLOBAL_PROPERTY(QList<qreal>, expressiveSlowEffects)
public:
explicit AnimCurves(QObject* parent = nullptr)
@ -32,7 +35,10 @@ public:
, m_standardDecel({ 0, 0, 0, 1, 1, 1 })
, m_expressiveFastSpatial({ 0.42, 1.67, 0.21, 0.9, 1, 1 })
, m_expressiveDefaultSpatial({ 0.38, 1.21, 0.22, 1, 1, 1 })
, m_expressiveSlowSpatial({ 0.39, 1.29, 0.35, 0.98, 1, 1 }) {}
, m_expressiveSlowSpatial({ 0.39, 1.29, 0.35, 0.98, 1, 1 })
, m_expressiveFastEffects({ 0.31, 0.94, 0.34, 1, 1, 1 })
, m_expressiveDefaultEffects({ 0.34, 0.8, 0.34, 1, 1, 1 })
, m_expressiveSlowEffects({ 0.34, 0.88, 0.34, 1, 1, 1 }) {}
};
class RoundingTokens : public ConfigObject {
@ -107,6 +113,9 @@ class AnimDurationTokens : public ConfigObject {
CONFIG_GLOBAL_PROPERTY(int, expressiveFastSpatial, 350)
CONFIG_GLOBAL_PROPERTY(int, expressiveDefaultSpatial, 500)
CONFIG_GLOBAL_PROPERTY(int, expressiveSlowSpatial, 650)
CONFIG_GLOBAL_PROPERTY(int, expressiveFastEffects, 150)
CONFIG_GLOBAL_PROPERTY(int, expressiveDefaultEffects, 200)
CONFIG_GLOBAL_PROPERTY(int, expressiveSlowEffects, 300)
public:
explicit AnimDurationTokens(QObject* parent = nullptr)