Rework parallax

This commit is contained in:
EoinKanro
2025-12-04 22:30:55 +01:00
parent 71c1fbe1dd
commit 1193b7a802
3 changed files with 68 additions and 52 deletions
@@ -208,7 +208,7 @@ Singleton {
property bool vertical: false property bool vertical: false
property bool autoVertical: false property bool autoVertical: false
property bool enableWorkspace: true property bool enableWorkspace: true
property real workspaceZoom: 1.07 // Relative to your screen, not wallpaper size property real workspaceZoom: 1.0 // Relative to wallpaper size
property bool enableSidebar: true property bool enableSidebar: true
property real widgetsFactor: 1.2 property real widgetsFactor: 1.2
} }
@@ -37,6 +37,7 @@ Variants {
property list<var> relevantWindows: HyprlandData.windowList.filter(win => win.monitor == monitor?.id && win.workspace.id >= 0).sort((a, b) => a.workspace.id - b.workspace.id) property list<var> relevantWindows: HyprlandData.windowList.filter(win => win.monitor == monitor?.id && win.workspace.id >= 0).sort((a, b) => a.workspace.id - b.workspace.id)
property int firstWorkspaceId: relevantWindows[0]?.workspace.id || 1 property int firstWorkspaceId: relevantWindows[0]?.workspace.id || 1
property int lastWorkspaceId: relevantWindows[relevantWindows.length - 1]?.workspace.id || 10 property int lastWorkspaceId: relevantWindows[relevantWindows.length - 1]?.workspace.id || 10
property int totalWorkspaces: Config?.options.bar.workspaces.shown ?? 10
// Wallpaper // Wallpaper
property bool wallpaperIsVideo: Config.options.background.wallpaperPath.endsWith(".mp4") || Config.options.background.wallpaperPath.endsWith(".webm") || Config.options.background.wallpaperPath.endsWith(".mkv") || Config.options.background.wallpaperPath.endsWith(".avi") || Config.options.background.wallpaperPath.endsWith(".mov") property bool wallpaperIsVideo: Config.options.background.wallpaperPath.endsWith(".mp4") || Config.options.background.wallpaperPath.endsWith(".webm") || Config.options.background.wallpaperPath.endsWith(".mkv") || Config.options.background.wallpaperPath.endsWith(".avi") || Config.options.background.wallpaperPath.endsWith(".mov")
property string wallpaperPath: wallpaperIsVideo ? Config.options.background.thumbnailPath : Config.options.background.wallpaperPath property string wallpaperPath: wallpaperIsVideo ? Config.options.background.thumbnailPath : Config.options.background.wallpaperPath
@@ -46,13 +47,15 @@ Variants {
const sensitiveNetwork = (CF.StringUtils.stringListContainsSubstring(Network.networkName.toLowerCase(), Config.options.workSafety.triggerCondition.networkNameKeywords)); const sensitiveNetwork = (CF.StringUtils.stringListContainsSubstring(Network.networkName.toLowerCase(), Config.options.workSafety.triggerCondition.networkNameKeywords));
return enabled && sensitiveWallpaper && sensitiveNetwork; return enabled && sensitiveWallpaper && sensitiveNetwork;
} }
property real wallpaperToScreenRatio: Math.min(wallpaperWidth / screen.width, wallpaperHeight / screen.height) property real parallaxRation: 1.2
property real preferredWallpaperScale: Config.options.background.parallax.workspaceZoom property real additionalScaleFactor: Config.options.background.parallax.workspaceZoom
property real effectiveWallpaperScale: 1 // Some reasonable init value, to be updated property real effectiveWallpaperScale: 1 // Some reasonable init value, to be updated
property int wallpaperWidth: modelData.width // Some reasonable init value, to be updated property int wallpaperWidth: modelData.width // Some reasonable init value, to be updated
property int wallpaperHeight: modelData.height // Some reasonable init value, to be updated property int wallpaperHeight: modelData.height // Some reasonable init value, to be updated
property real movableXSpace: ((wallpaperWidth / wallpaperToScreenRatio * effectiveWallpaperScale) - screen.width) / 2 property real scaledWallpaperWidth: wallpaperWidth * effectiveWallpaperScale
property real movableYSpace: ((wallpaperHeight / wallpaperToScreenRatio * effectiveWallpaperScale) - screen.height) / 2 property real scaledWallpaperHeight: wallpaperHeight * effectiveWallpaperScale
property real parallaxTotalPixelsX: Math.max(screen.width - scaledWallpaperWidth, scaledWallpaperWidth - screen.width)
property real parallaxTotalPixelsY: Math.max(screen.height - scaledWallpaperHeight, scaledWallpaperHeight - screen.height)
readonly property bool verticalParallax: (Config.options.background.parallax.autoVertical && wallpaperHeight > wallpaperWidth) || Config.options.background.parallax.vertical readonly property bool verticalParallax: (Config.options.background.parallax.autoVertical && wallpaperHeight > wallpaperWidth) || Config.options.background.parallax.vertical
// Colors // Colors
property bool shouldBlur: (GlobalStates.screenLocked && Config.options.lock.blur.enable) property bool shouldBlur: (GlobalStates.screenLocked && Config.options.lock.blur.enable)
@@ -111,13 +114,13 @@ Variants {
bgRoot.wallpaperWidth = width; bgRoot.wallpaperWidth = width;
bgRoot.wallpaperHeight = height; bgRoot.wallpaperHeight = height;
if (width <= screenWidth || height <= screenHeight) { // Perfect image; scale = 1
// Undersized/perfectly sized wallpapers // Small picture; scale > 1; will zoom in the picture
bgRoot.effectiveWallpaperScale = Math.max(screenWidth / width, screenHeight / height); // Big picture; scale < 1; will zoom out the picture
} else { // Choose max number so every side will fit
// Oversized = can be zoomed for parallax, yay const minSuitableScale = Math.max(screenWidth / width, screenHeight / height);
bgRoot.effectiveWallpaperScale = Math.min(bgRoot.preferredWallpaperScale, width / screenWidth, height / screenHeight); //todo switch off parallax
} bgRoot.effectiveWallpaperScale = minSuitableScale * bgRoot.additionalScaleFactor * bgRoot.parallaxRation;
} }
} }
} }
@@ -133,32 +136,49 @@ Variants {
opacity: (status === Image.Ready && !bgRoot.wallpaperIsVideo) ? 1 : 0 opacity: (status === Image.Ready && !bgRoot.wallpaperIsVideo) ? 1 : 0
cache: false cache: false
smooth: false smooth: false
// Range = groups that workspaces span on
property int chunkSize: Config?.options.bar.workspaces.shown ?? 10 property int workspaceIndex: (bgRoot.monitor.activeWorkspace?.id ?? 1) - 1
property int lower: Math.floor(bgRoot.firstWorkspaceId / chunkSize) * chunkSize property real middleFraction: 0.5
property int upper: Math.ceil(bgRoot.lastWorkspaceId / chunkSize) * chunkSize property real fraction: {
property int range: upper - lower // 0 - start of the picture
property real valueX: { // 1 - end of the picture
let result = 0.5; if (bgRoot.totalWorkspaces <= 1) {
return middleFraction;
}
return Math.max(0, Math.min(1, workspaceIndex / (bgRoot.totalWorkspaces - 1)));
}
x: {
if (bgRoot.screen.width > bgRoot.scaledWallpaperWidth) {
// Center the picture
return bgRoot.parallaxTotalPixelsX / 2;
}
let usedFraction = middleFraction;
if (Config.options.background.parallax.enableWorkspace && !bgRoot.verticalParallax) { if (Config.options.background.parallax.enableWorkspace && !bgRoot.verticalParallax) {
result = ((bgRoot.monitor.activeWorkspace?.id - lower) / range); usedFraction = fraction;
} }
if (Config.options.background.parallax.enableSidebar) { if (Config.options.background.parallax.enableSidebar) {
result += (0.15 * GlobalStates.sidebarRightOpen - 0.15 * GlobalStates.sidebarLeftOpen); let sidebarFraction = bgRoot.parallaxRation / 10;
usedFraction += (sidebarFraction * GlobalStates.sidebarRightOpen - sidebarFraction * GlobalStates.sidebarLeftOpen);
} }
return result; usedFraction = Math.max(0, Math.min(1, usedFraction));
return - bgRoot.parallaxTotalPixelsX * usedFraction;
} }
property real valueY: { y: {
let result = 0.5; if (bgRoot.screen.height > bgRoot.scaledWallpaperHeight) {
// Center the picture
return bgRoot.parallaxTotalPixelsY / 2;
}
let usedFraction = middleFraction;
if (Config.options.background.parallax.enableWorkspace && bgRoot.verticalParallax) { if (Config.options.background.parallax.enableWorkspace && bgRoot.verticalParallax) {
result = ((bgRoot.monitor.activeWorkspace?.id - lower) / range); usedFraction = fraction;
} }
return result; usedFraction = Math.max(0, Math.min(1, usedFraction));
return - bgRoot.parallaxTotalPixelsY * usedFraction;
} }
property real effectiveValueX: Math.max(0, Math.min(1, valueX))
property real effectiveValueY: Math.max(0, Math.min(1, valueY))
x: -(bgRoot.movableXSpace) - (effectiveValueX - 0.5) * 2 * bgRoot.movableXSpace
y: -(bgRoot.movableYSpace) - (effectiveValueY - 0.5) * 2 * bgRoot.movableYSpace
source: bgRoot.wallpaperSafetyTriggered ? "" : bgRoot.wallpaperPath source: bgRoot.wallpaperSafetyTriggered ? "" : bgRoot.wallpaperPath
fillMode: Image.PreserveAspectCrop fillMode: Image.PreserveAspectCrop
Behavior on x { Behavior on x {
@@ -174,11 +194,11 @@ Variants {
} }
} }
sourceSize { sourceSize {
width: bgRoot.screen.width * bgRoot.effectiveWallpaperScale * bgRoot.monitor.scale width: bgRoot.scaledWallpaperWidth
height: bgRoot.screen.height * bgRoot.effectiveWallpaperScale * bgRoot.monitor.scale height: bgRoot.scaledWallpaperHeight
} }
width: bgRoot.wallpaperWidth / bgRoot.wallpaperToScreenRatio * bgRoot.effectiveWallpaperScale width: bgRoot.scaledWallpaperWidth
height: bgRoot.wallpaperHeight / bgRoot.wallpaperToScreenRatio * bgRoot.effectiveWallpaperScale height: bgRoot.scaledWallpaperHeight
} }
Loader { Loader {
@@ -210,22 +230,18 @@ Variants {
WidgetCanvas { WidgetCanvas {
id: widgetCanvas id: widgetCanvas
anchors { anchors {
left: wallpaper.left left: bgRoot.screen.left
right: wallpaper.right right: bgRoot.screen.right
top: wallpaper.top top: bgRoot.screen.top
bottom: wallpaper.bottom bottom: bgRoot.screen.bottom
horizontalCenter: undefined horizontalCenter: undefined
verticalCenter: undefined verticalCenter: undefined
readonly property real parallaxFactor: Config.options.background.parallax.widgetsFactor readonly property real parallaxFactor: Config.options.background.parallax.widgetsFactor
leftMargin: { leftMargin: {
const xOnWallpaper = bgRoot.movableXSpace; return bgRoot.screen.width * 0.2;
const extraMove = (wallpaper.effectiveValueX * 2 * bgRoot.movableXSpace) * (parallaxFactor - 1);
return xOnWallpaper - extraMove;
} }
topMargin: { topMargin: {
const yOnWallpaper = bgRoot.movableYSpace; return bgRoot.screen.height * 0.2;
const extraMove = (wallpaper.effectiveValueY * 2 * bgRoot.movableYSpace) * (parallaxFactor - 1);
return yOnWallpaper - extraMove;
} }
Behavior on leftMargin { Behavior on leftMargin {
animation: Appearance.animation.elementMove.numberAnimation.createObject(this) animation: Appearance.animation.elementMove.numberAnimation.createObject(this)
@@ -275,9 +291,9 @@ Variants {
sourceComponent: WeatherWidget { sourceComponent: WeatherWidget {
screenWidth: bgRoot.screen.width screenWidth: bgRoot.screen.width
screenHeight: bgRoot.screen.height screenHeight: bgRoot.screen.height
scaledScreenWidth: bgRoot.screen.width / bgRoot.effectiveWallpaperScale scaledScreenWidth: bgRoot.screen.width
scaledScreenHeight: bgRoot.screen.height / bgRoot.effectiveWallpaperScale scaledScreenHeight: bgRoot.screen.height
wallpaperScale: bgRoot.effectiveWallpaperScale wallpaperScale: 1
} }
} }
@@ -286,9 +302,9 @@ Variants {
sourceComponent: ClockWidget { sourceComponent: ClockWidget {
screenWidth: bgRoot.screen.width screenWidth: bgRoot.screen.width
screenHeight: bgRoot.screen.height screenHeight: bgRoot.screen.height
scaledScreenWidth: bgRoot.screen.width / bgRoot.effectiveWallpaperScale scaledScreenWidth: bgRoot.screen.width
scaledScreenHeight: bgRoot.screen.height / bgRoot.effectiveWallpaperScale scaledScreenHeight: bgRoot.screen.height
wallpaperScale: bgRoot.effectiveWallpaperScale wallpaperScale: 1
wallpaperSafetyTriggered: bgRoot.wallpaperSafetyTriggered wallpaperSafetyTriggered: bgRoot.wallpaperSafetyTriggered
} }
} }
@@ -43,8 +43,8 @@ ContentPage {
icon: "loupe" icon: "loupe"
text: Translation.tr("Preferred wallpaper zoom (%)") text: Translation.tr("Preferred wallpaper zoom (%)")
value: Config.options.background.parallax.workspaceZoom * 100 value: Config.options.background.parallax.workspaceZoom * 100
from: 100 from: 10
to: 150 to: 200
stepSize: 1 stepSize: 1
onValueChanged: { onValueChanged: {
Config.options.background.parallax.workspaceZoom = value / 100; Config.options.background.parallax.workspaceZoom = value / 100;