dashboard: use shape for media visualiser

More cpu efficient
This commit is contained in:
2 * r + 2 * t 2025-07-09 01:08:35 +10:00
parent 1ac4ac388c
commit 18b6a321de

View file

@ -11,6 +11,7 @@ import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Effects import QtQuick.Effects
import QtQuick.Layouts import QtQuick.Layouts
import QtQuick.Shapes
Item { Item {
id: root id: root
@ -47,15 +48,11 @@ Item {
onTriggered: Players.active?.positionChanged() onTriggered: Players.active?.positionChanged()
} }
Connections { Ref {
target: Cava service: Cava
function onValuesChanged(): void {
visualiser.requestPaint();
}
} }
Canvas { Shape {
id: visualiser id: visualiser
readonly property real centerX: width / 2 readonly property real centerX: width / 2
@ -67,51 +64,48 @@ Item {
anchors.fill: cover anchors.fill: cover
anchors.margins: -Config.dashboard.sizes.mediaVisualiserSize anchors.margins: -Config.dashboard.sizes.mediaVisualiserSize
onColourChanged: requestPaint() preferredRendererType: Shape.CurveRenderer
data: visualiserBars.instances
}
onPaint: { Variants {
const ctx = getContext("2d"); id: visualiserBars
ctx.reset();
const values = Cava.values; model: Array.from({
const len = values.length; length: Config.dashboard.visualiserBars
}, (_, i) => i)
ctx.strokeStyle = colour; ShapePath {
ctx.lineWidth = 360 / len - Appearance.spacing.small / 4; id: visualiserBar
ctx.lineCap = "round";
const size = Config.dashboard.sizes.mediaVisualiserSize; required property int modelData
const cx = centerX; readonly property int value: Math.max(1, Math.min(100, Cava.values[modelData]))
const cy = centerY;
const rx = innerX + ctx.lineWidth / 2;
const ry = innerY + ctx.lineWidth / 2;
for (let i = 0; i < len; i++) { readonly property real angle: modelData * 2 * Math.PI / Config.dashboard.visualiserBars
const v = Math.max(1, Math.min(100, values[i])); readonly property real magnitude: value / 100 * Config.dashboard.sizes.mediaVisualiserSize
readonly property real cos: Math.cos(angle)
readonly property real sin: Math.sin(angle)
const angle = i * 2 * Math.PI / len; capStyle: ShapePath.RoundCap
const magnitude = v / 100 * size; strokeWidth: 360 / Config.dashboard.visualiserBars - Appearance.spacing.small / 4
const cos = Math.cos(angle); strokeColor: Colours.palette.m3primary
const sin = Math.sin(angle);
ctx.moveTo(cx + rx * cos, cy + ry * sin); startX: visualiser.centerX + (visualiser.innerX + strokeWidth / 2) * cos
ctx.lineTo(cx + (rx + magnitude) * cos, cy + (ry + magnitude) * sin); startY: visualiser.centerY + (visualiser.innerY + strokeWidth / 2) * sin
PathLine {
x: visualiser.centerX + (visualiser.innerX + visualiserBar.strokeWidth / 2 + visualiserBar.magnitude) * visualiserBar.cos
y: visualiser.centerY + (visualiser.innerY + visualiserBar.strokeWidth / 2 + visualiserBar.magnitude) * visualiserBar.sin
} }
ctx.stroke(); Behavior on strokeColor {
} ColorAnimation {
duration: Appearance.anim.durations.normal
Behavior on colour { easing.type: Easing.BezierSpline
ColorAnimation { easing.bezierCurve: Appearance.anim.curves.standard
duration: Appearance.anim.durations.normal }
easing.type: Easing.BezierSpline
easing.bezierCurve: Appearance.anim.curves.standard
} }
} }
Ref {
service: Cava
}
} }
StyledClippingRect { StyledClippingRect {