├── .eslintrc
├── .gitignore
├── .prettierignore
├── .prettierrc
├── README.md
├── components
├── AddColor.js
├── AngleRange.js
├── AnimatedBackground.js
├── Colors.js
├── Controls.js
├── Output.js
├── Random.js
└── SpeedRange.js
├── context
└── SettingsContext.js
├── next.config.js
├── package-lock.json
├── package.json
├── pages
├── _app.js
├── api
│ └── hello.js
└── index.js
├── public
├── favicon.ico
└── vercel.svg
└── styles
├── .prettierignore
├── .prettierrc
└── globals.css
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": ["next", "next/core-web-vitals"]
3 | }
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # next.js
12 | /.next/
13 | /out/
14 |
15 | # production
16 | /build
17 |
18 | # misc
19 | .DS_Store
20 | *.pem
21 |
22 | # debug
23 | npm-debug.log*
24 | yarn-debug.log*
25 | yarn-error.log*
26 |
27 | # local env files
28 | .env.local
29 | .env.development.local
30 | .env.test.local
31 | .env.production.local
32 |
33 | # vercel
34 | .vercel
35 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | .cache
2 | .next
3 | package.json
4 | package-lock.json
5 | public
6 | api/socks.js
7 | node-modules
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "endOfLine": "lf",
3 | "semi": false,
4 | "singleQuote": false,
5 | "tabWidth": 2,
6 | "trailingComma": "es5"
7 | }
8 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Animated Gradient Background Generator
2 |
3 | Created by Chicago web developer [John Polacek](https://johnpolacek.com, based on a [Pen](https://codepen.io/P1N2O/pen/pyBNzX) by Manuel Pinto.
4 |
5 | #### See the demo at [animated-gradient-background-generator.netlify.app/](https://animated-gradient-background-generator.netlify.app/)
6 |
7 | --
8 |
9 | This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
10 |
11 | ## Getting Started
12 |
13 | First, run the development server:
14 |
15 | ```bash
16 | npm run dev
17 | # or
18 | yarn dev
19 | ```
20 |
21 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
22 |
--------------------------------------------------------------------------------
/components/AddColor.js:
--------------------------------------------------------------------------------
1 | import React, { useState, useContext } from "react"
2 | import { ChromePicker } from "react-color"
3 | import { SettingsContext } from "../context/SettingsContext"
4 |
5 | const AddColor = () => {
6 | const [color, setColor] = useState("white")
7 | const { colorSelection, setColorSelection } = useContext(SettingsContext)
8 |
9 | return (
10 | <>
11 |
12 | {
16 | setColor(newColor.hex)
17 | }}
18 | />
19 |
20 |
21 |
38 |
39 | >
40 | )
41 | }
42 |
43 | export default AddColor
44 |
--------------------------------------------------------------------------------
/components/AngleRange.js:
--------------------------------------------------------------------------------
1 | import React, { useContext } from "react"
2 | import { SettingsContext } from "../context/SettingsContext"
3 |
4 | const AngleRange = () => {
5 | const { angle, setAngle } = useContext(SettingsContext)
6 |
7 | return (
8 |
9 |
20 | {
28 | setAngle(e.target.value)
29 | }}
30 | style={{
31 | margin: "0 16px",
32 | width: "180px",
33 | position: "relative",
34 | top: "2px",
35 | }}
36 | />
37 |
47 | {angle} degrees
48 |
49 |
50 | )
51 | }
52 |
53 | export default AngleRange
54 |
--------------------------------------------------------------------------------
/components/AnimatedBackground.js:
--------------------------------------------------------------------------------
1 | import React, { useContext } from "react"
2 | import { SettingsContext } from "../context/SettingsContext"
3 |
4 | const AnimatedBackground = ({ children }) => {
5 | const { colorSelection, speed, angle } = useContext(SettingsContext)
6 |
7 | const background =
8 | "linear-gradient(" + angle + "deg, " + colorSelection.toString() + ")"
9 |
10 | const backgroundSize =
11 | colorSelection.length * 60 + "%" + " " + colorSelection.length * 60 + "%"
12 |
13 | const animation =
14 | "gradient-animation " +
15 | colorSelection.length * (Math.abs(speed - 11) / 2) +
16 | "s ease infinite"
17 |
18 | return (
19 |
27 | {children}
28 |
29 | )
30 | }
31 |
32 | export default AnimatedBackground
33 |
--------------------------------------------------------------------------------
/components/Colors.js:
--------------------------------------------------------------------------------
1 | import React, { useContext } from "react"
2 | import { SettingsContext } from "../context/SettingsContext"
3 |
4 | const Colors = () => {
5 | const { colorSelection, setColorSelection } = useContext(SettingsContext)
6 |
7 | const onDelete = (deleteColor) => {
8 | setColorSelection(colorSelection.filter((color) => color !== deleteColor))
9 | }
10 |
11 | return (
12 |
13 | {colorSelection.map((color) => (
14 |
26 |
47 |
48 | ))}
49 |
50 | )
51 | }
52 |
53 | export default Colors
54 |
--------------------------------------------------------------------------------
/components/Controls.js:
--------------------------------------------------------------------------------
1 | import Colors from "./Colors"
2 | import AddColor from "./AddColor"
3 | import AngleRange from "./AngleRange"
4 | import SpeedRange from "./SpeedRange"
5 | import Random from "./Random"
6 |
7 | const Controls = () => (
8 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | )
24 |
25 | export default Controls
26 |
--------------------------------------------------------------------------------
/components/Output.js:
--------------------------------------------------------------------------------
1 | import React, { useContext, useState } from "react"
2 | import { SettingsContext } from "../context/SettingsContext"
3 |
4 | const Output = () => {
5 | const [copied, setCopied] = useState(false)
6 |
7 | const { colorSelection, speed, angle } = useContext(SettingsContext)
8 |
9 | const background =
10 | "linear-gradient(" + angle + "deg," + colorSelection.toString() + ")"
11 |
12 | const backgroundSize =
13 | colorSelection.length * 60 + "%" + " " + colorSelection.length * 60 + "%"
14 |
15 | const animation =
16 | "gradient-animation " +
17 | colorSelection.length * Math.abs(speed - 11) +
18 | "s ease infinite"
19 |
20 | const code = `.gradient-background {
21 | background: ${background};
22 | background-size: ${backgroundSize};
23 | animation: ${animation};
24 | }
25 |
26 | @keyframes gradient-animation {
27 | 0% {
28 | background-position: 0% 50%;
29 | }
30 | 50% {
31 | background-position: 100% 50%;
32 | }
33 | 100% {
34 | background-position: 0% 50%;
35 | }
36 | }`
37 |
38 | return (
39 |
42 |
55 | {code}
56 |
77 |
78 |
79 | )
80 | }
81 |
82 | export default Output
83 |
--------------------------------------------------------------------------------
/components/Random.js:
--------------------------------------------------------------------------------
1 | import React, { useContext } from "react"
2 | import { SettingsContext } from "../context/SettingsContext"
3 |
4 | const Random = () => {
5 | const { setColorSelection, setAngle, setSpeed } = useContext(SettingsContext)
6 |
7 | const goRandom = () => {
8 | const numColors = 3 + Math.round(Math.random() * 3)
9 | const colors = [...Array(numColors)].map(() => {
10 | // https://css-tricks.com/snippets/javascript/random-hex-color/
11 | return "#" + Math.floor(Math.random() * 16777215).toString(16)
12 | })
13 | setColorSelection(colors)
14 | setAngle(Math.floor(Math.random() * 361))
15 | setSpeed(Math.floor(Math.random() * 10) + 1)
16 | }
17 |
18 | return (
19 |
20 |
36 |
37 | )
38 | }
39 |
40 | export default Random
41 |
--------------------------------------------------------------------------------
/components/SpeedRange.js:
--------------------------------------------------------------------------------
1 | import React, { useContext } from "react"
2 | import { SettingsContext } from "../context/SettingsContext"
3 |
4 | const SpeedRange = () => {
5 | const { speed, setSpeed } = useContext(SettingsContext)
6 |
7 | return (
8 |
9 |
20 | {
28 | setSpeed(e.target.value)
29 | }}
30 | style={{
31 | margin: "0 16px",
32 | width: "180px",
33 | position: "relative",
34 | top: "2px",
35 | }}
36 | />
37 |
47 | {speed}
48 |
49 |
50 | )
51 | }
52 |
53 | export default SpeedRange
54 |
--------------------------------------------------------------------------------
/context/SettingsContext.js:
--------------------------------------------------------------------------------
1 | import React, { useState, createContext } from "react"
2 |
3 | const SettingsContext = createContext({ colorSelection: [] })
4 |
5 | const SettingsProvider = ({ children }) => {
6 | const [colorSelection, setColorSelection] = useState([
7 | "deepskyblue",
8 | "darkviolet",
9 | "blue",
10 | ])
11 | const [angle, setAngle] = useState(300)
12 | const [speed, setSpeed] = useState(5)
13 |
14 | return (
15 |
25 | {children}
26 |
27 | )
28 | }
29 |
30 | export { SettingsContext, SettingsProvider }
31 |
--------------------------------------------------------------------------------
/next.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | reactStrictMode: true,
3 | }
4 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "animated-gradient-background-generator",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "format": "prettier --write \"**/*.{js,jsx,json,md}\"",
7 | "format-watch": "npm run format && onchange \"**/*.{js,jsx,json,md}\" -- prettier --write {{changed}}",
8 | "dev": "next dev",
9 | "build": "next build",
10 | "start": "next start"
11 | },
12 | "dependencies": {
13 | "next": "11.0.1",
14 | "react": "17.0.2",
15 | "react-color": "^2.19.3",
16 | "react-dom": "17.0.2"
17 | },
18 | "devDependencies": {
19 | "eslint": "^7.31.0",
20 | "eslint-config-next": "^11.0.1",
21 | "onchange": "^7.1.0",
22 | "prettier": "^2.3.2"
23 | },
24 | "repository": "https://github.com/johnpolacek/animated-gradient-background-generator",
25 | "license": "MIT-0",
26 | "author": "John Polacek (https://johnpolacek.com/)"
27 | }
28 |
--------------------------------------------------------------------------------
/pages/_app.js:
--------------------------------------------------------------------------------
1 | import "../styles/globals.css"
2 |
3 | function MyApp({ Component, pageProps }) {
4 | return
5 | }
6 |
7 | export default MyApp
8 |
--------------------------------------------------------------------------------
/pages/api/hello.js:
--------------------------------------------------------------------------------
1 | // Next.js API route support: https://nextjs.org/docs/api-routes/introduction
2 |
3 | export default function handler(req, res) {
4 | res.status(200).json({ name: "John Doe" })
5 | }
6 |
--------------------------------------------------------------------------------
/pages/index.js:
--------------------------------------------------------------------------------
1 | import Head from "next/head"
2 | import Image from "next/image"
3 | import { SettingsProvider } from "../context/SettingsContext"
4 | import AnimatedBackground from "../components/AnimatedBackground"
5 | import Controls from "../components/Controls"
6 | import Output from "../components/Output"
7 |
8 | export default function Home() {
9 | return (
10 | <>
11 |
12 | Animated Gradient Background Generator
13 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | Animated Gradient Background Generator
25 |
26 |
27 |
28 |
29 |
46 |
47 |
48 | >
49 | )
50 | }
51 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/johnpolacek/animated-gradient-background-generator/7f42f938ef9dc60d82c0a899638864b7d3c62479/public/favicon.ico
--------------------------------------------------------------------------------
/public/vercel.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/styles/.prettierignore:
--------------------------------------------------------------------------------
1 | .cache
2 | .next
3 | package.json
4 | package-lock.json
5 | public
6 | api/socks.js
7 | node-modules
--------------------------------------------------------------------------------
/styles/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "endOfLine": "lf",
3 | "semi": false,
4 | "singleQuote": false,
5 | "tabWidth": 2,
6 | "trailingComma": "es5"
7 | }
8 |
--------------------------------------------------------------------------------
/styles/globals.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | padding: 0;
4 | margin: 0;
5 | font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
6 | Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
7 | height: 100%;
8 | }
9 |
10 | a {
11 | color: inherit;
12 | }
13 |
14 | * {
15 | box-sizing: border-box;
16 | }
17 |
18 | @keyframes gradient-animation {
19 | 0% {
20 | background-position: 0% 50%;
21 | }
22 | 50% {
23 | background-position: 100% 50%;
24 | }
25 | 100% {
26 | background-position: 0% 50%;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------