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