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; 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 { function press(x: real, y: real): void {
pressX = x; pressX = x;
pressY = y; pressY = y;
@ -52,6 +56,8 @@ MouseArea {
cursorShape: disabled ? undefined : Qt.PointingHandCursor cursorShape: disabled ? undefined : Qt.PointingHandCursor
hoverEnabled: true hoverEnabled: true
onPressed: e => press(e.x, e.y)
onPressedChanged: { onPressedChanged: {
if (!pressed && !rippleAnim.running && circle.opacity > 0) if (!pressed && !rippleAnim.running && circle.opacity > 0)
fadeAnim.start(); fadeAnim.start();
@ -69,8 +75,8 @@ MouseArea {
target: root target: root
property: "circleRadius" property: "circleRadius"
to: root.endRadius to: root.endRadius
easing: Tokens.anim.standardDecel easing: Tokens.anim.expressiveSlowEffects
duration: Tokens.anim.durations.normal * 2 duration: Tokens.anim.durations.expressiveSlowEffects * 2
} }
Anim { Anim {
@ -79,6 +85,8 @@ MouseArea {
target: circle target: circle
property: "opacity" property: "opacity"
to: 0 to: 0
easing: Tokens.anim.expressiveSlowEffects
duration: Tokens.anim.durations.expressiveSlowEffects
} }
StyledRect { StyledRect {
@ -123,53 +131,56 @@ MouseArea {
} }
} }
startX: base.topLeftRadius startX: root.clamp(base.topLeftRadius)
startY: 0 startY: 0
PathLine { PathLine {
x: root.width - base.topLeftRadius x: root.width - root.clamp(base.topLeftRadius)
y: 0 y: 0
} }
PathArc { PathArc {
relativeX: base.topLeftRadius relativeX: root.clamp(base.topLeftRadius)
relativeY: base.topLeftRadius relativeY: root.clamp(base.topLeftRadius)
radiusX: base.topLeftRadius radiusX: root.clamp(base.topLeftRadius)
radiusY: base.topLeftRadius radiusY: root.clamp(base.topLeftRadius)
} }
PathLine { PathLine {
x: root.width x: root.width
y: root.height - base.bottomRightRadius y: root.height - root.clamp(base.bottomRightRadius)
} }
PathArc { PathArc {
relativeX: -base.bottomRightRadius relativeX: -root.clamp(base.bottomRightRadius)
relativeY: base.bottomRightRadius relativeY: root.clamp(base.bottomRightRadius)
radiusX: base.bottomRightRadius radiusX: root.clamp(base.bottomRightRadius)
radiusY: base.bottomRightRadius radiusY: root.clamp(base.bottomRightRadius)
} }
PathLine { PathLine {
x: base.bottomLeftRadius x: root.clamp(base.bottomLeftRadius)
y: root.height y: root.height
} }
PathArc { PathArc {
relativeX: -base.bottomLeftRadius relativeX: -root.clamp(base.bottomLeftRadius)
relativeY: -base.bottomLeftRadius relativeY: -root.clamp(base.bottomLeftRadius)
radiusX: base.bottomLeftRadius radiusX: root.clamp(base.bottomLeftRadius)
radiusY: base.bottomLeftRadius radiusY: root.clamp(base.bottomLeftRadius)
} }
PathLine { PathLine {
x: 0 x: 0
y: base.topLeftRadius y: root.clamp(base.topLeftRadius)
} }
PathArc { PathArc {
x: base.topLeftRadius x: root.clamp(base.topLeftRadius)
y: 0 y: 0
radiusX: base.topLeftRadius radiusX: root.clamp(base.topLeftRadius)
radiusY: base.topLeftRadius radiusY: root.clamp(base.topLeftRadius)
} }
} }
} }
Behavior on stateOpacity { 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; 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 { AnimDurations* AnimTokens::durations() const {
return m_durations; return m_durations;
} }
@ -78,6 +90,9 @@ void AnimTokens::rebuildCurves() {
m_expressiveFastSpatial = buildCurve(m_curves->expressiveFastSpatial()); m_expressiveFastSpatial = buildCurve(m_curves->expressiveFastSpatial());
m_expressiveDefaultSpatial = buildCurve(m_curves->expressiveDefaultSpatial()); m_expressiveDefaultSpatial = buildCurve(m_curves->expressiveDefaultSpatial());
m_expressiveSlowSpatial = buildCurve(m_curves->expressiveSlowSpatial()); 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(); emit curvesChanged();
} }

View file

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

View file

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

View file

@ -20,6 +20,9 @@ class AnimCurves : public ConfigObject {
CONFIG_GLOBAL_PROPERTY(QList<qreal>, expressiveFastSpatial) CONFIG_GLOBAL_PROPERTY(QList<qreal>, expressiveFastSpatial)
CONFIG_GLOBAL_PROPERTY(QList<qreal>, expressiveDefaultSpatial) CONFIG_GLOBAL_PROPERTY(QList<qreal>, expressiveDefaultSpatial)
CONFIG_GLOBAL_PROPERTY(QList<qreal>, expressiveSlowSpatial) 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: public:
explicit AnimCurves(QObject* parent = nullptr) explicit AnimCurves(QObject* parent = nullptr)
@ -32,7 +35,10 @@ public:
, m_standardDecel({ 0, 0, 0, 1, 1, 1 }) , m_standardDecel({ 0, 0, 0, 1, 1, 1 })
, m_expressiveFastSpatial({ 0.42, 1.67, 0.21, 0.9, 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_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 { class RoundingTokens : public ConfigObject {
@ -107,6 +113,9 @@ class AnimDurationTokens : public ConfigObject {
CONFIG_GLOBAL_PROPERTY(int, expressiveFastSpatial, 350) CONFIG_GLOBAL_PROPERTY(int, expressiveFastSpatial, 350)
CONFIG_GLOBAL_PROPERTY(int, expressiveDefaultSpatial, 500) CONFIG_GLOBAL_PROPERTY(int, expressiveDefaultSpatial, 500)
CONFIG_GLOBAL_PROPERTY(int, expressiveSlowSpatial, 650) 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: public:
explicit AnimDurationTokens(QObject* parent = nullptr) explicit AnimDurationTokens(QObject* parent = nullptr)