Fix: background splitting bug

This commit is contained in:
DaZuo0122
2026-02-14 17:08:29 +08:00
parent 901bf0ffc3
commit 1fa7080210
10 changed files with 348 additions and 34 deletions

View File

@@ -2,7 +2,13 @@ import React from "react";
import ReactDOM from "react-dom/client";
import { invoke } from "@tauri-apps/api/core";
import { listen } from "@tauri-apps/api/event";
import { LogicalPosition, LogicalSize, getCurrentWindow } from "@tauri-apps/api/window";
import {
PhysicalPosition,
PhysicalSize,
currentMonitor,
getCurrentWindow,
monitorFromPoint
} from "@tauri-apps/api/window";
import { PixiPetRenderer, type UiSpritePack, type UiSnapshot } from "./renderer/pixi_pet";
import "./styles.css";
@@ -45,29 +51,58 @@ function fittedWindowSize(
scale: number
): { width: number; height: number } {
const safeScale = Number.isFinite(scale) && scale > 0 ? scale : 1;
const width = Math.max(frameWidth * safeScale + WINDOW_PADDING, MIN_WINDOW_SIZE);
const height = Math.max(frameHeight * safeScale + WINDOW_PADDING, MIN_WINDOW_SIZE);
const width = Math.round(Math.max(frameWidth * safeScale + WINDOW_PADDING, MIN_WINDOW_SIZE));
const height = Math.round(Math.max(frameHeight * safeScale + WINDOW_PADDING, MIN_WINDOW_SIZE));
return { width, height };
}
async function fitWindowForScale(pack: UiSpritePack, scale: number): Promise<void> {
const window = getCurrentWindow();
const [outerPosition, innerSize] = await Promise.all([window.outerPosition(), window.innerSize()]);
const target = fittedWindowSize(pack.frame_width, pack.frame_height, scale);
const widthChanged = Math.abs(target.width - innerSize.width) > SIZE_EPSILON;
const heightChanged = Math.abs(target.height - innerSize.height) > SIZE_EPSILON;
const centerX = outerPosition.x + innerSize.width / 2;
const centerY = outerPosition.y + innerSize.height / 2;
let targetWidth = target.width;
let targetHeight = target.height;
let targetX = centerX - targetWidth / 2;
let targetY = centerY - targetHeight / 2;
let monitor:
| {
position: { x: number; y: number };
size: { width: number; height: number };
workArea: { position: { x: number; y: number }; size: { width: number; height: number } };
}
| null = null;
try {
monitor = (await monitorFromPoint(centerX, centerY)) ?? (await currentMonitor());
} catch {
monitor = null;
}
if (monitor !== null) {
targetWidth = Math.min(targetWidth, monitor.workArea.size.width);
targetHeight = Math.min(targetHeight, monitor.workArea.size.height);
targetX = centerX - targetWidth / 2;
targetY = centerY - targetHeight / 2;
}
const widthChanged = Math.abs(targetWidth - innerSize.width) > SIZE_EPSILON;
const heightChanged = Math.abs(targetHeight - innerSize.height) > SIZE_EPSILON;
if (!widthChanged && !heightChanged) {
return;
}
const deltaWidth = target.width - innerSize.width;
const deltaHeight = target.height - innerSize.height;
const targetX = outerPosition.x - deltaWidth / 2;
const targetY = outerPosition.y - deltaHeight;
await window.setSize(new LogicalSize(target.width, target.height));
await window.setPosition(new LogicalPosition(targetX, targetY));
await window.setSize(new PhysicalSize(targetWidth, targetHeight));
if (monitor !== null) {
const minX = Math.round(monitor.workArea.position.x);
const minY = Math.round(monitor.workArea.position.y);
const maxX = Math.round(monitor.workArea.position.x + monitor.workArea.size.width - targetWidth);
const maxY = Math.round(monitor.workArea.position.y + monitor.workArea.size.height - targetHeight);
targetX = maxX < minX ? minX : Math.min(Math.max(targetX, minX), maxX);
targetY = maxY < minY ? minY : Math.min(Math.max(targetY, minY), maxY);
}
await window.setPosition(new PhysicalPosition(Math.round(targetX), Math.round(targetY)));
}
function MainOverlayWindow(): JSX.Element {