Die Geschichte hinter TryShape, einer Präsentation der CSS clip-path Eigenschaft

Avatar of Tapas Adhikary
Tapas Adhikary am

DigitalOcean bietet Cloud-Produkte für jede Phase Ihrer Reise. Starten Sie mit 200 $ kostenlosem Guthaben!

Ich liebe Formen, besonders bunte! Formen auf Websites gehören in die gleiche Kategorie der Nützlichkeit wie Hintergrundfarben, Bilder, Banner, Trennlinien, Grafiken und vieles mehr: Sie können uns helfen, Kontext zu verstehen und unsere Handlungen durch Affordanzen zu informieren.

Vor ein paar Monaten habe ich eine Anwendung entwickelt, um meine 7-jährige Tochter mit Mathematik zu beschäftigen. Neben einfacher Addition und Subtraktion war es mein Ziel, Fragen mithilfe von Formen zu stellen. Damals wurde ich mit der CSS-Eigenschaft clip-path vertraut, eine zuverlässige Methode, um Formen im Web zu erstellen. Dann habe ich schließlich eine weitere App namens TryShape mit der Kraft von clip-path entwickelt.

Ich werde Sie durch die Geschichte hinter TryShape führen und wie es hilft, Formen zu erstellen, zu verwalten, zu teilen und zu exportieren. Dabei werden wir viel über CSS clip-path und wie es mir geholfen hat, die App schnell zu erstellen, behandeln.

Hier sind einige wichtige Links

Zuerst die CSS clip-path Eigenschaft und Formen

Stellen Sie sich vor, Sie haben ein einfaches Stück Papier und einen Bleistift, um eine Form (sagen wir, ein Quadrat) darauf zu zeichnen. Wie würden Sie vorgehen? Höchstwahrscheinlich würden Sie von einem Punkt ausgehen, dann eine Linie zeichnen, um einen anderen Punkt zu erreichen, dann dies genau dreimal wiederholen, um zum Anfangspunkt zurückzukehren. Sie müssten auch sicherstellen, dass die gegenüberliegenden Linien parallel und von der gleichen Länge sind.

Die wesentlichen Bestandteile einer Form sind also Punkte, Linien, Richtungen, Kurven, Winkel und Längen, unter vielen anderen. Die CSS clip-path hilft, viele dieser Eigenschaften zu definieren, um einen Bereich eines HTML-Elements zu beschneiden und einen bestimmten Bereich anzuzeigen. Der Teil, der sich innerhalb des beschnittenen Bereichs befindet, wird angezeigt, und der Rest wird verborgen. Sie eröffnet Entwicklern eine Fülle von Möglichkeiten, verschiedene Formen mit der clip-path-Eigenschaft zu erstellen.

Mehr über Clipping und wie es sich von Masking unterscheidet.

Die clip-path Werte für die Formenerstellung

Die clip-path Eigenschaft akzeptiert die folgenden Werte zur Erstellung von Formen

  • circle()
  • ellipse()
  • inset()
  • polygon()
  • Eine Clip-Quelle mit der Funktion url()
  • path()

Um diese Werte verwenden zu können, müssen wir das grundlegende Koordinatensystem verstehen. Wenn wir die clip-path Eigenschaft auf ein Element anwenden, um Formen zu erstellen, müssen wir die x-Achse, die y-Achse und die Anfangskoordinaten (0,0) an der oberen linken Ecke des Elements berücksichtigen.

Hier ist ein div-Element mit seiner x-Achse, y-Achse und den Anfangskoordinaten (0,0).

A blue square with its starting point located at a zero zero position on a chart with x and y axes.
Anfangskoordinaten(0,0) mit x-Achse und y-Achse

Nun verwenden wir den Wert circle(), um eine kreisförmige Form zu erstellen. Mit diesem Wert können wir die Position und den Radius des Kreises festlegen. Um beispielsweise eine kreisförmige Form an der Koordinatenposition (70, 70) mit einem Radius von 70 Pixeln zu beschneiden, können wir den Wert der clip-path Eigenschaft wie folgt angeben:

clip-path: circle(70px at 70px 70px)

Der Mittelpunkt des Kreises liegt also bei der Koordinate (70, 70) mit einem Radius von 70 Pixeln. Nun wird nur dieser kreisförmige Bereich auf dem Element ausgeschnitten und angezeigt. Der Rest des Elements wird verborgen, um den Eindruck einer Kreisform zu erwecken.

A blue circle on a grid with an x and y axis. The circle starts at the zero zero position and its center is located at 70 px and 70px. A zoomed in area shows the clipping path, which is also located at 70x and 70px.
Der Mittelpunkt des Kreises liegt bei den Koordinaten (70, 70) mit einem ausgeschnittenen Bereich von 70x70 Pixeln. Daher wird der volle Kreis angezeigt.

Als Nächstes: Was passiert, wenn wir die Position bei (0,0) angeben wollen? In diesem Fall liegt der Mittelpunkt des Kreises bei der Position (0,0) mit einem Radius von 70 Pixeln. Dadurch ist nur ein Teil des Kreises innerhalb des Elements sichtbar.

The center of a blue circle is placed at the 0,0 coordinates with a 70px by 70px area clipping the bottom-left region of the circle.
Der Mittelpunkt des Kreises liegt bei den Koordinaten (0, 0) mit einem Bereich von 70x70 Pixeln, der den unteren linken Bereich des Kreises beschneidet.

Kommen wir nun zu den anderen beiden wichtigen Werten, inset() und polygon(). Wir verwenden einen Einzug (inset), um eine rechteckige Form zu definieren. Wir können den Abstand festlegen, den jede der vier Kanten haben kann, um einen Bereich aus einem Element auszuschneiden. Zum Beispiel:

clip-path: inset(30px)

Der obige clip-path-Wert schneidet einen Bereich aus, indem er die 30 Pixel von den Rändern des Elements auslässt. Das sehen Sie im folgenden Bild. Wir können auch einen unterschiedlichen Einzugswert für jede Kante angeben.

Die inset() Funktion ermöglicht es uns, einen Bereich vom äußeren Rand einer Form auszuschneiden.

Als Nächstes kommt der Wert polygon(). Wir können eine polygonale Form mit einer Reihe von Eckpunkten erstellen. Nehmen Sie dieses Beispiel:

clip-path: polygon(10% 10%, 90% 10%, 90% 90%, 10% 80%)

Hier geben wir eine Reihe von Eckpunkten an, um einen Bereich für den Zuschnitt zu erstellen. Das folgende Bild zeigt die Position jedes Eckpunkts, um eine polygonale Form zu erstellen. Wir können beliebig viele Eckpunkte angeben.

A square with four points inside of it located at 10% by 10%, 90% by 10%, 10% by 80% and 90% by 90%, creating the clipped area.
Die Polygon()-Funktion ermöglicht es uns, polygonale Formen mithilfe der an sie übergebenen Eckpunkte zu erstellen.

Als Nächstes betrachten wir die Werte ellipse() und url(). Der Wert ellipse() hilft, Formen durch Angabe von zwei Radienwerten und einer Position zu erstellen. Im folgenden Bild sehen wir eine Ellipse an der Position, an der der Radius (50%,50%) beträgt und die Form 70 Pixel breit und 100 Pixel hoch ist.

A blue blue against a light blue background. The ellipse is 70 pixels wide and 100 pixels tall and it's radius is centered at 50% 50%.
Wir müssen zwei Radienwerte und eine Position angeben, um eine Ellipse zu erstellen.

url() ist eine CSS-Funktion, um den ID-Wert des clip-path-Elements zur Darstellung einer SVG-Form anzugeben. Bitte schauen Sie sich das folgende Bild an. Wir haben eine SVG-Form mit den Elementen clipPath und path definiert. Sie können den ID-Wert des clipPath-Elements als Argument für die url()-Funktion verwenden, um diese Form darzustellen.

Showing the SVG code for a heart-shaped path and the actual heart next to it in blue.
Hier erstellen wir mit der url() Funktion eine Herzform

Zusätzlich können wir die Pfadwerte direkt in der path() Funktion verwenden, um die Form zu zeichnen.

Showing a line of CSS code for the clip-path property filled in with the code of an SVG path inside the path function. The result is below the code, a parabolic curve that's filled in blue.
Hier erstellen wir mit der path()-Funktion eine geschwungene Form.

In Ordnung. Ich hoffe, Sie haben ein Verständnis für die verschiedenen Werte der clip-path Eigenschaft gewonnen. Mit diesem Verständnis lassen Sie uns einige Implementierungen betrachten und damit experimentieren. Hier ist ein Pen für Sie. Bitte verwenden Sie ihn, um Werte hinzuzufügen und zu ändern, um eine neue Form zu erstellen.

Lassen Sie uns über TryShape sprechen

Es ist Zeit, über TryShape und seine Hintergrundgeschichte zu sprechen. TryShape ist eine Open-Source-Anwendung, die Ihnen hilft, Formen Ihrer Wahl zu erstellen, zu exportieren, zu teilen und zu verwenden. Sie können Banner, Kreise, Kunstwerke, Polygone erstellen und sie als SVG-, PNG- und JPEG-Dateien exportieren. Sie können auch ein CSS-Code-Snippet erstellen, das Sie kopieren und in Ihrer Anwendung verwenden können.

TryShape wurde mit dem folgenden Framework und den folgenden Bibliotheken (und natürlich clip-path) erstellt:

  • CSS clip-path: Wir haben bereits die Kraft dieser großartigen CSS-Eigenschaft besprochen.
  • Next.js: Das coolste React-basierte Framework. Es hat mir geholfen, Seiten, Komponenten, Interaktionen und APIs für die Verbindung zur Backend-Datenbank zu erstellen.
  • HarperDB: Eine flexible Datenbank zum Speichern von Daten und Abfragen mit SQL- und No-SQL-Interaktionen. TryShape hat sein Schema und seine Tabellen in der HarperDB-Cloud erstellt. Die Next.js-APIs interagieren mit dem Schema und den Tabellen, um die erforderlichen CRUD-Operationen von der Benutzeroberfläche aus durchzuführen.
  • Firebase: Authentifizierungsdienste von Google. TryShape verwendet es, um die Social-Login-Funktion mit Google, GitHub, Twitter und anderen Konten zu ermöglichen.
  • react-icons: Ein zentraler Anlaufpunkt für alle Icons für eine React-basierte Anwendung
  • date-fns: Die moderne, leichtgewichtige Bibliothek für Datumsformatierung
  • axios: Erleichtert API-Aufrufe von React-Komponenten
  • styled-components: Eine strukturierte Methode zum Erstellen von CSS-Regeln aus React-Komponenten
  • react-clip-path: Ein selbst entwickeltes Modul zur Handhabung der clip-path Eigenschaft in einer React-App
  • react-draggable: Macht ein HTML-Element in einer React-App ziehbar. TryShape verwendet es, um die Position von Formeckpunkten anzupassen.
  • downloadjs: Löst einen Download aus JavaScript aus
  • html-to-image: Konvertiert ein HTML-Element in ein Bild (einschließlich SVG, JPEG und PNG)
  • Vercel: Am besten zum Hosten einer Next.js-App

Erstellung von Formen in TryShape mit CSS clip-path

Lassen Sie mich den Quellcode hervorheben, der zur Erstellung einer Form mit der CSS clip-path Eigenschaft verwendet wird. Der folgende Codeausschnitt definiert die Benutzeroberflächenstruktur für ein Container-Element (Box), das 300 Pixel im Quadrat ist. Das Box-Element hat zwei Kindelemente, Shadow und Component.

<Box 
  height="300px" 
  width="300px" 
  onClick={(e) => props.handleChange(e)}>
  { 
    props.shapeInformation.showShadow && 
    <Shadow 
      backgroundColor={props.shapeInformation.backgroundColor} 
      id="shapeShadow" /> 
  }
  <Component 
    formula={props.shapeInformation.formula} 
    backgroundColor={props.shapeInformation.backgroundColor} 
    id="clippedShape" />
</Box>

Die Shadow-Komponente definiert den Bereich, der durch den clip-path-Zuschnitt verborgen wird. Wir erstellen sie, um einen hellfarbigen Hintergrund zu zeigen, der diesen Bereich für den Endbenutzer teilweise sichtbar macht. Die Component dient zur Zuweisung des clip-path-Werts, um den ausgeschnittenen Bereich anzuzeigen.

Sehen Sie sich die styled-component-Definitionen von Box, Shadow und Component unten an

// The styled-components code to create the UI components using CSS properties

// The container div
const Box = styled.div`
  width: ${props => props.width || '100px'};
  height: ${props => props.height || '100px'};
  margin: 0 auto;
  position: relative;
`;

// Shadow defines the area that is hidden by the `clip-path` clipping
// We show a light color background to make this area partially visible.
const Shadow = styled.div`
  background-color: ${props => props.backgroundColor || '#00c4ff'};
  opacity: 0.25;
  position: absolute;
  top: 10px;
  left: 10px;
  right: 10px;
  bottom: 10px;
`;

// The actual component that takes the `clip-path` value (formula) and set
// to the `clip-path` property.
const Component = styled.div`
  clip-path: ${props => props.formula}; // the formula is the clip-path value
  background-color: ${props => props.backgroundColor || '#00c4ff'};
  position: absolute;
  top: 10px;
  left: 10px;
  right: 10px;
  bottom: 10px;
`;
An illustration of a blue box with its inset clip points drawing another square that indicates the visible area of the shape in a darker blue.
Die Komponenten zur Anzeige einer Form (sowohl sichtbare als auch verborgene Bereiche) nach dem Zuschnitt.

Schauen Sie sich gerne den gesamten Codebestand im GitHub-Repo an.

Zukünftige Entwicklungsmöglichkeiten von TryShape

TryShape funktioniert gut bei der Erstellung und Verwaltung grundlegender Formen mit CSS clip-path im Hintergrund. Es ist hilfreich, die Formen und CSS-Code-Snippets zu exportieren, um sie in Ihren Webanwendungen zu verwenden. Es hat das Potenzial, mit vielen weiteren wertvollen Funktionen zu wachsen. Die wichtigste wird die Möglichkeit sein, Formen mit geschwungenen Kanten zu erstellen.

Zur Unterstützung von geschwungenen Formen benötigen wir die Unterstützung der folgenden Werte in TryShape:

  • eine Clip-Quelle mit url() und
  • path().

Mit diesen Werten können wir Formen mit SVG erstellen und dann einen der oben genannten Werte verwenden. Hier ist ein Beispiel für die CSS-Funktion url() zur Erstellung einer Form mit SVG-Unterstützung.

<div class="heart">Heart</div>
<svg>
  <clipPath id="heart-path" clipPathUnits="objectBoundingBox">
    <path d="M0.5,1
      C 0.5,1,0,0.7,0,0.3
      A 0.25,0.25,1,1,1,0.5,0.3
      A 0.25,0.25,1,1,1,1,0.3
      C 1,0.7,0.5,1,0.5,1 Z" />
  </clipPath>
</svg>

Dann das CSS:

.heart {
  clip-path: url(#heart-path);
}
It produces a heart shape like this.

Lassen Sie uns nun eine Form mit dem Wert path() erstellen. Das HTML sollte ein Element wie ein Div enthalten:

<div class="curve">Curve</div>

In CSS

.curve {
  clip-path: path("M 10 80 C 40 10, 65 10, 95 80 S 150 150, 180 80");
}

Bevor wir enden…

Ich hoffe, Sie haben meine TryShape-App kennengelernt und etwas über die Idee erfahren, die dazu geführt hat, die von mir berücksichtigten Strategien, die zugrunde liegende Technologie und ihr zukünftiges Potenzial. Bitte erwägen Sie, sie auszuprobieren und den Quellcode anzusehen. Und natürlich können Sie gerne mit Issues, Feature-Anfragen und Code dazu beitragen.

Bevor wir enden, möchte ich Ihnen dieses kurze Video hinterlassen, das für den Hashnode Hackathon vorbereitet wurde, bei dem TryShape teilnahm und schließlich in der Gewinnerliste landete. Ich hoffe, es gefällt Ihnen.

Lassen Sie uns in Kontakt treten. Sie können mich auf Twitter (@tapasadhikary) mit Kommentaren @en oder mich gerne verfolgen.