import { Application } from "pixi.js"; export const app = new Application(); let manuelResizeCallback = null; /** * Startet die PixiJS-Engine und hängt das Canvas in das HTML-Dokument ein. * * @param {string} containerId - Die HTML-ID des divs, in das PixiJS gerendert werden soll. */ export async function initPixi(containerId) { await app.init({ resizeTo: window, backgroundAlpha: 0, antialias: true, resolution: window.devicePixelRatio || 1, autoDensity: true }); document.getElementById(containerId).appendChild(app.canvas); } /** * Übernimmt die gesammte responsive Skalierungslogik für unsere PixiJS-Element. * Wir übergeben hier alle Container, die flexible auf Fenstergrößen reagieren müssen. * * @param {Object} refs - Ein Paket mit allen UI-Containern. */ export function setupResize(refs) { const { background, discordContainer, logoContainer, uiContainer, panelFrame, lobbyPixiContainer, footerBackground, footerPattern, footerBackgroundContainer, onboardingPixiContainer } = refs; function resize() { const screenWidth = window.innerWidth; const screenHeight = window.innerHeight; if (background && background.texture) { const scaleX = screenWidth / background.texture.width; const scaleY = screenHeight / background.texture.height; const scale = Math.max(scaleX, scaleY); background.scale.set(scale); background.x = (screenWidth - background.width) / 2; background.y = (screenHeight - background.height) / 2; } let panelScale = 1.0; let panelOffsetY = 0; if (screenHeight <= 500){ panelScale = 0.4; panelOffsetY = 0; discordContainer.position.set(-420, 350); logoContainer.position.set(-300, 150); logoContainer.scale.set(1.3); } else if (screenWidth <= 600) { panelScale = 0.7; panelOffsetY = 0; discordContainer.position.set(125, 520); logoContainer.position.set(250, -120); logoContainer.scale.set(0.7); } else { panelScale = 1.0; panelOffsetY = 0; discordContainer.position.set(640, 380); logoContainer.position.set(250, -120); logoContainer.scale.set(1.0); if (screenHeight <= 1050) { panelOffsetY = 80; } } uiContainer.scale.set(panelScale); uiContainer.x = (screenWidth - (panelFrame.width * panelScale)) / 2; uiContainer.y = ((screenHeight - (panelFrame.height * panelScale)) / 2) + panelOffsetY; const isMobilePortrait = screenWidth <= 800 && screenHeight > screenWidth; const isLandscapeMobile = screenHeight <= 500; const targetPanelWidth = isMobilePortrait ? 650 : 1240; const htmlFooter = document.getElementById('game-footer'); const footerHeight = (htmlFooter && htmlFooter.style.display !== 'none') ? htmlFooter.offsetHeight : 0; const actualFooterHeight = Math.max(footerHeight, isLandscapeMobile ? 30 : 40); const visualWidth = screenWidth - (isMobilePortrait ? 20 : 60); const visualHeight = screenHeight - actualFooterHeight - 80; const lobbyScale = Math.min(1.0, visualWidth / targetPanelWidth); let targetPanelHeight = visualHeight / lobbyScale; targetPanelHeight = Math.max(350, targetPanelHeight); if (!isMobilePortrait && !isLandscapeMobile) { targetPanelHeight = Math.min(800, targetPanelHeight); } let targetMaskHeight = targetPanelHeight - 110; let lobbyOffsetY = 0; if (isMobilePortrait) { lobbyOffsetY = -25; } if (lobbyPixiContainer.bgSprite && lobbyPixiContainer.scrollMask) { lobbyPixiContainer.bgSprite.width = targetPanelWidth; lobbyPixiContainer.bgSprite.height = targetPanelHeight; lobbyPixiContainer.scrollMask.clear(); lobbyPixiContainer.scrollMask.rect(30, 80, targetPanelWidth - 60, targetMaskHeight); lobbyPixiContainer.scrollMask.fill(0xffffff); } lobbyPixiContainer.scale.set(lobbyScale); lobbyPixiContainer.x = (screenWidth - (targetPanelWidth * lobbyScale)) / 2; lobbyPixiContainer.y = ((screenHeight - (targetPanelHeight * lobbyScale)) / 2) + lobbyOffsetY; const sectorHtmlLayer = document.getElementById('sector-browser-layer'); if (sectorHtmlLayer) { sectorHtmlLayer.style.width = `${targetPanelWidth}px`; sectorHtmlLayer.style.height = `${targetPanelHeight}px`; sectorHtmlLayer.style.left = `${lobbyPixiContainer.x}px`; sectorHtmlLayer.style.top = `${lobbyPixiContainer.y}px`; sectorHtmlLayer.style.transformOrigin = '0 0'; sectorHtmlLayer.style.transform = `scale(${lobbyScale})`; } const sectorListContainer = document.getElementById('sector-list-container'); if (sectorListContainer) { sectorListContainer.style.height = `${targetMaskHeight}px`; } if (onboardingPixiContainer) { onboardingPixiContainer.x = (screenWidth - 450) / 2; onboardingPixiContainer.y = (screenHeight - 550) / 2; } footerBackground.height = actualFooterHeight; footerPattern.height = actualFooterHeight; footerBackground.width = screenWidth; footerPattern.width = screenWidth; footerBackgroundContainer.y = screenHeight - footerHeight; } app.renderer.on('resize', resize); manuelResizeCallback = resize; resize(); } /** * Löst eine manuelle Neuberechnung des Layout aus (wichtig nach dem Wechsel zur Lobby) */ export function triggerResize() { if (manuelResizeCallback) { manuelResizeCallback(); } } /** * Wenn der Nutzer das Gerät dreht, laden wir die Seite nach einer kurzen Vertögerung neu * um sicherzustellen dass HTML und Canvas perfekr synchronisieren. */ window.addEventListener('orientationchange', () => { setTimeout(() => { window.location.reload(); }, 300); // 300ms warten, bis der Browser die neuen Maße gerendert hat });