├── .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 |
30 |

31 | Created by Chicago web developer{" "} 32 | John Polacek 33 |

34 |

35 | Based on a{" "} 36 | CodePen by 37 | Manuel Pinto 38 |

39 |

40 | Open sourced on{" "} 41 | 42 | Github 43 | 44 |

45 |
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 | 3 | 4 | -------------------------------------------------------------------------------- /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 | --------------------------------------------------------------------------------