Grosse Kacheln kippen jetzt weniger als kleine

Auf der Portfolio-Seite war die Bewegung zu stark. Der Grund liegt nicht
am Winkel, sondern an der Groesse: Bei gleichem Winkel legt eine grosse
Kachel an ihren Ecken viel mehr Weg zurueck als eine kleine.

Eine Preiskachel auf der Startseite ist 282 Punkte lang, eine
Portfolio-Kachel 1503. Fuenf Grad sehen bei der einen beilaeufig aus und
bei der anderen wie das Kippen des halben Bildschirms -- obwohl in
beiden Faellen exakt derselbe Wert im Stilblatt steht.

Der Winkel haengt jetzt an der Kachelgroesse. Bezugswert sind 420
Punkte: Kacheln bis dahin kippen voll, groessere anteilig weniger. Nach
unten bei 1,4 Grad begrenzt, damit auch die groesste Kachel noch
erkennbar reagiert und der Effekt nicht einfach ausfaellt.

Gemessen ueber alle Seiten:

  index        282px   Faktor 5,00   2,45 Grad
  ueber        588px   Faktor 3,57   1,76 Grad
  portal       562px   Faktor 3,74   1,83 Grad
  ablauf      1130px   Faktor 1,86   1,19 Grad
  leistungen  1206px   Faktor 1,74   1,14 Grad
  portfolio   1503px   Faktor 1,40   0,92 Grad

Der Durchlauf sammelt diese Werte jetzt und prueft das Verhaeltnis: Die
grosse Kachel MUSS weniger kippen als die kleine, und der Faktor darf
nie unter 1,4 fallen. Ein blosser Test auf "hoechstens neun Grad" haette
den Unterschied nicht bemerkt -- beide Faelle lagen ja deutlich
darunter, und trotzdem war einer davon zu viel.

Geprueft: 298 Pruefungen gruen (Bewegung 34, Portfolio 19, Verwaltung 62,
CRYONOVA 53, Blickfang 13, System 5, Abmelden 16, Abbruch 42,
Angebot 54).

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
2026-08-25 13:11:53 +02:00
co-authored by Claude Opus 5
parent 52f5d31199
commit 81c7d40274
6 changed files with 68 additions and 10 deletions
+8 -4
View File
@@ -656,10 +656,14 @@ a.wd-karte:hover, .wd-karte--klickbar:hover {
hoechstens fuenf Grad Neigung niemand sieht. */ hoechstens fuenf Grad Neigung niemand sieht. */
.wd-karte { .wd-karte {
transform-style: preserve-3d; transform-style: preserve-3d;
/* --wd-kipp kommt aus dem Skript und haengt an der Kachelgroesse:
kleine Kacheln kippen voll, grosse anteilig weniger. Ohne das
sieht derselbe Winkel bei einer Portfolio-Kachel aus wie das
Kippen des halben Bildschirms. */
transform: transform:
perspective(1400px) perspective(1400px)
rotateX(calc(var(--wd-ny, 0) * -5deg)) rotateX(calc(var(--wd-ny, 0) * var(--wd-kipp, 5) * -1deg))
rotateY(calc(var(--wd-nx, 0) * 5deg)); rotateY(calc(var(--wd-nx, 0) * var(--wd-kipp, 5) * 1deg));
transition: transition:
transform .32s cubic-bezier(.2,.8,.3,1), transform .32s cubic-bezier(.2,.8,.3,1),
box-shadow .32s ease; box-shadow .32s ease;
@@ -670,8 +674,8 @@ a.wd-karte:hover, .wd-karte--klickbar:hover {
.wd-karte:hover { .wd-karte:hover {
transform: transform:
perspective(1400px) perspective(1400px)
rotateX(calc(var(--wd-ny, 0) * -5deg)) rotateX(calc(var(--wd-ny, 0) * var(--wd-kipp, 5) * -1deg))
rotateY(calc(var(--wd-nx, 0) * 5deg)) rotateY(calc(var(--wd-nx, 0) * var(--wd-kipp, 5) * 1deg))
translateZ(20px); translateZ(20px);
box-shadow: box-shadow:
0 40px 84px -34px rgb(0 0 0 / .92), 0 40px 84px -34px rgb(0 0 0 / .92),
+16
View File
@@ -961,6 +961,22 @@
var ny = ((letzte.y - r.top) / r.height - 0.5) * 2; var ny = ((letzte.y - r.top) / r.height - 0.5) * 2;
k.style.setProperty("--wd-nx", nx.toFixed(3)); k.style.setProperty("--wd-nx", nx.toFixed(3));
k.style.setProperty("--wd-ny", ny.toFixed(3)); k.style.setProperty("--wd-ny", ny.toFixed(3));
/* WIE STARK gekippt wird, haengt an der Groesse der Kachel.
Bei gleichem Winkel legt eine grosse Kachel an ihren Ecken
viel mehr Weg zurueck als eine kleine -- fuenf Grad sehen
bei einer Preiskachel von 280 Punkten beilaeufig aus und
bei einer Portfolio-Kachel von 1470 Punkten wie ein
Kippen des halben Bildschirms.
Deshalb ein fester Bezugswert von 420 Punkten: Kacheln bis
dahin kippen voll, groessere anteilig weniger. Nach unten
bei 1,4 Grad begrenzt, damit auch die groesste Kachel noch
erkennbar reagiert und der Effekt nicht einfach ausfaellt. */
var lang = Math.max(r.width, r.height);
var grad = Math.max(1.4, Math.min(5, 5 * (420 / lang)));
k.style.setProperty("--wd-kipp", grad.toFixed(2));
} }
}); });
}, { passive: true }); }, { passive: true });
Binary file not shown.

Before

Width:  |  Height:  |  Size: 914 KiB

After

Width:  |  Height:  |  Size: 923 KiB

+40 -2
View File
@@ -42,6 +42,8 @@ const SEITEN = ["index", "leistungen", "ablauf", "portfolio", "ueber", "portal"]
srv.listen(4405, async () => { srv.listen(4405, async () => {
const browser = await chromium.launch(); const browser = await chromium.launch();
const gemessen = [];
console.log("1. NEIGEN SICH DIE KACHELN AUF JEDER SEITE?"); console.log("1. NEIGEN SICH DIE KACHELN AUF JEDER SEITE?");
for (const name of SEITEN) { for (const name of SEITEN) {
const seite = await browser.newPage({ viewport: { width: 1440, height: 900 } }); const seite = await browser.newPage({ viewport: { width: 1440, height: 900 } });
@@ -84,11 +86,16 @@ srv.listen(4405, async () => {
await seite.mouse.move(ziel.x, ziel.y, { steps: 14 }); await seite.mouse.move(ziel.x, ziel.y, { steps: 14 });
await seite.waitForTimeout(600); await seite.waitForTimeout(600);
const d = await karte.evaluate((e) => ({ const d = await karte.evaluate((e) => {
const r = e.getBoundingClientRect();
return {
nx: parseFloat(e.style.getPropertyValue("--wd-nx")), nx: parseFloat(e.style.getPropertyValue("--wd-nx")),
matrix: getComputedStyle(e).transform, matrix: getComputedStyle(e).transform,
lumen: getComputedStyle(e).getPropertyValue("--wd-lumen").trim(), lumen: getComputedStyle(e).getPropertyValue("--wd-lumen").trim(),
})); kipp: parseFloat(e.style.getPropertyValue("--wd-kipp")),
laengsteSeite: Math.round(Math.max(r.width, r.height)),
};
});
pruefe(`${name}: die Kachel neigt sich`, pruefe(`${name}: die Kachel neigt sich`,
d.matrix.startsWith("matrix3d") && !Number.isNaN(d.nx), d.matrix.startsWith("matrix3d") && !Number.isNaN(d.nx),
`nx ${d.nx}`); `nx ${d.nx}`);
@@ -98,6 +105,7 @@ srv.listen(4405, async () => {
const zahlen = d.matrix.slice(d.matrix.indexOf("(") + 1, -1).split(",").map(Number); const zahlen = d.matrix.slice(d.matrix.indexOf("(") + 1, -1).split(",").map(Number);
const winkel = Math.abs(Math.asin(Math.max(-1, Math.min(1, zahlen[2]))) * 180 / Math.PI); const winkel = Math.abs(Math.asin(Math.max(-1, Math.min(1, zahlen[2]))) * 180 / Math.PI);
pruefe(`${name}: und bleibt flach genug`, winkel <= 9, winkel.toFixed(1) + " Grad"); pruefe(`${name}: und bleibt flach genug`, winkel <= 9, winkel.toFixed(1) + " Grad");
gemessen.push({ seite: name, flaeche: d.laengsteSeite, faktor: d.kipp, winkel });
} }
/* Beim Verlassen zuruecksetzen. */ /* Beim Verlassen zuruecksetzen. */
@@ -110,6 +118,36 @@ srv.listen(4405, async () => {
await seite.close(); await seite.close();
} }
console.log("\n1b. GROSSE KACHELN KIPPEN WENIGER ALS KLEINE");
for (const g of gemessen) {
console.log(" " + g.seite.padEnd(11) + " laengste Seite " +
String(g.flaeche).padStart(4) + "px Faktor " + g.faktor +
" " + g.winkel.toFixed(2) + " Grad");
}
/* Bei gleichem Winkel legt eine grosse Kachel an ihren Ecken viel
mehr Weg zurueck als eine kleine. Eine Portfolio-Kachel ist ueber
1400 Punkte hoch -- dort sah derselbe Winkel aus wie das Kippen des
halben Bildschirms. Deshalb skaliert der Faktor mit der Groesse. */
const gross = gemessen.filter((g) => g.flaeche > 900);
const klein = gemessen.filter((g) => g.flaeche < 500);
if (gross.length && klein.length) {
const groessterGross = Math.max(...gross.map((g) => g.winkel));
const kleinsterKlein = Math.min(...klein.map((g) => g.winkel));
pruefe("die grosse Kachel kippt weniger als die kleine",
groessterGross < kleinsterKlein,
groessterGross.toFixed(2) + " Grad gegen " + kleinsterKlein.toFixed(2) + " Grad");
} else {
pruefe("grosse und kleine Kacheln zum Vergleichen gefunden", false,
gross.length + " grosse, " + klein.length + " kleine");
}
/* Nach unten begrenzt, damit der Effekt bei sehr grossen Kacheln
nicht einfach ausfaellt. */
pruefe("aber auch die groesste reagiert noch sichtbar",
gemessen.every((g) => g.faktor >= 1.4),
"kleinster Faktor " + Math.min(...gemessen.map((g) => g.faktor)));
console.log("\n2. DIE EINBLENDUNG DARF DIE NEIGUNG NICHT LOESCHEN"); console.log("\n2. DIE EINBLENDUNG DARF DIE NEIGUNG NICHT LOESCHEN");
const s2 = await browser.newPage({ viewport: { width: 1440, height: 900 } }); const s2 = await browser.newPage({ viewport: { width: 1440, height: 900 } });
await s2.goto("http://127.0.0.1:4405/webdesign/leistungen.html"); await s2.goto("http://127.0.0.1:4405/webdesign/leistungen.html");
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 MiB

After

Width:  |  Height:  |  Size: 1.2 MiB

+1 -1
View File
@@ -34,7 +34,7 @@
Start alle alten Zwischenspeicher weg. Muss bei jeder Änderung an den Start alle alten Zwischenspeicher weg. Muss bei jeder Änderung an den
Dateien unten hochgezählt werden, sonst hängen Nutzer auf einem alten Dateien unten hochgezählt werden, sonst hängen Nutzer auf einem alten
Stand fest. */ Stand fest. */
const CACHE_NAME = "dogfather-webdesign-v45"; const CACHE_NAME = "dogfather-webdesign-v46";
/* Bausteine, die die Oberfläche zum Anzeigen braucht. Bewusst KEINE /* Bausteine, die die Oberfläche zum Anzeigen braucht. Bewusst KEINE
HTML-Datei in dieser Liste. */ HTML-Datei in dieser Liste. */