Egal, ob Sie gerade erst mit Front-End anfangen oder schon lange dabei sind, der Bau eines Tools, das coole Front-End-Magie generieren kann, kann Ihnen helfen, etwas Neues zu lernen, Ihre Fähigkeiten zu entwickeln und vielleicht sogar ein wenig Bekanntheit zu erlangen.
Sie sind vielleicht schon auf einige dieser beliebten Online-Generatoren gestoßen
- Der Helden-Generator und CSS Grid Generator von Sarah Drasner
- Glassmorphism CSS Generator von Themesburg
- Textschatten von Components AI (und sie haben noch viele mehr)
Ich hatte Spaß daran, im Laufe der Jahre ein paar davon selbst zu bauen. Grundsätzlich kann jedes Mal, wenn Sie auf etwas Cooles im Front-End stoßen, eine Gelegenheit bestehen, einen interaktiven Generator für diese Sache zu erstellen.
In diesem Fall werden wir einen Generator für animierte Gradient-Hintergründe erstellen.
Das Projekt in Next aufsetzen
Eine schöne Sache an diesen Projekten ist, dass sie ganz Ihnen gehören. Wählen Sie jeden beliebigen Stack und legen Sie los. Ich bin ein großer Fan von Next.js, daher werde ich für dieses Projekt als grundlegendes Create Next App-Projekt beginnen.
npx create-next-app animated-gradient-background-generator
Dies generiert alle Dateien, die wir zum Start benötigen. Wir können pages/index.js als Shell für unser Projekt bearbeiten.
import Head from "next/head"
import Image from "next/image"
export default function Home() {
return (
<>
<Head>
<title>Animated CSS Gradient Background Generator</title>
<meta name="description" content="A tool for creating animated background gradients in pure CSS." />
<link rel="icon" href="/favicon.ico" />
</Head>
<main>
<h1>
Animated CSS Gradient Background Generator
</h1>
</main>
</>
)
}
Animierte Verläufe?
Zum Zeitpunkt der Erstellung dieses Artikels, wenn Sie nach animierten CSS-Gradient-Hintergründen suchen, ist das erste Ergebnis dieser Pen von Manuel Pinto.
Werfen wir einen Blick auf das CSS
body {
background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);
background-size: 400% 400%;
animation: gradient 15s ease infinite;
}
@keyframes gradient {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}
Dies ist ein großartiges Beispiel, das wir als Grundlage für die generierte Animation verwenden können.
Eine React-Komponente zur Beschreibung eines animierten Verlaufs
Wir können ein paar mögliche konfigurierbare Optionen für den Generator herausgreifen
- Ein Array von Verlauffarben
- Der Winkel des Verlaufs
- Die Geschwindigkeit der Animation
Um es in den *Kontext* zu stellen, möchten wir diese Einstellungen mit einer Higher-Order-Komponente, context/SettingsContext.js, zusammen mit einigen Standardwerten als Daten in unserer kleinen App *bereitstellen*.
import React, { useState, createContext } from "react"
const SettingsContext = createContext({ colorSelection: [] })
const SettingsProvider = ({ children }) => {
const [colorSelection, setColorSelection] = useState([
"deepskyblue",
"darkviolet",
"blue",
])
const [angle, setAngle] = useState(300)
const [speed, setSpeed] = useState(5)
return (
<SettingsContext.Provider
value={{
colorSelection,
setColorSelection,
angle,
setAngle,
speed,
setSpeed,
}}
>
{children}
</SettingsContext.Provider>
)
}
export { SettingsContext, SettingsProvider }
Für die Komponenten unseres Generators möchten wir erstellen
- eine Steuerkomponente zur Anpassung dieser Einstellungen,
- eine visuelle Anzeigekomponente für den generierten animierten Verlauf und
- eine Komponente für die CSS-Codeausgabe.
Beginnen wir mit einer Controls-Komponente, die die verschiedenen Eingaben zur Anpassung der Einstellungen enthält.
import Colors from "./Colors"
const Controls = (props) => (
<>
<Colors />
</>
)
export default Controls
Wir können unsere SettingsProvider und Controls-Komponenten zu pages/index.js hinzufügen
import Head from "next/head"
import Image from "next/image"
import { SettingsProvider } from "../context/SettingsContext"
import Controls from "../components/Controls"
import Output from "../components/Output"
export default function Home() {
return (
<>
<Head>
...
</Head>
<SettingsProvider>
<main style={{ textAlign: "center", padding: "64px" }}>
<h1>Animated CSS Gradient Background Generator</h1>
<Controls />
<Output />
</main>
</SettingsProvider>
</>
)
}
Unser SettingsProvider beginnt mit den drei Farben aus unserem CodePen-Beispiel als Standardwerten. Wir können überprüfen, ob wir die Farneinstellungen über unseren SettingsContext in einer neuen Colors-Komponente erhalten.
import React, { useContext } from "react"
import { SettingsContext } from "../context/SettingsContext"
const Colors = () => {
const { colorSelection } = useContext(SettingsContext)
return (
<>
{colorSelection.map((color) => (
<div>{color}</div>
))}
</>
)
}
export default Colors
Wir werden die Colors-Komponente verwenden, um einzelne Farbfelder mit einer kleinen Schaltfläche zum Löschen über unseren SettingsContext anzuzeigen.
import React, { useContext } from "react"
import { SettingsContext } from "../context/SettingsContext"
const Colors = () => {
const { colorSelection, setColorSelection } = useContext(SettingsContext)
const onDelete = (deleteColor) => {
setColorSelection(colorSelection.filter((color) => color !== deleteColor))
}
return (
<div>
{colorSelection.map((color) => (
<div
key={color}
style={{
background: color,
display: "inline-block",
padding: "32px",
margin: "16px",
position: "relative",
borderRadius: "4px",
}}
>
<button
onClick={() => onDelete(color)}
style={{
background: "crimson",
color: "white",
display: "inline-block",
borderRadius: "50%",
position: "absolute",
top: "-8px",
right: "-8px",
border: "none",
fontSize: "18px",
lineHeight: 1,
width: "24px",
height: "24px",
cursor: "pointer",
boxShadow: "0 0 1px #000",
}}
>
×
</button>
</div>
))}
</div>
)
}
export default Colors
Sie werden vielleicht bemerken, dass wir zu diesem Zeitpunkt Inline-Stile für CSS verwendet haben. Wen kümmert's! Wir haben hier Spaß, also können wir tun, was immer uns gefällt.
Farben verwalten
Als Nächstes erstellen wir eine AddColor-Komponente mit einer Schaltfläche, die einen Farbwähler öffnet, der zum Hinzufügen weiterer Farben zum Verlauf verwendet wird.
Für den Farbwähler installieren wir react-color und verwenden die Option ChromePicker.
npm install react-color
Auch hier werden wir SettingsContext verwenden, um die Auswahl der Verlauffarben zu aktualisieren.
import React, { useState, useContext } from "react"
import { ChromePicker } from "react-color"
import { SettingsContext } from "../context/SettingsContext"
const AddColor = () => {
const [color, setColor] = useState("white")
const { colorSelection, setColorSelection } = useContext(SettingsContext)
return (
<>
<div style={{ display: "inline-block", paddingBottom: "32px" }}>
<ChromePicker
header="Pick Colors"
color={color}
onChange={(newColor) => {
setColor(newColor.hex)
}}
/>
</div>
<div>
<button
onClick={() => {
setColorSelection([...colorSelection, color])
}}
style={{
background: "royalblue",
color: "white",
padding: "12px 16px",
borderRadius: "8px",
border: "none",
fontSize: "16px",
cursor: "pointer",
lineHeight: 1,
}}
>
+ Add Color
</button>
</div>
</>
)
}
export default AddColor
Winkel und Geschwindigkeit verwalten
Nachdem unsere Farbsteuerungen fertig sind, fügen wir nun Komponenten mit Bereichseingaben hinzu, um den Winkel und die Animationsgeschwindigkeit einzustellen.
Hier ist der Code für AngleRange, wobei SpeedRange sehr ähnlich ist.
import React, { useContext } from "react"
import { SettingsContext } from "../context/SettingsContext"
const AngleRange = () => {
const { angle, setAngle } = useContext(SettingsContext)
return (
<div style={{ padding: "32px 0", fontSize: "18px" }}>
<label
style={{
display: "inline-block",
fontWeight: "bold",
width: "100px",
textAlign: "right",
}}
htmlFor="angle"
>
Angle
</label>
<input
type="range"
id="angle"
name="angle"
min="-180"
max="180"
value={angle}
onChange={(e) => {
setAngle(e.target.value)
}}
style={{
margin: "0 16px",
width: "180px",
position: "relative",
top: "2px",
}}
/>
<span
style={{
fontSize: "14px",
padding: "0 8px",
position: "relative",
top: "-2px",
width: "120px",
display: "inline-block",
}}
>
{angle} degrees
</span>
</div>
)
}
export default AngleRange
Nun zum spaßigen Teil: **Das Rendern des animierten Hintergrunds**. Wenden wir dies auf den gesamten Hintergrund der Seite mit einer AnimatedBackground-Wrapperkomponente an.
import React, { useContext } from "react"
import { SettingsContext } from "../context/SettingsContext"
const AnimatedBackground = ({ children }) => {
const { colorSelection, speed, angle } = useContext(SettingsContext)
const background =
"linear-gradient(" + angle + "deg, " + colorSelection.toString() + ")"
const backgroundSize =
colorSelection.length * 60 + "%" + " " + colorSelection.length * 60 + "%"
const animation =
"gradient-animation " +
colorSelection.length * Math.abs(speed - 11) +
"s ease infinite"
return (
<div style={{ background, "background-size": backgroundSize, animation, color: "white" }}>
{children}
</div>
)
}
export default AnimatedBackground
Wir nennen die CSS-Animation für den Verlauf gradient-animation. Wir müssen diese zu styles/globals.css hinzufügen, um die Animation auszulösen
@keyframes gradient-animation {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}
Nützlich für Benutzer machen
Als Nächstes fügen wir eine Codeausgabe hinzu, damit die Leute den generierten CSS-Code kopieren und einfügen und in ihren eigenen Projekten verwenden können.
import React, { useContext, useState } from "react"
import { SettingsContext } from "../context/SettingsContext"
const Output = () => {
const [copied, setCopied] = useState(false)
const { colorSelection, speed, angle } = useContext(SettingsContext)
const background =
"linear-gradient(" + angle + "deg," + colorSelection.toString() + ")"
const backgroundSize =
colorSelection.length * 60 + "%" + " " + colorSelection.length * 60 + "%"
const animation =
"gradient-animation " +
colorSelection.length * Math.abs(speed - 11) +
"s ease infinite"
const code = `.gradient-background {
background: ${background};
background-size: ${backgroundSize};
animation: ${animation};
}
@keyframes gradient-animation {
0% {
background-position: 0% 50%;
}
50% {
background-position: 100% 50%;
}
100% {
background-position: 0% 50%;
}
}`
return (
<div
style={{ position: "relative", maxWidth: "640px", margin: "64px auto" }}
>
<pre
style={{
background: "#fff",
color: "#222",
padding: "32px",
width: "100%",
borderRadius: "4px",
textAlign: "left",
whiteSpace: "pre",
boxShadow: "0 2px 8px rgba(0,0,0,.33)",
overflowX: "scroll",
}}
>
<code>{code}</code>
<button
style={{
position: "absolute",
top: "8px",
right: "8px",
background: "royalblue",
color: "white",
padding: "8px 12px",
borderRadius: "8px",
border: "none",
fontSize: "16px",
cursor: "pointer",
lineHeight: 1,
}}
onClick={() => {
setCopied(true)
navigator.clipboard.writeText(code)
}}
>
{copied ? "copied" : "copy"}
</button>
</pre>
</div>
)
}
export default Output
Spaß machen
Es macht manchmal Spaß (und ist nützlich), eine Schaltfläche hinzuzufügen, die zufällige Werte auf einem Generator wie diesem einstellt. Das gibt den Leuten eine Möglichkeit, schnell zu experimentieren und zu sehen, welche Ergebnisse sie mit dem Tool erzielen können. Es ist auch eine Gelegenheit, coole Dinge nachzuschlagen, wie z. B. wie man zufällige Hex-Farben generiert.
import React, { useContext } from "react"
import { SettingsContext } from "../context/SettingsContext"
const Random = () => {
const { setColorSelection, setAngle, setSpeed } = useContext(SettingsContext)
const goRandom = () => {
const numColors = 3 + Math.round(Math.random() * 3)
const colors = [...Array(numColors)].map(() => {
return "#" + Math.floor(Math.random() * 16777215).toString(16)
})
setColorSelection(colors)
setAngle(Math.floor(Math.random() * 361))
setSpeed(Math.floor(Math.random() * 10) + 1)
}
return (
<div style={{ padding: "48px 0 16px" }}>
<button
onClick={goRandom}
style={{
fontSize: "24px",
fontWeight: 200,
background: "rgba(255,255,255,.9)",
color: "blue",
padding: "24px 48px",
borderRadius: "8px",
cursor: "pointer",
boxShadow: "0 0 4px #000",
border: "none",
}}
>
RANDOM
</button>
</div>
)
}
export default Random
Zusammenfassung
Es gibt ein paar abschließende Dinge, die Sie tun möchten, um Ihr Projekt für die Erstveröffentlichung abzuschließen
- Aktualisieren Sie
package.jsonmit Ihren Projektinformationen. - Fügen Sie einige Links zu Ihrer persönlichen Website, dem Repository des Projekts hinzu und geben Sie die gebührende Anerkennung.
- Aktualisieren Sie die Datei
README.md, die von Create Next App mit Standardinhalten generiert wurde.
Das ist es! Wir sind bereit, unseren neuen coolen Front-End-Generator zu veröffentlichen und die Belohnungen für Ruhm und Vermögen zu ernten, die uns erwarten!
Sie können den Code für dieses Projekt auf GitHub sehen und die Demo ist auf Netlify gehostet.