Die Anmeldung bekommt die Biene in Schraegsicht

Die 3/4-Ansicht ist unter 64 px unbrauchbar und deshalb genau hier richtig:
Auf dem Anmeldebildschirm ist Platz, und man wartet ohnehin auf den Anbieter.
Sie schwebt sechs Sekunden lang zwei Pixel weit — eher ein Atmen als eine
Bewegung, und bei prefers-reduced-motion steht sie still.

Gerechnet wird sie in tools/biene.py aus demselben Raster wie die anderen
Fassungen.
This commit is contained in:
marc committed 2026-09-02 10:27:03 +02:00
1 parent 3f8b98b869
commit ff413864a9
6 files changed
+113 -3

No files matched your search

+77 -2
View File
@@ -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'<rect x="{x}" y="{y}" width="{lauf}" height="1" fill="#{r:02x}{g:02x}{b:02x}"/>')
x += lauf
return ('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" '
n = len(raster)
return (f'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 {n} {n}" '
'shape-rendering="crispEdges" aria-hidden="true">' + "".join(teile) + "</svg>")
@@ -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__":