diff --git a/README.md b/README.md index d9dbc6b..37657ec 100644 --- a/README.md +++ b/README.md @@ -201,6 +201,7 @@ python3 tools/biene.py |---|---| | `web/img/biene.svg` | Favicon | | `web/js/biene.js` | Menüleiste des Schreibtischs (`BIENE_SVG`), System-Fenster und Startlauf (`BIENE_ASCII`) | +| `web/img/biene-3d.svg`, `-3d-256.png` | Anmeldebildschirm — die Schrägsicht | | `web/img/biene-256.png`, `-32.png` | Doku und Vorschau | In die HoneyBar ist dieselbe SVG-Zeile **einkopiert** — sie ist eine einzelne @@ -218,6 +219,18 @@ die Farbe mit — die Biene nicht. Ein Zeichen, das die Farbe wechselt, ist ein Symbol wie *wolke*; eines, das seine Farbe behält, ist ein Wappen. Der eine warme Fleck liest sich als „das hier ist das System selbst". +### Einmal groß: die Schrägsicht + +Auf dem Anmeldebildschirm steht dieselbe Biene als **Würfel in 2:1-Schrägsicht** +— gerechnet, nicht gemalt: Das Skript legt Deckel und die zwei sichtbaren +Wangen an und malt Streifen, Augen und Flügel darauf. Die Streifen laufen +parallel zur linken Deckelkante und setzen sich auf der rechten Wange als +senkrechte Bänder fort, damit sie über den Knick hinweg zusammenpassen. + +Sie ist **unter 64 px unbrauchbar** — zu viele Kanten auf zu wenig Pixeln —, +und genau deshalb steht sie dort: Der Anmeldebildschirm ist die einzige Stelle +mit Platz und Zeit. In den Leisten bleibt die Seitenansicht. + ### Und aus Schriftzeichen Im System-Fenster und über dem Startlauf steht dieselbe Biene aus `#`, `:` und diff --git a/tools/biene.py b/tools/biene.py index d1e9f25..1b56309 100644 --- a/tools/biene.py +++ b/tools/biene.py @@ -59,6 +59,76 @@ BIENE = [ ] +# ── Die 3/4-Ansicht ────────────────────────────────────────────────────── +# +# Nur für den Anmeldebildschirm: groß, einmal am Tag, mit Zeit zum Hinsehen. +# Unter 64 px zerfällt sie — zu viele Kanten auf zu wenig Pixeln. +# +# Ein Würfel hat in Pixelkunst die Steigung 2:1: zwei Pixel nach rechts, einer +# nach unten. Von Hand wird das krumm, also werden die drei sichtbaren Flächen +# gerechnet — Deckel als Raute, darunter zwei Wangen. Wichtig ist, **zeilenweise** +# zu rechnen: Wer die Raute Punkt für Punkt setzt, lässt Löcher, weil zwei +# Schritte nach rechts nur einen nach unten kosten. +def wuerfel(breite, wand): + hoehe = breite // 2 + mitte = breite / 2 + deckel = { + (x, y) + for y in range(hoehe) + for x in range(breite) + if abs(x + 0.5 - mitte) / 2 + abs(y + 0.5 - hoehe / 2) <= hoehe / 2 + } + unterkante = {} + for (x, y) in deckel: + unterkante[x] = max(unterkante.get(x, -1), y) + flaechen = {q: "T" for q in deckel} + for x, yb in unterkante.items(): + for t in range(1, wand + 1): + flaechen[(x, yb + t)] = "V" if x < mitte else "R" # vorn / rechts + return flaechen, unterkante, mitte + + +def schraeg(breite=22, wand=10, dx=5, dy=9, n=32, band=5): + flaechen, unterkante, mitte = wuerfel(breite, wand) + g = [["." for _ in range(n)] for _ in range(n)] + + def setz(x, y, c): + if 0 <= x + dx < n and 0 <= y + dy < n: + g[y + dy][x + dx] = c + + # Die Streifen laufen parallel zur linken Deckelkante (u = x - 2y) und + # setzen sich auf der rechten Wange als senkrechte Bänder fort: dieselbe + # Rechnung, ausgewertet an der Kante, an der die Wange beginnt. Deshalb + # passen sie über den Knick hinweg zusammen. + streifig = lambda x, y: ((x - 2 * y) // band) % 2 == 0 + for (x, y), art in sorted(flaechen.items()): + if art == "T": + setz(x, y, "S" if streifig(x, y) else "L") + elif art == "R": + setz(x, y, "s" if streifig(x, unterkante[x]) else "y") + else: + setz(x, y, "Y") + + # Augen: Rechtecke in Flächenkoordinaten — auf dem Schirm werden daraus + # Parallelogramme, genau wie beim Vorbild. + for ax in (2, 7): + for x in range(ax, ax + 3): + if x in unterkante: + for t in (3, 4, 5): + setz(x, unterkante[x] + t, "E") + if ax + 1 in unterkante: + setz(ax + 1, unterkante[ax + 1] + 4, "B") + + for k in range(3): # zwei Flügel in derselben Schräge + for b in range(6): + setz(3 + 2 * k + b, -2 + k, "W") + setz(10 + 2 * k + b, -4 + k, "w") + for k in range(2): # kurze Fühler am Deckelrand + setz(int(mitte) - 5 - k, -3 - k, "D") + setz(int(mitte) + 6 + k, -5 - k, "D") + return ["".join(z) for z in g] + + def svg(raster): """Waagerechte Läufe gleicher Farbe werden ein Rechteck — dieselbe Idee wie bei den Pixelsymbolen in web/js/glyphs.js, nur mit Farbe statt currentColor. @@ -80,7 +150,8 @@ def svg(raster): r, g, b = FARBEN[z] teile.append(f'') x += lauf - return ('") @@ -127,6 +198,10 @@ def main(): zeichen = text(BIENE) (WURZEL / "web/img/biene.svg").write_text(bild + "\n") + # Für die Anmeldung: einmal groß, in Schrägsicht. + drei = schraeg() + (WURZEL / "web/img/biene-3d.svg").write_text(svg(drei) + "\n") + png(drei, 8, WURZEL / "web/img/biene-3d-256.png") png(BIENE, 16, WURZEL / "web/img/biene-256.png") png(BIENE, 2, WURZEL / "web/img/biene-32.png") @@ -144,7 +219,7 @@ def main(): f"export const BIENE_ASCII = {json.dumps(zeichen)};\n" ) print(text(BIENE)) - print(f"\nweb/img/biene.svg ({len(bild)} Zeichen), biene-256.png, biene-32.png, web/js/biene.js") + print(f"\nweb/img/biene.svg ({len(bild)} Zeichen), biene-3d.svg, drei PNG, web/js/biene.js") if __name__ == "__main__": diff --git a/web/css/style.css b/web/css/style.css index c00432b..37fe953 100644 --- a/web/css/style.css +++ b/web/css/style.css @@ -944,8 +944,26 @@ body { overflow: hidden; } +/* Die Biene über dem Anmeldeknopf, in Schrägsicht. Sie schwebt ein wenig — + sechs Sekunden für zwei Pixel, also eher ein Atmen als eine Bewegung. Wer + Bewegung abgestellt hat, bekommt sie ruhig. */ +.login-biene { + display: block; + width: clamp(96px, 22vw, 132px); + height: auto; + margin: 22px 0 0; + image-rendering: pixelated; + animation: schweben 6s ease-in-out infinite; +} +@keyframes schweben { + 50% { transform: translateY(-4px); } +} +@media (prefers-reduced-motion: reduce) { + .login-biene { animation: none; } +} + .login-box { - margin-top: 26px; + margin-top: 20px; display: flex; flex-direction: column; align-items: flex-start; diff --git a/web/img/biene-3d-256.png b/web/img/biene-3d-256.png new file mode 100644 index 0000000..c9a6eca Binary files /dev/null and b/web/img/biene-3d-256.png differ diff --git a/web/img/biene-3d.svg b/web/img/biene-3d.svg new file mode 100644 index 0000000..36a8353 --- /dev/null +++ b/web/img/biene-3d.svg @@ -0,0 +1 @@ + diff --git a/web/index.html b/web/index.html index ed0fad6..f02d4f5 100644 --- a/web/index.html +++ b/web/index.html @@ -21,6 +21,9 @@