Upload via GUI (143 Dateien)
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* "Fenster wachsen aus dem Knopf": Ein Popup-Fenster (Optionen, Mods, Skin,
|
||||
* Freunde …) erscheint nicht schlagartig, sondern wächst aus dem angeklickten
|
||||
* Knopf heraus. Dafür wird das noch unsichtbare Fenster abfotografiert und das
|
||||
* Bild in einem durchsichtigen Hilfsfenster vom Knopf aus groß gezogen; am Ende
|
||||
* übernimmt das echte Fenster an exakt derselben Stelle.
|
||||
*
|
||||
* Das Hilfsfenster entsteht jedes Mal neu und gleich in der richtigen Größe:
|
||||
* Unter Windows färbt sich ein durchsichtiges Fenster schwarz, sobald es
|
||||
* nachträglich vergrößert wird, und ein verstecktes Fenster zeichnet nicht mehr.
|
||||
* Abschaltbar unter Optionen → Darstellung → Animationen („Bewegte Oberfläche“).
|
||||
*/
|
||||
const path = require('path');
|
||||
const { BrowserWindow } = require('electron');
|
||||
|
||||
const DAUER_MS = 280;
|
||||
const HOECHSTENS_MS = 2000; // spätestens dann ist das Fenster in jedem Fall zu sehen
|
||||
const warte = (ms) => new Promise((r) => setTimeout(r, ms));
|
||||
|
||||
function vereinigung(a, b) {
|
||||
const x = Math.min(a.x, b.x);
|
||||
const y = Math.min(a.y, b.y);
|
||||
return {
|
||||
x, y,
|
||||
width: Math.max(a.x + a.width, b.x + b.width) - x,
|
||||
height: Math.max(a.y + a.height, b.y + b.height) - y,
|
||||
};
|
||||
}
|
||||
|
||||
// Rechteck in Koordinaten des Hilfsfensters umrechnen
|
||||
const relativ = (r, box) => ({ x: r.x - box.x, y: r.y - box.y, width: r.width, height: r.height });
|
||||
|
||||
async function abspielen(ziel, von, merke) {
|
||||
// unsichtbar zeigen, damit Chromium den Inhalt zeichnet, dann abfotografieren
|
||||
ziel.setOpacity(0);
|
||||
ziel.setIgnoreMouseEvents(true);
|
||||
ziel.show();
|
||||
await warte(90);
|
||||
if (ziel.isDestroyed()) return;
|
||||
const bild = await ziel.webContents.capturePage();
|
||||
if (bild.isEmpty() || ziel.isDestroyed()) return;
|
||||
const nach = ziel.getBounds();
|
||||
const box = vereinigung(von, nach);
|
||||
|
||||
const hilfe = new BrowserWindow({
|
||||
x: box.x, y: box.y, width: box.width, height: box.height,
|
||||
show: false, frame: false, transparent: true, resizable: false, movable: false,
|
||||
minimizable: false, maximizable: false, fullscreenable: false, focusable: false,
|
||||
skipTaskbar: true, hasShadow: false, alwaysOnTop: true, backgroundColor: '#00000000',
|
||||
title: 'AeroMC',
|
||||
webPreferences: { contextIsolation: true, nodeIntegration: false, sandbox: true },
|
||||
});
|
||||
merke(hilfe);
|
||||
hilfe.setIgnoreMouseEvents(true);
|
||||
await hilfe.loadFile(path.join(__dirname, 'aufbau.html'));
|
||||
const ok = await hilfe.webContents.executeJavaScript(
|
||||
`vorbereiten(${JSON.stringify(bild.toDataURL())}, ${JSON.stringify(relativ(nach, box))}, ${JSON.stringify(relativ(von, box))})`);
|
||||
if (!ok || hilfe.isDestroyed()) return;
|
||||
hilfe.showInactive();
|
||||
await hilfe.webContents.executeJavaScript(`abspielen(${DAUER_MS})`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeigt `ziel` (geladen, aber noch nicht sichtbar) mit Wachs-Animation an.
|
||||
* `von` ist das Rechteck des angeklickten Knopfs in Bildschirmkoordinaten.
|
||||
*/
|
||||
async function wachsen(ziel, von) {
|
||||
let hilfe = null;
|
||||
try {
|
||||
await Promise.race([abspielen(ziel, von, (h) => { hilfe = h; }), warte(HOECHSTENS_MS)]);
|
||||
} catch {
|
||||
// Animation ist nur Zierde – im Fehlerfall das Fenster einfach zeigen
|
||||
} finally {
|
||||
if (!ziel.isDestroyed()) {
|
||||
ziel.setOpacity(1);
|
||||
ziel.setIgnoreMouseEvents(false);
|
||||
if (!ziel.isVisible()) ziel.show();
|
||||
ziel.focus();
|
||||
}
|
||||
// Hilfsfenster erst nach dem Umschalten schließen, sonst blitzt der Hintergrund durch
|
||||
setTimeout(() => { if (hilfe && !hilfe.isDestroyed()) hilfe.destroy(); }, 60);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { wachsen };
|
||||
Reference in New Issue
Block a user