Flutter Design Series: Glas Morphismus

von Andreas Scheidmeir
Quick Tipp

Der Begriff Morphismus kommt aus der Mathematik und beschreibt (grob gesagt) die strukturerhaltende Überführung von mathematischen Konstrukten. Die Design-Welt hat sich diesen Begriff zu Eigen gemacht, um Designs zu beschreiben, die sich analog zu realen Konzepten verhalten.

Im Fall von Glas Morphismus (eng. Glassmorphism) sollen so die Eigenschaften von Glas, meist Milchglas, nachgestellt werden. Dafür kommen semitransparente Flächen zum Einsatz, die deren Hintergrund unscharf zeichnen und durch Schlagschatten Tiefe simulieren. Die Umsetzung in Flutter möchte ich in diesem Blogpost anhand eines einfachen Beispiels Schritt für Schritt aufzeigen.

Voraussetzung

Damit der Effekt wirkt, benötigt es einen kontrastreichen Hintergrund, am besten mit harten Kanten, die hinter dem Glas-Element verschwinden. Ohne diesen wirkt die Unschärfe nicht, welche für den Milchglaseffekt wichtig ist. Damit eigenen sich vor allem bunte und verspielte Hintergründe und man sollte vor der Umsetzung prüfen, ob ein evtl. vorhandener Styleguide dies zulässt.

Umsetzung

Im Folgenden breche ich die einzelnen Elemente des Effekts herunter und beschreibe deren Umsetzung in Flutter.

Schritt 1

In der einfachsten Form benötigen wir einen Container mit semitransparentem Hintergrund und Schlagschatten. Dies lässt sich einfach über die BoxDecoration am Flutter-Container umsetzen. Hier runden wir die Ecken ab und definieren die Hintergrundfarbe mit Transparenz sowie den Schlagschatten.

Container(
  decoration: BoxDecoration(
    borderRadius: BorderRadius.circular(20.0),
    color: Colors.white.withOpacity(0.3),
    boxShadow: [
      BoxShadow(
        color: Colors.black.withOpacity(0.15),
        blurRadius: 20,
        spreadRadius: 5,
        offset: const Offset(5, 5),
      )
    ],
  ),
  child: …
),

Schritt 2

In der Regel verläuft das Licht nicht gleichmäßig über eine Glasplatte. Um den Effekt von Sonnenlicht, das von links oben auf die UI fällt, zu simulieren, können wir die statische Hintergrundfarbe durch einen linearen Gradienten ersetzen. Dafür definieren wir im Beispiel statt der color einen LinearGradient, der von links oben nach rechts unten verläuft und über die Fläche hinweg transparenter wird. Wer will kann natürlich weitere Farb- oder Deckkraftvariationen einfügen und mittels der stops deren Verteilung steuern (0.0 beschreibt den Anfang, hier links oben, und 1.0 das Ende).

Container(
  decoration: BoxDecoration(
    borderRadius: ...
    boxShadow: ...
    gradient: LinearGradient(
      begin: Alignment.topLeft,
      end: Alignment.bottomRight,
      colors: [
        Colors.white.withOpacity(0.5),
        Colors.white.withOpacity(0.2),
      ],
      stops: const [
        0.0,
        1.0,
      ],
    ),
  ),
  child: …
),

Schritt 3

Der wichtigste Punkt ist, alles was hinter der simulierten Glasfläche liegt, weich zu zeichnen. Hierfür gibt es das BackdropFilter Widget, welches ImageFilter entgegen nimmt wie:

ImageFilter.blur(
  sigmaX: 20.0,
  sigmaY: 20.0,
),

Je größer die angegebenen Sigma-Werte sind, desto stärker wird der Hintergrund unscharf gezeichnet. Dies betriff zunächst alles, was nicht Kind-Element des BackdropFilters ist. Um es auf den Kasten zu beschränken, umschließen wir das ganze zusätzlich mit dem ClipRRect, was eine abgerundete, rechteckige Beschränkung um den Effekt legt.

Dies clippt aber auch den Schlagschatten, weswegen wir diesen über das ClipRRect -Widget in ein extra Container ziehen müssen:

Container(
  decoration: BoxDecoration(
    borderRadius: BorderRadius.circular(20.0),
    boxShadow: …
  ),
  child: ClipRRect(
    borderRadius: BorderRadius.circular(20.0),
    child: BackdropFilter(
      filter: ImageFilter.blur(
        sigmaX: 20.0,
        sigmaY: 20.0,
      ),
      child: Container(
        decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(20.0), 
          gradient: …
        ),
        child: …
        ),
      ),
    ),
  ),
),

Schritt 4

Eine reale Glasplatte hat eine gewisse Dicke und in ihren Rändern fängt sich das Licht. Dies können wir einfach mit einem dünnen weißen Rand simulieren, welchen wir an den inneren Container (an dem auch der Farbverlauf definiert ist) zeichnen.

Container(
  decoration: BoxDecoration(
    borderRadius: …
    gradient: …
    border: Border.all(
      color: Colors.white.withOpacity(0.2),
      width: 1.0,
    ),
  ),
  child:…
),

Schritt 5

Damit haben wir bereits einen recht überzeugenden Effekt. Um noch die unebene Oberfläche der Milchglasscheibe zu simulieren, überlagern wir ein Rausch-Bild mit geringer Deckkraft. Ein solches Bild kann einfach mittels Grafikprogrammen wie Photoshop oder über diverse Online-Generatoren (einfach nach noise image generator googeln) erstellt werden. Das Bild wird über DecorationImage eingebunden. Da es leider keine direkte Möglichkeit gibt, die Deckkraft zu steuern, nutzen wir einen colorFilter, welcher über den definierten BlendMode das selbe Ergebnis erzielt.

Container(
  decoration: BoxDecoration(
    borderRadius: …
    gradient: …
    border: …
    image: DecorationImage(
      image: Image.asset("images/noise.jpg").image,
      fit: BoxFit.fill,
      colorFilter: ColorFilter.mode(
        Colors.black.withOpacity(0.05),
        BlendMode.dstATop,
      ),
    ),
  ),
  child:…
),

Fazit

Da Flutter die volle Kontrolle über jeden gezeichneten Pixel bietet, ist die Umsetzung, wie beschrieben, einfach und schnell. Hat man einmal den grundlegenden Glas-Container definiert, kann man diesen beliebig wieder verwenden und überlagern.

Flutter kümmert sich dynamisch um die Zeichnung der Unschärfe, sodass auch animierte Hintergründe verwendet werden können, welche den Effekt noch einmal verstärken. An dieser Stelle aber nicht übertreiben, sonst lenkt der Hintergrund von der UI ab, auf der der Fokus liegen sollte.

Zurück

© 2006-2024 exensio GmbH
Einstellungen gespeichert
Datenschutzeinstellungen

Wir nutzen Cookies auf unserer Website. Einige von ihnen sind essenziell, während andere uns helfen, diese Website und Ihre Erfahrung zu verbessern.

Sie können Ihre Einwilligung jederzeit ändern oder widerrufen, indem Sie auf den Link in der Datenschutzerklärung klicken.

Zu den gesetzlichen Rechenschaftspflichten gehört die Einwilligung (Opt-In) zu protokollieren und archivieren. Aus diesem Grund wird Ihre Opt-In Entscheidung in eine LOG-Datei geschrieben. In dieser Datei werden folgende Daten gespeichert:

 

  • IP-Adresse des Besuchers
  • Vom Besucher gewählte Datenschutzeinstellung (Privacy Level)
  • Datum und Zeit des Speicherns
  • Domain
You are using an outdated browser. The website may not be displayed correctly. Close