Lebensuhr clock: real 12-hour dial instead of a nonexistent 24-hour one
A clock face has 12 numbers, not 24 — the previous version invented a 0-24 dial that doesn't exist on any real clock. Now a proper 1-12 face, with each age plotted at its 12h-mod position, labeled with time + vorm./nachm. (every dial position is hit twice a day), and a filled dot for vormittags vs. a hollow ring for nachmittags so the two laps stay visually distinct.
This commit is contained in:
+49
-54
@@ -196,24 +196,19 @@ export default function LebensuhrPage() {
|
||||
</P>
|
||||
|
||||
{/* Decorative companion to the table below, not a replacement for
|
||||
it (a version that tried to carry the actual Alter/Uhrzeit
|
||||
pairs on its own read ambiguous — see the table's own
|
||||
comment) — the 8 ages plotted at their proportional clock
|
||||
position, each labeled with its matching time too. All 12
|
||||
ticks now carry their real 24h-scale hour (0,2,4…22, full
|
||||
"HH:00" at the four cardinal ones) instead of just 4 bare
|
||||
numbers — a dial showing only 00/06/12/18 read like an
|
||||
ordinary 12-hour clock face (same 4 positions), which
|
||||
wrongly implied two laps per day instead of one. Sized up
|
||||
(viewBox 420 vs. the original 250) after the smaller version
|
||||
clipped the longer time labels at the edge. Coordinates are
|
||||
hand-computed (evenly spaced every 40°/2h, since age/90,
|
||||
time/24 and tick/12 are all the same proportion, with -90°
|
||||
so age/hour 0 sits at the top), not derived from
|
||||
lebensuhrRows — if the rows above ever change, these need
|
||||
updating too. */}
|
||||
it — a real 12-hour dial (1–12, like an actual clock face;
|
||||
an earlier version numbered it 0–24, which doesn't exist on
|
||||
a real clock and read wrong for exactly that reason), with
|
||||
the 8 ages plotted at their 12-hour position. Since every
|
||||
day has two laps around a 12h dial, each point also carries
|
||||
"vorm."/"nachm." — and a filled dot for vormittags vs. a
|
||||
hollow ring for nachmittags, so the two laps stay visually
|
||||
distinct even without reading the text. Coordinates are
|
||||
hand-computed from lebensuhrRows's own age→time pairs
|
||||
(hour mod 12, -90° so 12 sits at the top) — if those rows
|
||||
ever change, these need updating too. */}
|
||||
<div className="flex justify-center py-2">
|
||||
<svg viewBox="0 0 420 420" className="w-full max-w-[22rem] h-auto" aria-hidden="true">
|
||||
<svg viewBox="-10 -10 440 440" className="w-full max-w-[22rem] h-auto" aria-hidden="true">
|
||||
<circle cx="210" cy="210" r="150" stroke="var(--color-border)" strokeWidth="1.5" fill="none" />
|
||||
{[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11].map((h) => {
|
||||
const deg = (h / 12) * 360 - 90;
|
||||
@@ -224,53 +219,51 @@ export default function LebensuhrPage() {
|
||||
const x2 = 210 + 150 * Math.cos(rad), y2 = 210 + 150 * Math.sin(rad);
|
||||
return <line key={h} x1={x1} y1={y1} x2={x2} y2={y2} stroke="var(--color-border)" strokeWidth={major ? 2 : 1.5} />;
|
||||
})}
|
||||
{/* Every hour tick labeled on the 24h scale (h*2), so the
|
||||
dial can't be mistaken for a normal 12-hour clock face. */}
|
||||
{/* The dial's own numerals, 1–12, same as a real clock face. */}
|
||||
{([
|
||||
[0, "00:00", 210, 45, "middle"],
|
||||
[1, "02", 289.0, 73.2, "start"],
|
||||
[2, "04", 346.8, 131.0, "start"],
|
||||
[3, "06:00", 375, 210, "start"],
|
||||
[4, "08", 346.8, 289.0, "start"],
|
||||
[5, "10", 289.0, 346.8, "start"],
|
||||
[6, "12:00", 210, 375, "middle"],
|
||||
[7, "14", 131.0, 346.8, "end"],
|
||||
[8, "16", 73.2, 289.0, "end"],
|
||||
[9, "18:00", 45, 210, "end"],
|
||||
[10, "20", 73.2, 131.0, "end"],
|
||||
[11, "22", 131.0, 73.2, "end"],
|
||||
] as [number, string, number, number, "start" | "middle" | "end"][]).map(([h, label, x, y, anchor]) => (
|
||||
<text
|
||||
key={h}
|
||||
x={x}
|
||||
y={y}
|
||||
textAnchor={anchor}
|
||||
dominantBaseline="middle"
|
||||
className={h % 3 === 0 ? "fill-text-primary" : "fill-text-muted"}
|
||||
style={{ fontSize: h % 3 === 0 ? 13 : 10, fontWeight: h % 3 === 0 ? 700 : 400 }}
|
||||
>
|
||||
{label}
|
||||
[1, 292.5, 67.1, "start"],
|
||||
[2, 352.9, 127.5, "start"],
|
||||
[3, 375, 210, "start"],
|
||||
[4, 352.9, 292.5, "start"],
|
||||
[5, 292.5, 352.9, "start"],
|
||||
[6, 210, 375, "middle"],
|
||||
[7, 127.5, 352.9, "end"],
|
||||
[8, 67.1, 292.5, "end"],
|
||||
[9, 45, 210, "end"],
|
||||
[10, 67.1, 127.5, "end"],
|
||||
[11, 127.5, 67.1, "end"],
|
||||
[12, 210, 45, "middle"],
|
||||
] as [number, number, number, "start" | "middle" | "end"][]).map(([h, x, y, anchor]) => (
|
||||
<text key={h} x={x} y={y} textAnchor={anchor} dominantBaseline="middle" className="fill-text-muted" style={{ fontSize: 12, fontWeight: 600 }}>
|
||||
{h}
|
||||
</text>
|
||||
))}
|
||||
{/* One dot per lebensuhrRows entry, at its 12h-dial position
|
||||
(hour mod 12) — filled for vormittags, hollow ring for
|
||||
nachmittags, since the same dial position is hit twice a
|
||||
day. */}
|
||||
{([
|
||||
[10, "02:40", 285.8, 119.6, 320.6, 78.2, "start"],
|
||||
[20, "05:20", 326.2, 189.5, 379.4, 180.1, "start"],
|
||||
[30, "08:00", 312.2, 269.0, 359.0, 296.0, "start"],
|
||||
[40, "10:40", 250.4, 320.9, 268.8, 371.6, "start"],
|
||||
[50, "13:20", 169.6, 320.9, 151.2, 371.6, "end"],
|
||||
[60, "16:00", 107.8, 269.0, 61.0, 296.0, "end"],
|
||||
[70, "18:40", 93.8, 189.5, 40.6, 180.1, "end"],
|
||||
[80, "21:20", 134.2, 119.6, 99.4, 78.2, "end"],
|
||||
] as [number, string, number, number, number, number, "start" | "end"][]).map(([age, time, dx, dy, lx, ly, anchor]) => (
|
||||
[10, "2:40", "vorm.", 326.2, 189.5, 379.4, 180.1, "start"],
|
||||
[20, "5:20", "vorm.", 250.4, 320.9, 268.8, 371.6, "start"],
|
||||
[30, "8:00", "vorm.", 107.8, 269.0, 61.0, 296.0, "end"],
|
||||
[40, "10:40", "vorm.", 134.2, 119.6, 99.4, 78.2, "end"],
|
||||
[50, "1:20", "nachm.", 285.8, 119.6, 320.6, 78.2, "start"],
|
||||
[60, "4:00", "nachm.", 312.2, 269.0, 359.0, 296.0, "start"],
|
||||
[70, "6:40", "nachm.", 169.6, 320.9, 151.2, 371.6, "end"],
|
||||
[80, "9:20", "nachm.", 93.8, 189.5, 40.6, 180.1, "end"],
|
||||
] as [number, string, string, number, number, number, number, "start" | "end"][]).map(([age, time, ampm, dx, dy, lx, ly, anchor]) => (
|
||||
<g key={age}>
|
||||
<line x1={dx} y1={dy} x2={lx} y2={ly} stroke="var(--color-border)" strokeWidth="1" />
|
||||
<circle cx={dx} cy={dy} r="5" fill="var(--color-brand)" />
|
||||
<circle cx={dx} cy={dy} r="5" fill={ampm === "vorm." ? "var(--color-brand)" : "none"} stroke="var(--color-brand)" strokeWidth="2" />
|
||||
<text x={lx} y={ly} textAnchor={anchor} dominantBaseline="middle" className="fill-text-primary" style={{ fontSize: 15, fontWeight: 700 }}>
|
||||
{age}
|
||||
</text>
|
||||
<text x={lx} y={ly + 16} textAnchor={anchor} dominantBaseline="middle" className="fill-text-muted" style={{ fontSize: 12 }}>
|
||||
<text x={lx} y={ly + 15} textAnchor={anchor} dominantBaseline="middle" className="fill-text-muted" style={{ fontSize: 11 }}>
|
||||
{time}
|
||||
</text>
|
||||
<text x={lx} y={ly + 27} textAnchor={anchor} dominantBaseline="middle" className="fill-text-muted" style={{ fontSize: 10, fontStyle: "italic" }}>
|
||||
{ampm}
|
||||
</text>
|
||||
</g>
|
||||
))}
|
||||
<text x="210" y="196" textAnchor="middle" className="fill-text-primary" style={{ fontFamily: "var(--font-caveat)", fontSize: 30 }}>
|
||||
@@ -281,7 +274,9 @@ export default function LebensuhrPage() {
|
||||
</text>
|
||||
</svg>
|
||||
</div>
|
||||
<p className="text-center text-body-sm text-text-muted -mt-1">Alter (fett) und die passende Uhrzeit darunter.</p>
|
||||
<p className="text-center text-body-sm text-text-muted -mt-1">
|
||||
Gefüllter Punkt = vormittags, Ring = nachmittags — jede Uhrzeit läuft schließlich zweimal am Tag über das Zifferblatt.
|
||||
</p>
|
||||
|
||||
{/* Still a real table (explicit "Alter"/"Uhrzeit" headers — a
|
||||
dot-on-a-line version tried here first read ambiguous
|
||||
|
||||
Reference in New Issue
Block a user