diff options
| -rw-r--r-- | desktop/modules/sound/Osd.qml | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/desktop/modules/sound/Osd.qml b/desktop/modules/sound/Osd.qml index 2894d35..dfcf876 100644 --- a/desktop/modules/sound/Osd.qml +++ b/desktop/modules/sound/Osd.qml @@ -132,6 +132,46 @@ Scope { color: Qt.alpha(Theme.base, 0.82) } + // Frost on the scrim, faked: a faint top-down sheen and fixed + // grain. The art is opaque, so the compositor's frosting cannot + // show here without costing the scrim its legibility. + Rectangle { + anchors.fill: bgArt + visible: bgEffect.visible + radius: bgMask.radius + gradient: Gradient { + GradientStop { position: 0.0; color: Qt.alpha(Theme.text, 0.08) } + GradientStop { position: 0.6; color: "transparent" } + } + } + + // ponytail: grain painted once with Canvas; a ShaderEffect would + // animate or scale better but needs a compiled .qsb beside it. + Canvas { + anchors.fill: bgArt + visible: bgEffect.visible + layer.enabled: true + layer.effect: MultiEffect { + maskEnabled: true + maskSource: bgMask + maskThresholdMin: 0.5 + maskSpreadAtMin: 1.0 + } + onPaint: { + if (width <= 0 || height <= 0) return; + const ctx = getContext("2d"); + const img = ctx.createImageData(width, height); + for (let i = 0; i < img.data.length; i += 4) { + const v = Math.random() * 255; + img.data[i] = v; + img.data[i + 1] = v; + img.data[i + 2] = v; + img.data[i + 3] = 14; + } + ctx.putImageData(img, 0, 0); + } + } + HoverHandler { onHoveredChanged: root.hovered = hovered } |
