App-Symbol: Entwurf 3 bei 54 Prozent
DataMetric oben, das CI-Fahrzeug in der Mitte, 360 in Audi-Rot unten, auf Nacht-Grund. Ausgewaehlt aus zwoelf Varianten, jede zweimal gezeigt: gross und bei 60 pt, der Groesse auf dem Homescreen - daran entschied es sich. Vektorquelle unter native/logo/, erzeugt von scripts/logo-bauen.cjs. Das Fahrzeug liest das Skript aus ICONS.audi im Panel, damit es nur eine Quelle fuer diese Form gibt; die Schriften stecken als data-URI in der SVG, sonst haengt das Ergebnis davon ab, welche Fonts auf dem rasternden Rechner installiert sind. Drei Ausfuehrungen fuer iOS 18: hell mit eigenem Grund, dunkel und getoent ohne - dort legt das System seinen eigenen Grund darunter, ein mitgeliefertes Schwarz bliebe als Kasten sichtbar. Getoent wertet iOS die Helligkeit aus, deshalb wird die 360 dort ein helleres Grau statt Rot. ios-signieren.sh legt die Vorlage ueber die von Capacitor erzeugte - ios/ ist gitignored, ein in Xcode eingesetztes Symbol waere beim naechsten cap add ios wieder weg. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -6188,3 +6188,38 @@ Fahrzeugfoto von 42 %/78 % auf 26 %/96 %; FIN statt „Fahrgestellnummer"; Solld
|
||||
`watchPosition` statt `getCurrentPosition` für die Live-Ortung, mit Abmeldung beim Verlassen der
|
||||
Seite; `NSLocationWhenInUseUsageDescription` in `ios-signieren.sh` (in der ausgelieferten `.ipa`
|
||||
fehlte jeder Location-Schlüssel — deshalb fragte iOS nie).
|
||||
|
||||
### App-Symbol (2026-08-31)
|
||||
|
||||
Gewaehlt: Entwurf 3 bei 54 % Fahrzeuggroesse — **DataMetric** oben, das CI-Fahrzeug in der Mitte,
|
||||
**360** in Audi-Rot unten, auf Nacht-Grund. Zwoelf Varianten wurden dafuer nebeneinander gezeigt,
|
||||
jede zweimal: gross und bei 60 pt, der Groesse auf dem Homescreen. Genau daran entschied es sich —
|
||||
gestapelte Elemente teilen sich dort 60 Punkte, und was gross elegant wirkt, ist klein oft ein Fleck.
|
||||
|
||||
- Vektorquelle: `companion-app/native/logo/AppIcon-{hell,dunkel,getoent}.svg`, erzeugt von
|
||||
`scripts/logo-bauen.cjs`. Das Fahrzeug liest das Skript aus `ICONS.audi` im Panel — eine zweite
|
||||
Kopie des Pfades waere eine zweite Quelle fuer dieselbe Form. Die Schriften stecken als
|
||||
data:-URI in der SVG: ohne das haengt das Ergebnis davon ab, welche Fonts auf dem
|
||||
rasternden Rechner installiert sind, und das faellt erst am fertigen Symbol auf.
|
||||
- Fertige Vorlage: `companion-app/native/AppIcon.appiconset/` (drei 1024er-PNG plus
|
||||
`Contents.json`). `ios-signieren.sh` legt sie ueber die von Capacitor erzeugte — `ios/` ist
|
||||
gitignored, ein in Xcode eingesetztes Symbol waere beim naechsten `cap add ios` wieder weg.
|
||||
- Drei Ausfuehrungen, wie iOS 18 sie erwartet: **hell** mit eigenem Grund, **dunkel** und
|
||||
**getoent** ohne. Bei den letzten beiden legt das System seinen eigenen Grund darunter; ein
|
||||
mitgeliefertes Schwarz bliebe darauf als Kasten sichtbar. Getoent wertet iOS die Helligkeit aus,
|
||||
deshalb wird die 360 dort ein helleres Grau statt Rot — abgesetzt, ohne eine Farbe zu behaupten,
|
||||
die es getoent nicht gibt.
|
||||
- Die PNG sind in Chromium aus den SVG gerastert (die eingebettete Schrift steht nur dort
|
||||
zuverlaessig zur Verfuegung). Bei einer Aenderung: `node scripts/logo-bauen.cjs`, dann neu
|
||||
rastern — die SVG sind die Quelle, die PNG das Ergebnis.
|
||||
|
||||
### Der Xcode-Lauf braucht jetzt keine Handgriffe mehr
|
||||
|
||||
`ios-signieren.sh` erledigt der Reihe nach: Git-Stand pruefen, Webbuendel bauen, `cap sync`,
|
||||
Standort-Berechtigung, Share-Erweiterung, App-Symbol, Versionsnummer aus der `manifest.json`,
|
||||
alte Bereitstellungsprofile dieser App wegraeumen, archivieren, exportieren, Luftweg vorbereiten.
|
||||
|
||||
Was zwangslaeufig manuell bleibt: die App-Gruppe und die App-ID `app.datametric360.teilen` im
|
||||
Apple-Portal (einmalig), das Keychain-„Immer erlauben" beim ersten Signieren (einmalig pro
|
||||
Schluesselbund; der nicht-interaktive Weg verlangt das Anmeldepasswort auf der Kommandozeile und
|
||||
scheidet damit aus), und `git push` der fertigen `.ipa`, weil das Telefon sie aus dem Repo laedt.
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 65 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 65 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 70 KiB |
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "AppIcon-hell.png",
|
||||
"idiom" : "universal",
|
||||
"platform" : "ios",
|
||||
"size" : "1024x1024"
|
||||
},
|
||||
{
|
||||
"appearances" : [
|
||||
{
|
||||
"appearance" : "luminosity",
|
||||
"value" : "dark"
|
||||
}
|
||||
],
|
||||
"filename" : "AppIcon-dunkel.png",
|
||||
"idiom" : "universal",
|
||||
"platform" : "ios",
|
||||
"size" : "1024x1024"
|
||||
},
|
||||
{
|
||||
"appearances" : [
|
||||
{
|
||||
"appearance" : "luminosity",
|
||||
"value" : "tinted"
|
||||
}
|
||||
],
|
||||
"filename" : "AppIcon-getoent.png",
|
||||
"idiom" : "universal",
|
||||
"platform" : "ios",
|
||||
"size" : "1024x1024"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 51 KiB |
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 51 KiB |
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 51 KiB |
@@ -119,6 +119,25 @@ fi
|
||||
echo "==> Share-Erweiterung einrichten"
|
||||
node scripts/ios-teilen-einrichten.mjs
|
||||
|
||||
# App-Symbol einspielen.
|
||||
#
|
||||
# Capacitors Vorlage bringt ein eigenes Platzhalter-Symbol mit, und ios/ ist
|
||||
# gitignored - ein in Xcode eingesetztes Symbol waere beim naechsten
|
||||
# `npx cap add ios` wieder weg. Die Vorlage liegt deshalb versioniert unter
|
||||
# native/AppIcon.appiconset und wird hier ueber die von Capacitor erzeugte
|
||||
# gelegt.
|
||||
#
|
||||
# Drei Ausfuehrungen, wie iOS 18 sie erwartet: hell mit eigenem Grund, dunkel
|
||||
# und getoent ohne - dort legt das System seinen eigenen Grund darunter, und
|
||||
# ein mitgeliefertes Schwarz bliebe darauf als Kasten sichtbar.
|
||||
echo "==> App-Symbol einspielen"
|
||||
SYMBOLZIEL="ios/App/App/Assets.xcassets/AppIcon.appiconset"
|
||||
rm -rf "$SYMBOLZIEL"
|
||||
mkdir -p "$SYMBOLZIEL"
|
||||
cp -R native/AppIcon.appiconset/. "$SYMBOLZIEL"/
|
||||
[ -f "$SYMBOLZIEL/Contents.json" ] || { echo "FEHLER: App-Symbol nicht eingespielt." >&2; exit 1; }
|
||||
echo " hell, dunkel, getoent"
|
||||
|
||||
# Versionsnummer aus der manifest.json in die App schreiben.
|
||||
#
|
||||
# Capacitors Vorlage setzt 1.0/1 und laesst es dabei - zwei nacheinander
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
/**
|
||||
* Baut die drei App-Symbol-Vorlagen als SVG.
|
||||
*
|
||||
* Gewaehlt wurde Entwurf 3 bei 54 % Fahrzeuggroesse: DataMetric oben, das
|
||||
* CI-Fahrzeug in der Mitte, 360 in Audi-Rot unten, auf Nacht-Grund.
|
||||
*
|
||||
* WARUM DIE SCHRIFTEN EINGEBETTET WERDEN
|
||||
* --------------------------------------
|
||||
* Eine SVG-Datei, die nur `font-family: "Audi Type"` nennt, sieht nur dort
|
||||
* richtig aus, wo die Schrift installiert ist. Auf einem anderen Rechner - und
|
||||
* in jedem Rasterisierer - faellt sie auf eine Ersatzschrift zurueck, und das
|
||||
* faellt erst am fertigen Symbol auf. Die woff2-Dateien stecken deshalb als
|
||||
* data:-URI in der Datei; sie ist damit fuer sich allein vollstaendig.
|
||||
*
|
||||
* DIE DREI AUSFUEHRUNGEN VON iOS 18
|
||||
* ---------------------------------
|
||||
* hell - die Kachel wie entworfen, mit eigenem Grund.
|
||||
* dunkel - ohne Grund. iOS legt seinen eigenen dunklen Verlauf darunter; ein
|
||||
* mitgeliefertes Schwarz wuerde darauf als Kasten sichtbar bleiben.
|
||||
* getoent - ohne Grund und ohne Farbe. iOS faerbt das Bild selbst nach der
|
||||
* Wahl des Nutzers ein und wertet dafuer die Helligkeit aus - das
|
||||
* Rot der 360 wird deshalb zu einem helleren Grau als der Rest,
|
||||
* damit die Zahl auch getoent noch abgesetzt bleibt.
|
||||
*
|
||||
* MASSE
|
||||
* -----
|
||||
* Alles als Anteil der Kantenlaenge, hergeleitet aus dem freigegebenen
|
||||
* Entwurf (Flex-Spalte, Abstand 0,02 - siehe index.html):
|
||||
*
|
||||
* Wort 0,095 | Abstand 0,02 | Fahrzeug 0,54 | Abstand 0,02 | Zahl 0,17
|
||||
* zusammen 0,845, der Rest verteilt sich gleichmaessig oben und unten.
|
||||
*/
|
||||
|
||||
const fs = require("fs")
|
||||
const path = require("path")
|
||||
|
||||
const SCHRIFTEN = path.join(__dirname, "..", "src", "assets", "audi", "schriften")
|
||||
|
||||
/* Das CI-Fahrzeug kommt aus dem Panel selbst - eine zweite Kopie des Pfades
|
||||
waere eine zweite Quelle fuer dieselbe Form. */
|
||||
const PANEL = path.join(
|
||||
__dirname,
|
||||
"..",
|
||||
"..",
|
||||
"custom_components",
|
||||
"audi_dashboard",
|
||||
"frontend",
|
||||
"audi-dashboard-app.js",
|
||||
)
|
||||
const MARKE = "audi: '<path"
|
||||
const roh = fs.readFileSync(PANEL, "utf8")
|
||||
const von = roh.indexOf(MARKE)
|
||||
if (von < 0) throw new Error("ICONS.audi nicht in audi-dashboard-app.js gefunden")
|
||||
const dVon = roh.indexOf('d="', von) + 3
|
||||
const dBis = roh.indexOf('"', dVon)
|
||||
const AUTO = roh.slice(dVon, dBis)
|
||||
if (!AUTO.startsWith("M")) throw new Error("Pfad sieht nicht wie erwartet aus: " + AUTO.slice(0, 30))
|
||||
|
||||
function schriftDaten(datei) {
|
||||
return fs.readFileSync(path.join(SCHRIFTEN, datei)).toString("base64")
|
||||
}
|
||||
|
||||
const TYPE = schriftDaten("audi-type-400.woff2")
|
||||
const WIDE = schriftDaten("audi-type-wide-300.woff2")
|
||||
|
||||
/* Anteile der Kantenlaenge. */
|
||||
const A = {
|
||||
wort: 0.095,
|
||||
fahrzeug: 0.54,
|
||||
zahl: 0.17,
|
||||
abstand: 0.02,
|
||||
}
|
||||
|
||||
const S = 1024
|
||||
const gesamt = (A.wort + A.abstand + A.fahrzeug + A.abstand + A.zahl) * S
|
||||
const oben = (S - gesamt) / 2
|
||||
|
||||
const wortMitte = oben + (A.wort * S) / 2
|
||||
const autoOben = oben + (A.wort + A.abstand) * S
|
||||
const autoKante = A.fahrzeug * S
|
||||
const zahlMitte = autoOben + autoKante + A.abstand * S + (A.zahl * S) / 2
|
||||
|
||||
/** Das CI-Fahrzeug aus dem 24er-Raster auf seine Kachelgroesse gebracht. */
|
||||
function fahrzeug(farbe) {
|
||||
const faktor = autoKante / 24
|
||||
const links = (S - autoKante) / 2
|
||||
return `<g transform="translate(${links.toFixed(2)} ${autoOben.toFixed(2)}) scale(${faktor.toFixed(5)})"><path d="${AUTO}" fill="${farbe}"/></g>`
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {object} o
|
||||
* @param {string|null} o.grund Hintergrund, oder null fuer keinen
|
||||
* @param {string} o.vorn Wort und Fahrzeug
|
||||
* @param {string} o.akzent die 360
|
||||
*/
|
||||
function symbol({ grund, vorn, akzent }) {
|
||||
return `<svg xmlns="http://www.w3.org/2000/svg" width="${S}" height="${S}" viewBox="0 0 ${S} ${S}">
|
||||
<style>
|
||||
@font-face { font-family: "Audi Type"; font-weight: 400; src: url(data:font/woff2;base64,${TYPE}) format("woff2"); }
|
||||
@font-face { font-family: "Audi Type Wide"; font-weight: 300; src: url(data:font/woff2;base64,${WIDE}) format("woff2"); }
|
||||
.wort { font-family: "Audi Type"; font-weight: 400; letter-spacing: -0.01em; }
|
||||
.zahl { font-family: "Audi Type Wide"; font-weight: 300; letter-spacing: -0.03em; }
|
||||
</style>
|
||||
${grund ? ` <rect width="${S}" height="${S}" fill="${grund}"/>\n` : ""}\
|
||||
<text class="wort" x="${S / 2}" y="${wortMitte.toFixed(2)}" font-size="${(A.wort * S).toFixed(2)}" fill="${vorn}" text-anchor="middle" dominant-baseline="central">DataMetric</text>
|
||||
${fahrzeug(vorn)}
|
||||
<text class="zahl" x="${S / 2}" y="${zahlMitte.toFixed(2)}" font-size="${(A.zahl * S).toFixed(2)}" fill="${akzent}" text-anchor="middle" dominant-baseline="central">360</text>
|
||||
</svg>
|
||||
`
|
||||
}
|
||||
|
||||
const AUSFUEHRUNGEN = {
|
||||
/* Nacht-Canvas und Audi-Rot aus den Tokens des Projekts. */
|
||||
hell: { grund: "#0C1014", vorn: "#FFFFFF", akzent: "#F50537" },
|
||||
dunkel: { grund: null, vorn: "#FFFFFF", akzent: "#F50537" },
|
||||
/* Getoent wertet iOS die Helligkeit aus: Weiss fuer Wort und Fahrzeug, ein
|
||||
helles Grau fuer die Zahl - so bleibt sie abgesetzt, ohne eine Farbe zu
|
||||
behaupten, die es getoent nicht gibt. */
|
||||
getoent: { grund: null, vorn: "#FFFFFF", akzent: "#B4B4B8" },
|
||||
}
|
||||
|
||||
const ZIEL = path.join(__dirname, "..", "native", "logo")
|
||||
fs.mkdirSync(ZIEL, { recursive: true })
|
||||
|
||||
for (const [name, o] of Object.entries(AUSFUEHRUNGEN)) {
|
||||
const datei = path.join(ZIEL, `AppIcon-${name}.svg`)
|
||||
fs.writeFileSync(datei, symbol(o), "utf8")
|
||||
console.log(`${path.basename(datei)} ${(fs.statSync(datei).size / 1024).toFixed(0)} KB`)
|
||||
}
|
||||
|
||||
console.log("")
|
||||
console.log("Masse bei 1024:")
|
||||
console.log(` Wort Mitte y=${wortMitte.toFixed(1)} Groesse ${(A.wort * S).toFixed(1)}`)
|
||||
console.log(` Fahrzeug oben y=${autoOben.toFixed(1)} Kante ${autoKante.toFixed(1)}`)
|
||||
console.log(` Zahl Mitte y=${zahlMitte.toFixed(1)} Groesse ${(A.zahl * S).toFixed(1)}`)
|
||||
Reference in New Issue
Block a user