feat(android): a shield instead of a padlock, and the launch screen matches
The padlock was drawn in thin blue strokes on slate: at 36 px the outline muddied and the shackle vanished. A filled white shield with a punched keyhole keeps its silhouette at every size, and says protection more plainly. The keyhole is CUT OUT rather than painted, through an even-odd fill on a single path - painting it meant keeping two files agreeing on one colour, and any drift would have read as a smudge. The launch layer is the exception: it sits flat on the system background, where a cut-out would be a hole, so there the keyhole is painted and stays entirely inside the white shield. The launch background takes the top of the app gradient instead of slate, so the launch screen dissolves into the first screen rather than cutting against it. No gradient inside the vectors: the aapt this chain uses does not know inline gradients. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 655 B After Width: | Height: | Size: 711 B |
|
Before Width: | Height: | Size: 877 B After Width: | Height: | Size: 922 B |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 3.0 KiB |
@@ -1,13 +1,16 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!-- Fond de l'icone adaptative. Le systeme y applique son propre masque
|
<!-- Fond de l'icone adaptative : un aplat, dans le bleu de l'application.
|
||||||
(rond, carre arrondi, goutte selon le lanceur), donc il doit couvrir les
|
Le systeme le decoupe a la forme voulue par le lanceur (cercle, carre
|
||||||
108 unites entieres : tout ce qui manque devient un bord blanc. -->
|
arrondi, goutte), donc il doit couvrir les 108 unites entieres.
|
||||||
|
|
||||||
|
Pas de degrade : aapt - la premiere version, celle que sert la chaine de
|
||||||
|
ce projet - ne connait pas les degrades en ligne dans un vecteur. -->
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:width="108dp"
|
android:width="108dp"
|
||||||
android:height="108dp"
|
android:height="108dp"
|
||||||
android:viewportWidth="108"
|
android:viewportWidth="108"
|
||||||
android:viewportHeight="108">
|
android:viewportHeight="108">
|
||||||
<path
|
<path
|
||||||
android:fillColor="#0F172A"
|
android:fillColor="#1B3563"
|
||||||
android:pathData="M0,0h108v108h-108z" />
|
android:pathData="M0,0 L108,0 L108,108 L0,108 Z" />
|
||||||
</vector>
|
</vector>
|
||||||
|
|||||||
@@ -1,29 +1,26 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!-- Avant-plan de l'icone adaptative : un cadenas.
|
<!-- Avant-plan de l'icone adaptative : un bouclier a serrure.
|
||||||
TOUT DOIT TENIR DANS LES 66 UNITES CENTRALES (soit 21..87) : le systeme
|
TOUT DOIT TENIR DANS LES 66 UNITES CENTRALES (soit 21..87) : le systeme
|
||||||
recadre et anime la couche autour de cette zone sure, et ce qui deborde
|
recadre et anime la couche autour de cette zone sure, et ce qui deborde
|
||||||
peut etre rogne selon le lanceur. Le dessin ci-dessous occupe 34..74. -->
|
peut etre rogne selon le lanceur. Le dessin occupe 31..77 en x, 29..82
|
||||||
|
en y.
|
||||||
|
|
||||||
|
UN SEUL CHEMIN, EN EVENODD. La serrure n'est pas peinte de la couleur du
|
||||||
|
fond, elle est EVIDEE : le fond se voit au travers. Peinte, elle imposerait
|
||||||
|
de tenir deux fichiers d'accord sur une couleur, et le moindre ecart se
|
||||||
|
verrait comme une tache. Evidee, il n'y a rien a synchroniser.
|
||||||
|
|
||||||
|
Blanc plein plutot qu'un trait bleu : a 36 px un contour se boue, une
|
||||||
|
silhouette pleine tient. -->
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:width="108dp"
|
android:width="108dp"
|
||||||
android:height="108dp"
|
android:height="108dp"
|
||||||
android:viewportWidth="108"
|
android:viewportWidth="108"
|
||||||
android:viewportHeight="108">
|
android:viewportHeight="108">
|
||||||
<!-- Anse : trait, pas remplissage, pour garder l'interieur ajoure. -->
|
|
||||||
<path
|
<path
|
||||||
android:strokeColor="#3B82F6"
|
android:fillColor="#FFFFFF"
|
||||||
android:strokeWidth="5.5"
|
android:fillType="evenOdd"
|
||||||
android:strokeLineCap="round"
|
android:pathData="M54,29 L77,37 L77,56 C77,69.5 67,78 54,82 C41,78 31,69.5 31,56 L31,37 Z
|
||||||
android:fillColor="#00000000"
|
M54,50 m-7,0 a7,7 0 1,0 14,0 a7,7 0 1,0 -14,0 Z
|
||||||
android:pathData="M44,56 L44,47 A10,10 0 0 1 64,47 L64,56" />
|
M51,55.5 L57,55.5 L58.6,70 L49.4,70 Z" />
|
||||||
<!-- Corps -->
|
|
||||||
<path
|
|
||||||
android:fillColor="#3B82F6"
|
|
||||||
android:pathData="M38,54 L70,54 A4,4 0 0 1 74,58 L74,76 A4,4 0 0 1 70,80 L38,80 A4,4 0 0 1 34,76 L34,58 A4,4 0 0 1 38,54 Z" />
|
|
||||||
<!-- Serrure, evidee dans la couleur du fond -->
|
|
||||||
<path
|
|
||||||
android:fillColor="#0F172A"
|
|
||||||
android:pathData="M54,62 m-4,0 a4,4 0 1,0 8,0 a4,4 0 1,0 -8,0 Z" />
|
|
||||||
<path
|
|
||||||
android:fillColor="#0F172A"
|
|
||||||
android:pathData="M52.2,66 L55.8,66 L55,73.5 L53,73.5 Z" />
|
|
||||||
</vector>
|
</vector>
|
||||||
|
|||||||
@@ -1,22 +1,17 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!-- Version monochrome, pour les icones themees d'Android 13+. Le systeme
|
<!-- Couche monochrome (icones thematiques d'Android 13+). Le systeme ne
|
||||||
ignore les couleurs et ne garde que la silhouette, qu'il teinte selon le
|
retient que la FORME : il repeint le dessin avec la couleur du theme de
|
||||||
fond d'ecran. La serrure doit donc etre un TROU dans le trace, pas une
|
l'utilisateur, donc la couleur posee ici n'a aucune importance.
|
||||||
forme d'une autre couleur - d'ou le remplissage evenOdd plutot que deux
|
Meme bouclier que l'avant-plan, serrure evidee de la meme facon. -->
|
||||||
chemins superposes. -->
|
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:width="108dp"
|
android:width="108dp"
|
||||||
android:height="108dp"
|
android:height="108dp"
|
||||||
android:viewportWidth="108"
|
android:viewportWidth="108"
|
||||||
android:viewportHeight="108">
|
android:viewportHeight="108">
|
||||||
<path
|
|
||||||
android:strokeColor="#FFFFFF"
|
|
||||||
android:strokeWidth="5.5"
|
|
||||||
android:strokeLineCap="round"
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M44,56 L44,47 A10,10 0 0 1 64,47 L64,56" />
|
|
||||||
<path
|
<path
|
||||||
android:fillColor="#FFFFFF"
|
android:fillColor="#FFFFFF"
|
||||||
android:fillType="evenOdd"
|
android:fillType="evenOdd"
|
||||||
android:pathData="M38,54 L70,54 A4,4 0 0 1 74,58 L74,76 A4,4 0 0 1 70,80 L38,80 A4,4 0 0 1 34,76 L34,58 A4,4 0 0 1 38,54 Z M54,62 m-4,0 a4,4 0 1,0 8,0 a4,4 0 1,0 -8,0 Z M52.2,66 L55.8,66 L55,73.5 L53,73.5 Z" />
|
android:pathData="M54,29 L77,37 L77,56 C77,69.5 67,78 54,82 C41,78 31,69.5 31,56 L31,37 Z
|
||||||
|
M54,50 m-7,0 a7,7 0 1,0 14,0 a7,7 0 1,0 -14,0 Z
|
||||||
|
M51,55.5 L57,55.5 L58.6,70 L49.4,70 Z" />
|
||||||
</vector>
|
</vector>
|
||||||
|
|||||||
@@ -2,26 +2,25 @@
|
|||||||
<!-- Icone de l'ecran de demarrage.
|
<!-- Icone de l'ecran de demarrage.
|
||||||
Sur Android 12+, le systeme l'affiche via windowSplashScreenAnimatedIcon
|
Sur Android 12+, le systeme l'affiche via windowSplashScreenAnimatedIcon
|
||||||
dans un disque de 288 unites dont il ne garantit que les 192 centrales :
|
dans un disque de 288 unites dont il ne garantit que les 192 centrales :
|
||||||
le dessin ci-dessous occupe 101..187, bien a l'interieur.
|
le dessin occupe 103..186, bien a l'interieur.
|
||||||
C'est le meme cadenas que l'icone du lanceur, a l'echelle. -->
|
Meme bouclier que l'icone du lanceur, a l'echelle.
|
||||||
|
|
||||||
|
ICI LA SERRURE EST PEINTE, pas evidee : la couche de demarrage est posee
|
||||||
|
a plat sur le fond du systeme, et un evidement y ferait un trou. Elle est
|
||||||
|
entierement contenue dans le bouclier blanc, donc sa couleur n'a qu'a
|
||||||
|
trancher sur du blanc - elle ne depend d'aucun autre fichier. -->
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:width="288dp"
|
android:width="288dp"
|
||||||
android:height="288dp"
|
android:height="288dp"
|
||||||
android:viewportWidth="288"
|
android:viewportWidth="288"
|
||||||
android:viewportHeight="288">
|
android:viewportHeight="288">
|
||||||
<path
|
<path
|
||||||
android:strokeColor="#3B82F6"
|
android:fillColor="#FFFFFF"
|
||||||
android:strokeWidth="11"
|
android:pathData="M144,96.3 L185.4,110.7 L185.4,144.9 C185.4,169.2 167.4,184.5 144,191.7 C120.6,184.5 102.6,169.2 102.6,144.9 L102.6,110.7 Z" />
|
||||||
android:strokeLineCap="round"
|
|
||||||
android:fillColor="#00000000"
|
|
||||||
android:pathData="M124,139 L124,121 A20,20 0 0 1 164,121 L164,139" />
|
|
||||||
<path
|
<path
|
||||||
android:fillColor="#3B82F6"
|
android:fillColor="#1B3563"
|
||||||
android:pathData="M112,135 L176,135 A8,8 0 0 1 184,143 L184,179 A8,8 0 0 1 176,187 L112,187 A8,8 0 0 1 104,179 L104,143 A8,8 0 0 1 112,135 Z" />
|
android:pathData="M144,134.1 m-12.6,0 a12.6,12.6 0 1,0 25.2,0 a12.6,12.6 0 1,0 -25.2,0 Z" />
|
||||||
<path
|
<path
|
||||||
android:fillColor="#0F172A"
|
android:fillColor="#1B3563"
|
||||||
android:pathData="M144,151 m-8,0 a8,8 0 1,0 16,0 a8,8 0 1,0 -16,0 Z" />
|
android:pathData="M138.6,144 L149.4,144 L152.3,170.1 L135.7,170.1 Z" />
|
||||||
<path
|
|
||||||
android:fillColor="#0F172A"
|
|
||||||
android:pathData="M140.4,159 L151.6,159 L149,174 L143,174 Z" />
|
|
||||||
</vector>
|
</vector>
|
||||||
|
|||||||
@@ -3,5 +3,7 @@
|
|||||||
ecran de demarrage blanc suivi d'une application sombre donne un flash
|
ecran de demarrage blanc suivi d'une application sombre donne un flash
|
||||||
desagreable a chaque lancement. -->
|
desagreable a chaque lancement. -->
|
||||||
<resources xmlns:android="http://schemas.android.com/apk/res/android">
|
<resources xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<color name="splash_background">#0F172A</color>
|
<!-- Le haut du degrade de l'application : l'ecran de demarrage se fond
|
||||||
|
alors dans le premier ecran au lieu de le trancher. -->
|
||||||
|
<color name="splash_background">#3E6394</color>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Genere les icones PNG du lanceur, pour Android < 8 qui ignore les icones
|
# Genere les icones PNG du lanceur, pour Android < 8 qui ignore les icones
|
||||||
# adaptatives. Meme dessin que les vecteurs de android-res\drawable :
|
# adaptatives. Meme dessin que les vecteurs de android-res\drawable :
|
||||||
# cadenas cyan sur ardoise.
|
# bouclier blanc a serrure, sur le bleu de l'application.
|
||||||
#
|
#
|
||||||
# A relancer seulement si le dessin change ; les PNG sont suivis par git.
|
# A relancer seulement si le dessin change ; les PNG sont suivis par git.
|
||||||
|
|
||||||
@@ -8,8 +8,8 @@ $ErrorActionPreference = 'Stop'
|
|||||||
Add-Type -AssemblyName System.Drawing
|
Add-Type -AssemblyName System.Drawing
|
||||||
|
|
||||||
$root = Join-Path $PSScriptRoot 'android-res'
|
$root = Join-Path $PSScriptRoot 'android-res'
|
||||||
$bg = [System.Drawing.Color]::FromArgb(255, 15, 23, 42) # #0F172A
|
$bg = [System.Drawing.Color]::FromArgb(255, 27, 53, 99) # #1B3563
|
||||||
$fg = [System.Drawing.Color]::FromArgb(255, 59, 130, 246) # #3B82F6
|
$fg = [System.Drawing.Color]::FromArgb(255, 255, 255, 255) # blanc
|
||||||
|
|
||||||
# densite -> cote en pixels, tel qu'Android les attend
|
# densite -> cote en pixels, tel qu'Android les attend
|
||||||
$sizes = @{ 'drawable-ldpi' = 36; 'drawable-mdpi' = 48; 'drawable-hdpi' = 72
|
$sizes = @{ 'drawable-ldpi' = 36; 'drawable-mdpi' = 48; 'drawable-hdpi' = 72
|
||||||
@@ -38,29 +38,37 @@ foreach ($dir in $sizes.Keys) {
|
|||||||
# Echelle : le dessin vectoriel vit dans un carre de 108.
|
# Echelle : le dessin vectoriel vit dans un carre de 108.
|
||||||
$u = $n / 108.0
|
$u = $n / 108.0
|
||||||
$brush = New-Object System.Drawing.SolidBrush $fg
|
$brush = New-Object System.Drawing.SolidBrush $fg
|
||||||
$pen = New-Object System.Drawing.Pen $fg, ([float](5.5 * $u))
|
|
||||||
$pen.StartCap = 'Round'; $pen.EndCap = 'Round'
|
|
||||||
|
|
||||||
# Anse : demi-cercle ouvert vers le bas, puis deux montants.
|
# Bouclier : sommet, epaules, montants, puis les deux courbes qui se
|
||||||
$g.DrawArc($pen, [float](44*$u), [float](37*$u), [float](20*$u), [float](20*$u), 180, 180)
|
# rejoignent en pointe. Memes coordonnees que ic_launcher_foreground.xml.
|
||||||
$g.DrawLine($pen, [float](44*$u), [float](47*$u), [float](44*$u), [float](56*$u))
|
$s = New-Object System.Drawing.Drawing2D.GraphicsPath
|
||||||
$g.DrawLine($pen, [float](64*$u), [float](47*$u), [float](64*$u), [float](56*$u))
|
$s.AddLines(@(
|
||||||
|
(New-Object System.Drawing.PointF ([float](54*$u), [float](29*$u))),
|
||||||
|
(New-Object System.Drawing.PointF ([float](77*$u), [float](37*$u))),
|
||||||
|
(New-Object System.Drawing.PointF ([float](77*$u), [float](56*$u)))))
|
||||||
|
$s.AddBezier(
|
||||||
|
[float](77*$u), [float](56*$u), [float](77*$u), [float](69.5*$u),
|
||||||
|
[float](67*$u), [float](78*$u), [float](54*$u), [float](82*$u))
|
||||||
|
$s.AddBezier(
|
||||||
|
[float](54*$u), [float](82*$u), [float](41*$u), [float](78*$u),
|
||||||
|
[float](31*$u), [float](69.5*$u), [float](31*$u), [float](56*$u))
|
||||||
|
$s.AddLine([float](31*$u), [float](56*$u), [float](31*$u), [float](37*$u))
|
||||||
|
$s.CloseFigure()
|
||||||
|
$g.FillPath($brush, $s)
|
||||||
|
|
||||||
# Corps
|
# Serrure, evidee dans la couleur du fond. Le vecteur y arrive par un
|
||||||
$body = New-Object System.Drawing.Drawing2D.GraphicsPath
|
# remplissage pair-impair ; ici, repeindre par-dessus revient au meme,
|
||||||
$bx = 34*$u; $by = 54*$u; $bw = 40*$u; $bh = 26*$u; $br = 4*$u
|
# l'icone ancienne etant de toute facon opaque.
|
||||||
$body.AddArc([float]$bx, [float]$by, [float](2*$br), [float](2*$br), 180, 90)
|
|
||||||
$body.AddArc([float]($bx+$bw-2*$br), [float]$by, [float](2*$br), [float](2*$br), 270, 90)
|
|
||||||
$body.AddArc([float]($bx+$bw-2*$br), [float]($by+$bh-2*$br), [float](2*$br), [float](2*$br), 0, 90)
|
|
||||||
$body.AddArc([float]$bx, [float]($by+$bh-2*$br), [float](2*$br), [float](2*$br), 90, 90)
|
|
||||||
$body.CloseFigure()
|
|
||||||
$g.FillPath($brush, $body)
|
|
||||||
|
|
||||||
# Serrure, evidee dans la couleur du fond
|
|
||||||
$bgBrush = New-Object System.Drawing.SolidBrush $bg
|
$bgBrush = New-Object System.Drawing.SolidBrush $bg
|
||||||
$g.FillEllipse($bgBrush, [float](50*$u), [float](58*$u), [float](8*$u), [float](8*$u))
|
$g.FillEllipse($bgBrush, [float](47*$u), [float](43*$u), [float](14*$u), [float](14*$u))
|
||||||
$g.FillRectangle($bgBrush, [float](52.4*$u), [float](64*$u), [float](3.2*$u), [float](9*$u))
|
$slot = New-Object System.Drawing.Drawing2D.GraphicsPath
|
||||||
|
$slot.AddLines(@(
|
||||||
|
(New-Object System.Drawing.PointF ([float](51*$u), [float](55.5*$u))),
|
||||||
|
(New-Object System.Drawing.PointF ([float](57*$u), [float](55.5*$u))),
|
||||||
|
(New-Object System.Drawing.PointF ([float](58.6*$u), [float](70*$u))),
|
||||||
|
(New-Object System.Drawing.PointF ([float](49.4*$u), [float](70*$u)))))
|
||||||
|
$slot.CloseFigure()
|
||||||
|
$g.FillPath($bgBrush, $slot)
|
||||||
$g.Dispose()
|
$g.Dispose()
|
||||||
$bmp.Save((Join-Path $out 'ic_launcher.png'), [System.Drawing.Imaging.ImageFormat]::Png)
|
$bmp.Save((Join-Path $out 'ic_launcher.png'), [System.Drawing.Imaging.ImageFormat]::Png)
|
||||||
$bmp.Dispose()
|
$bmp.Dispose()
|
||||||
|
|||||||