Portal-Screenshots im Geräteformat neu aufgenommen
iPhone 16 Pro 402 x 874 (Safe Area 59/34) und MacBook-Safari-Fläche 1512 x 893, je @2x, weiter nur mit den Demodaten der Bäckerei Sonnenschein. Kein Versatz mehr im iPhone; im letzten Schritt bleibt die Statusleiste deckend. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
No files matched your search
|
Before Width: | Height: | Size: 158 KiB After Width: | Height: | Size: 178 KiB |
|
Before Width: | Height: | Size: 147 KiB After Width: | Height: | Size: 169 KiB |
|
Before Width: | Height: | Size: 140 KiB After Width: | Height: | Size: 159 KiB |
|
Before Width: | Height: | Size: 133 KiB After Width: | Height: | Size: 154 KiB |
|
Before Width: | Height: | Size: 131 KiB After Width: | Height: | Size: 151 KiB |
|
Before Width: | Height: | Size: 159 KiB After Width: | Height: | Size: 180 KiB |
|
Before Width: | Height: | Size: 137 KiB After Width: | Height: | Size: 158 KiB |
|
Before Width: | Height: | Size: 166 KiB After Width: | Height: | Size: 190 KiB |
|
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 70 KiB |
|
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 6.7 KiB |
|
Before Width: | Height: | Size: 193 KiB After Width: | Height: | Size: 214 KiB |
|
Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 91 KiB |
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 73 KiB |
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 73 KiB |
|
Before Width: | Height: | Size: 57 KiB After Width: | Height: | Size: 65 KiB |
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 73 KiB |
|
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 53 KiB |
|
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 69 KiB |
|
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 70 KiB After Width: | Height: | Size: 66 KiB |
|
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 60 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 39 KiB |
|
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 57 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 59 KiB After Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 70 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 52 KiB After Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 74 KiB |
|
Before Width: | Height: | Size: 148 KiB After Width: | Height: | Size: 146 KiB |
|
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 31 KiB |
|
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 58 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 49 KiB |
|
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 51 KiB |
@@ -31,22 +31,22 @@ SCHRITT = 4
|
||||
KB = 1024
|
||||
BUDGET_DESKTOP = 120 * KB
|
||||
BUDGET_HANDY = 60 * KB
|
||||
# Der lange Screenshot ist gut dreimal so hoch wie ein Handy-Bild (5428 statt 1688 px). Sein Budget
|
||||
# Der lange Screenshot ist gut dreimal so hoch wie ein Handy-Bild (5131 statt 1748 px). Sein Budget
|
||||
# wächst mit der Höhe (je Bildschirmhöhe weiterhin unter 60 KB), sonst wäre der Text nur noch Matsch.
|
||||
BUDGET_LANG = {390: 80 * KB, 780: 150 * KB}
|
||||
# Unter der letzten Inhaltszeile (Zeile 5179) ist der Rohexport nur noch schwarz. Abgeschnitten wird
|
||||
# Unter der letzten Inhaltszeile (Zeile 5091) ist der Rohexport nur noch schwarz. Abgeschnitten wird
|
||||
# 40 px darunter, sonst endet die Verschiebung im Handy-Rahmen auf einem leeren Streifen.
|
||||
LANG_HOEHE = 5219
|
||||
LANG_HOEHE = 5131
|
||||
|
||||
# Dateiname (ohne .webp) -> (Art, Zielbreiten)
|
||||
BILDER = {
|
||||
# Desktop-Fenster (Roh 2880 x 1800)
|
||||
# Desktop-Fenster (Roh 3024 x 1786 = MacBook-Safari-Fläche 1512 x 893 @2x)
|
||||
"desktop-1-projekte": ("desktop", (800, 1200, 1600)),
|
||||
"desktop-2-fortschritt": ("desktop", (800, 1200, 1600)),
|
||||
"desktop-3b-chat-foto": ("desktop", (800, 1200, 1600)),
|
||||
"desktop-4-rechnungen": ("desktop", (800, 1200, 1600)),
|
||||
"desktop-7-news-pinnwand": ("desktop", (800, 1200, 1600)),
|
||||
# Handy (Roh 780 x 1688, das lange Bild 780 x 5428, beschnitten auf 5219)
|
||||
# Handy (Roh 804 x 1748 = iPhone 16 Pro @2x, Safe Area 59/34; das lange Bild 804 x 5340, beschnitten auf 5131)
|
||||
"phone-1-projekte": ("handy", (390, 780)),
|
||||
"phone-3-projektdetails": ("handy", (390, 780)),
|
||||
"phone-4b-chat-foto": ("handy", (390, 780)),
|
||||
|
||||
@@ -59,8 +59,8 @@ export const DesktopFenster = ({ bild, children, className, adresse = "project.w
|
||||
);
|
||||
|
||||
/**
|
||||
* Handy: iPhone 16 Pro (Inhalt in 402 x 874). Die Portal-Aufnahmen haben oben nur 47 px (Roh, 2x)
|
||||
* Rand für die Statusleiste; damit Dynamic Island nichts verdeckt, beginnt das Bild 35 px tiefer.
|
||||
* Handy: iPhone 16 Pro (Inhalt in 402 x 874). Die Portal-Aufnahmen sind genau in diesem Format
|
||||
* mit Safe Area 59 / 34 aufgenommen, Statusleiste und Home-Balken liegen also passend darüber.
|
||||
*/
|
||||
export const HandyRahmen = ({ bild, children, className }: RahmenProps) => (
|
||||
<IPhoneFrame className={className}>
|
||||
|
||||
@@ -12,6 +12,3 @@
|
||||
object-fit: cover;
|
||||
object-position: top;
|
||||
}
|
||||
.wk-geraet-inhalt--handy {
|
||||
top: 35px;
|
||||
}
|
||||
@@ -22,18 +22,19 @@ const HANDY_BREITEN = [390, 780];
|
||||
const srcSet = (name: string, breiten: number[]) =>
|
||||
breiten.map((b) => `${BILDER}/${name}-${b}.webp ${b}w`).join(", ");
|
||||
|
||||
/** Desktop-Bild: Rohformat 2880 x 1800, ausgeliefert in 800 / 1200 / 1600 px. */
|
||||
/** Desktop-Bild: Rohformat 3024 x 1786 (MacBook-Safari-Fläche 1512 x 893 @2x), ausgeliefert in 800 / 1200 / 1600 px. */
|
||||
const desktopBild = (name: string, alt: string): RahmenBildDaten => ({
|
||||
src: `${BILDER}/${name}-1200.webp`,
|
||||
srcSet: srcSet(name, DESKTOP_BREITEN),
|
||||
sizes: "(min-width: 1200px) 692px, 50vw",
|
||||
width: 1600,
|
||||
height: 1000,
|
||||
height: 945,
|
||||
alt,
|
||||
});
|
||||
|
||||
/** Handy-Bild: Rohformat 780 x 1688 (das lange Bild 780 x 5219), ausgeliefert in 390 / 780 px. */
|
||||
const handyBild = (name: string, alt: string, sizes: string, hoehe = 1688): RahmenBildDaten => ({
|
||||
/** Handy-Bild: Rohformat 804 x 1748 = iPhone 16 Pro @2x (das lange Bild 804 x 5131), ausgeliefert in 390 / 780 px;
|
||||
* width/height geben das Seitenverhältnis bei 780 px an. */
|
||||
const handyBild = (name: string, alt: string, sizes: string, hoehe = 1696): RahmenBildDaten => ({
|
||||
src: `${BILDER}/${name}-780.webp`,
|
||||
srcSet: srcSet(name, HANDY_BREITEN),
|
||||
sizes,
|
||||
@@ -291,7 +292,7 @@ const Buehne = () => {
|
||||
>
|
||||
{f.lang ? (
|
||||
<div className="kp-lang">
|
||||
<RahmenBild bild={handyBild(f.handy.name, f.handy.alt, "(min-width: 1200px) 340px, 30vw", 5219)} />
|
||||
<RahmenBild bild={handyBild(f.handy.name, f.handy.alt, "(min-width: 1200px) 340px, 30vw", 4978)} />
|
||||
</div>
|
||||
) : (
|
||||
<RahmenBild bild={handyBild(f.handy.name, f.handy.alt, "(min-width: 1200px) 230px, 20vw")} />
|
||||
@@ -326,7 +327,7 @@ const LangeKarte = ({ f }: { f: Funktion }) => {
|
||||
<div className="kp-karte" ref={ref} data-sichtbar={sichtbar ? "ja" : "nein"}>
|
||||
<HandyRahmen className="kp-karte__handy">
|
||||
<div className="kp-lang">
|
||||
<RahmenBild bild={handyBild(f.handy.name, f.handy.alt, "250px", 5219)} />
|
||||
<RahmenBild bild={handyBild(f.handy.name, f.handy.alt, "250px", 4978)} />
|
||||
</div>
|
||||
</HandyRahmen>
|
||||
<h3 className="wk-h3 kp-karte__titel">{f.titel}</h3>
|
||||
|
||||
@@ -213,8 +213,8 @@
|
||||
transform: translate(-35.9cqw, -14.2cqw) scale(1.5);
|
||||
}
|
||||
|
||||
/* Der lange Screenshot: gleiche Breite wie der Schirm, 68,81 % seiner Höhe wandern aus dem Bild
|
||||
(sichtbar sind 839 von 2690 px im iPhone-Inhalt). Die Verschiebung hängt am Scrollfortschritt (--kp-q), kein eigener Scrollbereich. */
|
||||
/* Der lange Screenshot: gleiche Breite wie der Schirm, 65,93 % seiner Höhe wandern aus dem Bild
|
||||
(sichtbar sind 874 von 2565,5 px im iPhone-Inhalt, 1 - 1748 / 5131). Die Verschiebung hängt am Scrollfortschritt (--kp-q), kein eigener Scrollbereich. */
|
||||
.kp-lang {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
@@ -237,7 +237,7 @@
|
||||
transition: transform var(--dur-enter) var(--ease);
|
||||
}
|
||||
.kp-buehne .kp-lang {
|
||||
transform: translateY(calc(var(--kp-q, 0) * -68.81%));
|
||||
transform: translateY(calc(var(--kp-q, 0) * -65.93%));
|
||||
}
|
||||
/* die große Ebene nur im letzten Schritt auf die Grafikkarte legen */
|
||||
.kp-buehne[data-app="ja"] .kp-lang {
|
||||
@@ -280,7 +280,7 @@
|
||||
transform: translateY(0);
|
||||
}
|
||||
100% {
|
||||
transform: translateY(-68.81%);
|
||||
transform: translateY(-65.93%);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -334,3 +334,15 @@
|
||||
.kp-schritt-karte .kp-schritt__nr {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
/* Wie in der echten Portal-App ist die Statusleiste deckend: der lange Screenshot läuft darunter
|
||||
durch, statt mit Uhrzeit und Symbolen zu überlappen (59 px = Safe Area oben im iPhone-Inhalt). */
|
||||
.wk-geraet-inhalt:has(.kp-lage.is-aktiv .kp-lang)::after,
|
||||
.wk-geraet-inhalt:has(> .kp-lang)::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
inset: 0 0 auto 0;
|
||||
height: 59px;
|
||||
background: radial-gradient(70% 160% at 50% 0%, #1e0b31 0%, #000 100%);
|
||||
z-index: 1;
|
||||
}
|
||||
@@ -127,10 +127,10 @@ describe("Kundenportal: Bilder (Spezifikation 9.5)", () => {
|
||||
expect(bilder).toHaveLength(6);
|
||||
for (const bild of bilder.slice(0, 5)) {
|
||||
expect(bild.getAttribute("width")).toBe("780");
|
||||
expect(bild.getAttribute("height")).toBe("1688");
|
||||
expect(bild.getAttribute("height")).toBe("1696");
|
||||
}
|
||||
expect(bilder[5].getAttribute("src")).toContain("phone-2-projekte-lang");
|
||||
expect(bilder[5].getAttribute("height")).toBe("5219");
|
||||
expect(bilder[5].getAttribute("height")).toBe("4978");
|
||||
});
|
||||
|
||||
it("Desktop: zu Beginn hängen nur die ersten beiden Schritte ihre Bilder ein (spart Daten)", () => {
|
||||
|
||||