diff --git a/assets/img/app-symbole/workspace-180.png b/assets/img/app-symbole/workspace-180.png index ed9f767d..2b8e652c 100644 Binary files a/assets/img/app-symbole/workspace-180.png and b/assets/img/app-symbole/workspace-180.png differ diff --git a/assets/img/app-symbole/workspace-192-maskable.png b/assets/img/app-symbole/workspace-192-maskable.png index a53f0563..87d12f9d 100644 Binary files a/assets/img/app-symbole/workspace-192-maskable.png and b/assets/img/app-symbole/workspace-192-maskable.png differ diff --git a/assets/img/app-symbole/workspace-192.png b/assets/img/app-symbole/workspace-192.png index 6d03c872..55e9047a 100644 Binary files a/assets/img/app-symbole/workspace-192.png and b/assets/img/app-symbole/workspace-192.png differ diff --git a/assets/img/app-symbole/workspace-32.png b/assets/img/app-symbole/workspace-32.png index 03d88edc..15ed751c 100644 Binary files a/assets/img/app-symbole/workspace-32.png and b/assets/img/app-symbole/workspace-32.png differ diff --git a/assets/img/app-symbole/workspace-512-maskable.png b/assets/img/app-symbole/workspace-512-maskable.png index fe1b2d08..55a6d64c 100644 Binary files a/assets/img/app-symbole/workspace-512-maskable.png and b/assets/img/app-symbole/workspace-512-maskable.png differ diff --git a/assets/img/app-symbole/workspace-512.png b/assets/img/app-symbole/workspace-512.png index 63d1408a..77990e0e 100644 Binary files a/assets/img/app-symbole/workspace-512.png and b/assets/img/app-symbole/workspace-512.png differ diff --git a/tools/app-symbole.mjs b/tools/app-symbole.mjs index 1d02ddd4..9e51574b 100644 --- a/tools/app-symbole.mjs +++ b/tools/app-symbole.mjs @@ -55,7 +55,19 @@ if (!existsSync(LOGO)) { ------------------------------------------------------------------ */ export const APPS = [ { schluessel: "universe", name: "Dogfather Universe", kurz: "Universe", wo: "dogfather-universe.com" }, - { schluessel: "workspace", name: "Creator Workspace", kurz: "Workspace", wo: "/workspace" }, + /* DER WORKSPACE STEHT HIER NICHT MEHR (08.09.2026). + + Sein Symbol ist seit heute kein eingefaerbtes Logo mehr, sondern + eine Mischung aus Husky UND Chili -- gebaut von + tools/workspace-symbol.mjs (Wunsch Filipe: "eine geile mischung + von diesen zwei logo"). + + Bliebe er in dieser Liste, wuerde der naechste Lauf von + `app-symbole.mjs bauen` die sechs Dateien stillschweigend + ueberschreiben -- gleiche Namen, gleicher Ordner. Nichts wuerde + scheitern, das Symbol waere nur wieder das alte, und niemand + wuesste warum. Eine Zeile, die man nicht loescht, ist eine Falle, + die man spaeter selbst stellt. */ { schluessel: "webdesign", name: "Dogfather Webdesign", kurz: "Webdesign", wo: "/webdesign" }, { schluessel: "portal", name: "Kundenportal", kurz: "Portal", wo: "/webdesign/portal.html" }, { schluessel: "wdverwalt", name: "Webdesign-Verwaltung", kurz: "WD-Verw.", wo: "/webdesign/verwaltung.html" }, diff --git a/tools/workspace-symbol.mjs b/tools/workspace-symbol.mjs new file mode 100644 index 00000000..5b128c87 --- /dev/null +++ b/tools/workspace-symbol.mjs @@ -0,0 +1,159 @@ +/* =================================================================== + Das App-Symbol des Workspace: Husky UND Chili in einem Zeichen. + + Filipe (08.09.2026): "ich will dass du da eine geile mischung machst + von diesen zwei logo ... mach was ultra krass geiles draus bitte." + + DIE AUFGABE IST NICHT "zwei Bilder nebeneinander". Ein App-Symbol + steht bei 32 px im Browserreiter und bei 192 px auf dem + Startbildschirm. Zwei vollstaendige Logos nebeneinander ergeben dort + zwei unlesbare Haelften. Gebraucht wird EINE Form, in der beide + vorkommen. + + DIE LOESUNG: Der Husky steht im Zentrum, die Chili bildet den BOGEN + um ihn -- wie der Ring eines Siegels, nur nicht geschlossen. Das ist + dieselbe Anordnung wie beim Spicy-Media-Original (Zeichen im Kreis) + und laesst dem Husky die Mitte, wo eine Silhouette bei kleiner + Groesse noch traegt. + + DER HINTERGRUND traegt beide Farben: ein diagonaler Verlauf von + Chili-Rot (unten links) nach Dogi-Blau (oben rechts), abgedunkelt, + damit der silberne Husky darauf steht statt darin zu verschwinden. + Wo sich die beiden treffen, liegt die Mitte -- genauso wie im + Schriftzug "Spicy & Dogi" in der Kopfleiste. + + MASKABLE: Android schneidet bis zu 20 % ringsum weg. Fuer diese + Fassungen sitzt alles enger zusammen und der Bogen wird kuerzer -- + sonst waere von der Chili nach dem Beschnitt nur ein Reststueck da. + + Aufrufen mit: node tools/workspace-symbol.mjs + =================================================================== */ + +import { readFileSync, writeFileSync, existsSync, mkdirSync } from "node:fs"; +import { join, dirname } from "node:path"; +import { fileURLToPath } from "node:url"; + +const WURZEL = join(dirname(fileURLToPath(import.meta.url)), ".."); +const HUSKY = join(WURZEL, "workspace", "assets", "img", "marke-husky.webp"); +const CHILI = join(WURZEL, "workspace", "assets", "img", "marke-spicy.webp"); +const ZIEL = join(WURZEL, "assets", "img", "app-symbole"); + +for (const q of [HUSKY, CHILI]) { + if (!existsSync(q)) { console.error(`Fehlt: ${q}`); process.exit(1); } +} +const alsDaten = (p) => "data:image/webp;base64," + readFileSync(p).toString("base64"); + +/* Die Groessen, die Manifest und HTML tatsaechlich anfordern. */ +const GROESSEN = [ + { n: 512, endung: "512" }, + { n: 192, endung: "192" }, + { n: 512, endung: "512-maskable", maskable: true }, + { n: 192, endung: "192-maskable", maskable: true }, + { n: 180, endung: "180" }, + { n: 32, endung: "32" }, +]; + +function html(n, maskable, husky, chili) { + /* Bei einem maskable-Symbol darf nur der innere Kreis mit 80 % + Durchmesser als sicher gelten. Alles Wichtige sitzt deshalb enger. */ + const platz = maskable ? 0.62 : 0.80; + const huskyGr = Math.round(n * platz * 0.72); + const ringGr = Math.round(n * platz); + /* Unter 64 px faellt der Chili-Bogen weg: Er waere dort ein + verwaschener Fleck und wuerde die Husky-Silhouette anfressen. + Ein Symbol, das klein noch erkennbar ist, ist mehr wert als eins, + das alle Bestandteile zeigt und dabei zu Matsch wird. */ + const mitChili = n >= 64; + return `
+ ${mitChili ? '
' : ""} +
+
`; +} + +const { chromium } = await import( + "file:///C:/Users/qciga/Documents/Obelix/Analyse/node_modules/playwright/index.mjs"); +const browser = await chromium.launch(); +const seite = await (await browser.newContext({ deviceScaleFactor: 1 })).newPage(); +if (!existsSync(ZIEL)) mkdirSync(ZIEL, { recursive: true }); + +const husky = alsDaten(HUSKY), chili = alsDaten(CHILI); +let gebaut = 0; +const schwach = []; + +for (const g of GROESSEN) { + await seite.setViewportSize({ width: g.n, height: g.n }); + await seite.setContent(html(g.n, !!g.maskable, husky, chili), { waitUntil: "networkidle" }); + const bild = await seite.screenshot({ omitBackground: false }); + const datei = join(ZIEL, `workspace-${g.endung}.png`); + writeFileSync(datei, bild); + + /* NACHSEHEN, OB WIRKLICH ETWAS DRAUFSTEHT. Ein Symbol, das aus einem + Fehler heraus einfarbig ist, hat dieselbe Dateigroesse wie eines + mit Motiv -- die Bytezahl beweist gar nichts. Gemessen wird die + Streuung der Helligkeit: Ein leeres Feld hat keine. */ + const streuung = await seite.evaluate(async (b64) => { + const bild = new Image(); bild.src = "data:image/png;base64," + b64; + await bild.decode(); + const c = document.createElement("canvas"); + c.width = bild.width; c.height = bild.height; + const g2 = c.getContext("2d"); g2.drawImage(bild, 0, 0); + const d = g2.getImageData(0, 0, c.width, c.height).data; + let s = 0, s2 = 0, n = 0; + for (let i = 0; i < d.length; i += 4) { + const h = 0.2126 * d[i] + 0.7152 * d[i + 1] + 0.0722 * d[i + 2]; + s += h; s2 += h * h; n++; + } + return Math.sqrt(s2 / n - (s / n) ** 2); + }, bild.toString("base64")); + + console.log(` workspace-${g.endung}.png`.padEnd(34) + + `${(bild.length / 1024).toFixed(1)} KB ยท Streuung ${streuung.toFixed(1)}`); + if (streuung < 12) schwach.push(`${g.endung} (${streuung.toFixed(1)})`); + gebaut++; +} +await browser.close(); + +/* Die Zahlen gehoeren in die Bedingung, nicht nur in den Bericht. */ +if (gebaut !== GROESSEN.length) { + console.error(`\nFEHLER: ${gebaut} von ${GROESSEN.length} erzeugt.`); process.exit(1); +} +if (schwach.length) { + console.error(`\nFEHLER: kaum Zeichnung in ${schwach.join(", ")} -- da steht vermutlich` + + ` nichts drauf.`); process.exit(1); +} +console.log(`\n${gebaut} Symbole erzeugt, alle mit erkennbarer Zeichnung.`);