Dokumentation

Native Exporte

Ein einziger Befehl macht aus glyphfox-Icons echte Vektor-Assets für Android, Jetpack Compose, iOS, SwiftUI und Flutter. Strichstärke, Ecken, Duotone, Modifikatoren und Fusionen werden als einfache Pfade exportiert, und Striche bleiben Striche.

Überblick

Terminal
npx glyphfox export android home search file+check --out app/src/main/res
npx glyphfox export compose --from icons.txt --package com.acme.icons --out app/src/main/java
npx glyphfox export ios home search --out MyApp/Assets.xcassets
npx glyphfox export swiftui home search --out MyApp
npx glyphfox export flutter home search --out .
npx glyphfox export android --all --weight 1.5 --corners sharp --out app/src/main/res

Übergib Icon-Namen oder eine beliebige Spec der Namenssyntax, eine Listendatei mit --from (ein Name pro Zeile, # leitet einen Kommentar ein) oder --all für das ganze Set. Die Geometrie ist dieselbe, die die Web-Pakete zeichnen, daher sehen dieselben Specs überall gleich aus:

heart
bell/duotone
file+check
cloud&lock
user+plus@tl
ZielSchreibt unter --outVerwendung
androiddrawable/gf_NAME.xml@drawable/gf_home, R.drawable.gf_home
composePACKAGE/GlyphFox.kt und PACKAGE/NAME.ktIcon(GlyphFox.Home, null)
iosGlyphFox.xcassets/gf-NAME.imagesetUIImage(named: "gf-home")
swiftuiGlyphFox.swift und der KatalogImage(glyphfox: .home)
flutterassets/glyphfox/NAME.svg und lib/glyphfox.dartGlyphFoxIcon(GlyphFoxIcons.home)

Android

Ein VectorDrawable pro Icon in drawable/, richte --out also auf app/src/main/res. Striche behalten ihre Breite in Viewport-Einheiten, ihre runden oder eckigen Linienenden und Verbindungen und bekommen nie eine Füllung, sodass sie mit dem Drawable genau wie das SVG skalieren. Die Farbe ist ein Tint: standardmäßig ?attr/colorControlNormal, damit die Icons dem Theme folgen wie die Material-Icons.

res/drawable/gf_heart.xml
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportWidth="24"
    android:viewportHeight="24"
    android:tint="?attr/colorControlNormal">
    <path
        android:pathData="M12,19.89 L4.41,12.3 A4.8,4.8,0,1,1,12,6.58 A4.8,4.8,0,1,1,19.59,12.3 Z"
        android:strokeColor="@android:color/white"
        android:strokeWidth="2"
        android:strokeLineCap="round"
        android:strokeLineJoin="round" />
</vector>
layout.xml
<ImageView
    android:layout_width="24dp"
    android:layout_height="24dp"
    android:src="@drawable/gf_heart"
    android:contentDescription="@string/favorite" />

Übergib ein Theme-Attribut oder eine Farbressource als --color (?attr/colorPrimary, @color/brand), um damit einzufärben, oder eine Hex-Farbe (#ff7a1a), um die Farbe ohne Tint fest in die Pfade einzubrennen. Duotone-Ebenen sind gefüllte Pfade mit fillAlpha, --mirror-rtl setzt android:autoMirrored, und Drehung und Spiegelungen werden zu einer Gruppe um die Mitte.

Jetpack Compose

GlyphFox.kt deklariert das Objekt GlyphFox, und jedes Icon ist eine ImageVector-Extension-Property darauf, beim ersten Zugriff gebaut und zwischengespeichert, in einer eigenen Datei. Die Dateien landen im Paketordner unter --out, richte die Option also auf das Kotlin-Quellverzeichnis.

com/acme/icons/Heart.kt
package com.acme.icons

val GlyphFox.Heart: ImageVector
    get() {
        if (_heart != null) {
            return _heart!!
        }
        _heart = ImageVector.Builder(
            name = "GlyphFox.Heart",
            defaultWidth = 24.dp,
            defaultHeight = 24.dp,
            viewportWidth = 24f,
            viewportHeight = 24f,
        ).apply {
            path(
                stroke = SolidColor(Color.Black),
                strokeLineWidth = 2f,
                strokeLineCap = StrokeCap.Round,
                strokeLineJoin = StrokeJoin.Round,
            ) {
                moveTo(12f, 19.89f)
                lineTo(4.41f, 12.3f)
                arcTo(4.8f, 4.8f, 0f, true, true, 12f, 6.58f)
                arcTo(4.8f, 4.8f, 0f, true, true, 19.59f, 12.3f)
                close()
            }
        }.build()
        return _heart!!
    }

private var _heart: ImageVector? = null
Screen.kt
import com.acme.icons.GlyphFox
import com.acme.icons.Heart

Icon(GlyphFox.Heart, contentDescription = "Favorite")
Icon(GlyphFox.Heart, contentDescription = null, tint = MaterialTheme.colorScheme.primary)
Image(GlyphFox.Heart, contentDescription = null) // keeps the exported color

GlyphFox.all.forEach { (name, vector) -> Icon(vector, contentDescription = name) }

Jede Property wird wie bei den Material-Icons über ihren Namen importiert. GlyphFox.all ordnet jedem exportierten Namen seinen Vektor zu, für Picker und Vorschauen. Mit aktiviertem Code Shrinking entfernt R8 die Icons, die eine App nie verwendet, es sei denn, sie liest GlyphFox.all.

iOS-Asset-Katalog

Ein Image Set pro Icon mit dem SVG, Preserve Vector Data und Render As Template Image, sodass die Icons in jeder Größe scharf bleiben und die Tint-Farbe übernehmen. Richte --out auf einen vorhandenen Katalog wie MyApp/Assets.xcassets, um die Image Sets dort hinzuzufügen (seine eigene Contents.json bleibt erhalten), oder auf einen Ordner, um GlyphFox.xcassets zu erhalten.

gf-heart.imageset/Contents.json
{
  "images" : [
    {
      "filename" : "gf-heart.svg",
      "idiom" : "universal"
    }
  ],
  "info" : {
    "author" : "xcode",
    "version" : 1
  },
  "properties" : {
    "preserves-vector-representation" : true,
    "template-rendering-intent" : "template"
  }
}
ViewController.swift
let heart = UIImageView(image: UIImage(named: "gf-heart"))
heart.tintColor = .systemOrange

Die SVG-Dateien enthalten konkrete Farben (standardmäßig Schwarz), die das Template-Rendering durch den Tint ersetzt. Mit einer Hex-Farbe in --color wechselt der Katalog zum Original-Rendering, damit die Farbe sichtbar wird; --rendering template oder original legt es explizit fest, und --mirror-rtl markiert die Image Sets so, dass sie in Layouts von rechts nach links gespiegelt werden.

SwiftUI

glyphfox export swiftui schreibt denselben Asset-Katalog und dazu GlyphFox.swift: ein Enum mit einem Case pro Image Set, Image(glyphfox:) und UIImage.glyphfox(_:) für UIKit.

GlyphFox.swift
public enum GlyphFox: String, CaseIterable, Sendable {
    case heart = "gf-heart"
    case `repeat` = "gf-repeat"
}

public extension Image {
    init(glyphfox icon: GlyphFox, bundle: Bundle? = nil) {
        self = Image(icon.rawValue, bundle: bundle).renderingMode(.template)
    }
}
ContentView.swift
Label { Text("Favorites") } icon: { Image(glyphfox: .heart) }

Image(glyphfox: .heart)
    .resizable()
    .frame(width: 32, height: 32)
    .foregroundStyle(.orange)
    .accessibilityLabel("Favorite")

ForEach(GlyphFox.allCases, id: \.self) { Image(glyphfox: $0) }

Übergib bundle: .module, wenn der Katalog in einem Swift-Paket liegt.

Flutter

SVG-Dateien in assets/glyphfox/ und lib/glyphfox.dart mit einer Konstante pro Icon und einem kleinen GlyphFoxIcon-Widget auf Basis von flutter_svg. Richte --out auf den App-Ordner und füge dann das Paket und die Assets in pubspec.yaml hinzu:

pubspec.yaml
dependencies:
  flutter_svg: ^2.0.0

flutter:
  assets:
    - assets/glyphfox/
main.dart
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'glyphfox.dart';

Row(children: [
  const GlyphFoxIcon(GlyphFoxIcons.heart),
  GlyphFoxIcon(GlyphFoxIcons.heart, size: 32, color: Colors.orange, semanticLabel: 'Favorite'),
  SvgPicture.asset(GlyphFoxIcons.heart), // the exported colors, no tint
])

GlyphFoxIcon folgt wie Icon dem umgebenden IconTheme bei Größe und Farbe, färbt die ganze Zeichnung ein (die Duotone-Ebene behält ihre Deckkraft) und ist dekorativ, solange es kein semanticLabel bekommt. GlyphFoxIcons.values listet alle exportierten Pfade auf, und --assets verschiebt den SVG-Ordner.

Optionen

OptionZieleStandardBeschreibung
specsalleNamen oder Specs wie file+check@tr, cloud&lock:side oder heart/duotone.
--fromalleEine Listendatei: ein Name pro Zeile oder durch Kommas getrennt, # leitet einen Kommentar ein.
--allalleAlle Icons des Sets.
--outalle.Der Projektordner: res für android, das Kotlin-Quellverzeichnis für compose, ein Ordner oder ein .xcassets-Katalog für ios und swiftui, der App-Ordner für flutter.
--sizealle24Größe in dp, Punkten oder logischen Pixeln. Unter 24 wird der Strich optisch ausgeglichen, wie im Web.
--weightalle2Strichstärke von 1 bis 3 auf dem 24er-Raster.
--absolute-weightalleDer Strich bleibt bei der Exportgröße so breit wie die Strichstärke in Einheiten.
--cornersalleroundround oder sharp (eckige Linienenden und spitze Verbindungen).
--variantalleoutlineoutline oder duotone. Der gefüllte Stil schneidet Linien mit Masken aus, die VectorDrawable und ImageVector nicht zeichnen können, daher wird er abgelehnt.
--coloralleTintEine Hex-Farbe, fest in die Dateien eingebrannt. Android nimmt auch ein Theme-Attribut oder eine Farbressource an, die als Tint dient.
--secondary-color, --secondary-opacityalleFarbe, 0.3Farbe und Deckkraft der Duotone-Ebene.
--rotate, --flip-x, --flip-yalleEine Transformation um die Mitte des Rasters.
--mirror-rtlalleSpiegelt das Icon in Layouts von rechts nach links (autoMirrored, autoMirror, die Richtung des Image Sets).
--modifier, --modifier-corneralleDasselbe Badge auf jedem Icon, wie bei file+check.
--prefixandroid, ios, swiftuigf_, gf-Präfix der Drawable- oder Image-Set-Namen.
--packagecomposeglyphfoxKotlin-Paket, zugleich der Ordner unter --out.
--renderingios, swiftuitemplatetemplate oder original; original ist der Standard bei einer Hex-Farbe in --color.
--assetsflutterassets/glyphfoxOrdner der SVG-Dateien und der Pfade in den Konstanten.

Namen und Farben

Aus einer Spec wird auf jeder Plattform ein Name: file+check@tr ist gf_file_check_tr auf Android, GlyphFox.FileCheckTr für Compose, gf-file-check-tr im Katalog und fileCheckTr in Swift und Dart. Zwei Specs, die auf denselben Namen hinauslaufen, werden abgelehnt, und Schlüsselwörter werden maskiert (repeat wird in Swift zu `repeat`).

Ohne --color folgt jedes Ziel dem Tint der Plattform: colorControlNormal, LocalContentColor, dem Foreground Style von SwiftUI oder IconTheme. Mit einer Hex-Farbe wird die Farbe fest eingebrannt und bleibt: Android lässt den Tint weg, der Katalog rendert das Original und GlyphFoxIcon behält die exportierten Farben, solange es kein color bekommt. Icon() in Compose färbt immer ein, nutze also Image() oder tint = Color.Unspecified, um die eingebrannte Farbe zu sehen.