├── icons ├── lock-closed.svg └── lock-open.svg ├── index.html ├── main.css └── main.js /icons/lock-closed.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /icons/lock-open.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Colour Palette Generator 8 | 9 | 10 | 11 | 12 | 13 |
14 |

Colour Palette

15 |

16 | Press [] to generate a new palette 17 |

18 | 19 |

Generator

20 | 21 |
22 |
23 | 26 | 27 | 28 | 29 | 30 |
31 |
32 | 35 | 36 | 37 | 38 | 39 |
40 |
41 | 44 | 45 | 46 | 47 | 48 |
49 |
50 | 53 | 54 | 55 | 56 | 57 |
58 |
59 |
60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /main.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --primary: #D81E5D; 3 | --secondary: #8A4FFF; 4 | --light: #EEE; 5 | --grey: #AAA; 6 | --dark: #1e2f42; 7 | } 8 | 9 | * { 10 | margin: 0; 11 | padding: 0; 12 | 13 | box-sizing: border-box; 14 | font-family: 'Fira Sans', sans-serif; 15 | } 16 | 17 | body { 18 | background-color: var(--light); 19 | } 20 | 21 | main { 22 | padding: 4rem 2rem; 23 | max-width: 1200px; 24 | margin: 0 auto; 25 | } 26 | 27 | h1 { 28 | color: var(--dark); 29 | font-size: 3rem; 30 | font-weight: 900; 31 | text-transform: uppercase; 32 | margin-bottom: 1rem; 33 | } 34 | 35 | p { 36 | color: var(--grey); 37 | font-size: 1.125rem; 38 | margin-bottom: 2rem; 39 | } 40 | 41 | .generator-button { 42 | color: var(--primary); 43 | font-size: inherit; 44 | font-weight: 700; 45 | background: linear-gradient(to bottom right, var(--primary), var(--secondary)); 46 | -webkit-background-clip: text; 47 | -webkit-text-fill-color: transparent; 48 | transition: 0.4s ease-out; 49 | } 50 | 51 | .generator-button:hover { 52 | padding-left: 0.5rem; 53 | padding-right: 0.5rem; 54 | } 55 | 56 | h4 { 57 | color: var(--grey); 58 | font-size: 1.5rem; 59 | text-transform: uppercase; 60 | margin-bottom: 1rem; 61 | } 62 | 63 | .colours { 64 | display: grid; 65 | grid-template-columns: repeat(1, 1fr); 66 | grid-gap: 1rem; 67 | } 68 | 69 | .colour { 70 | display: flex; 71 | align-items: center; 72 | justify-content: space-between; 73 | padding: 0.5rem 1rem; 74 | background-color: var(--dark); 75 | color: #fff; 76 | border-radius: 1rem; 77 | transition: 0.4s ease-out; 78 | border: 2px solid transparent; 79 | } 80 | 81 | .colour.copied { 82 | border: 2px solid red; 83 | } 84 | 85 | button, input { 86 | appearance: none; 87 | background: none; 88 | border: none; 89 | outline: none; 90 | color: inherit; 91 | } 92 | 93 | button { 94 | user-select: none; 95 | cursor: pointer; 96 | } 97 | 98 | .lock-toggle { 99 | opacity: 0.5; 100 | transition: 0.4s linear; 101 | } 102 | 103 | .lock-toggle.is-locked { 104 | opacity: 1; 105 | } 106 | 107 | .colour-input { 108 | text-align: center; 109 | } 110 | 111 | @media (min-width: 768px) { 112 | .colours { 113 | grid-template-columns: repeat(2, 1fr); 114 | } 115 | } 116 | 117 | @media (min-width: 1024px) { 118 | .colours { 119 | grid-template-columns: repeat(4, 1fr); 120 | } 121 | 122 | .colour { 123 | flex-direction: column; 124 | align-items: center; 125 | justify-content: center; 126 | padding: 1rem; 127 | } 128 | 129 | .colour-input { 130 | margin-top: 1rem; 131 | margin-bottom: 1rem; 132 | } 133 | } -------------------------------------------------------------------------------- /main.js: -------------------------------------------------------------------------------- 1 | class Colour { 2 | constructor(hex, element) { 3 | this.hex = hex; 4 | this.element = element; 5 | this.locked = false; 6 | } 7 | 8 | setHex(hex) { 9 | this.hex = hex; 10 | this.element.style.backgroundColor = hex; 11 | this.element.querySelector(".colour-input").value = hex; 12 | } 13 | 14 | setLocked(locked) { 15 | this.locked = locked; 16 | 17 | if (locked) { 18 | this.element 19 | .querySelector(".lock-toggle") 20 | .classList.add("is-locked"); 21 | 22 | this.element 23 | .querySelector("img") 24 | .src = "icons/lock-closed.svg"; 25 | } else { 26 | this.element 27 | .querySelector(".lock-toggle") 28 | .classList.remove("is-locked"); 29 | 30 | this.element 31 | .querySelector("img") 32 | .src = "icons/lock-open.svg"; 33 | } 34 | } 35 | 36 | toggleLocked() { 37 | this.setLocked(!this.locked); 38 | } 39 | 40 | generateHex() { 41 | if (this.locked) { 42 | return 43 | } 44 | 45 | const chars = "0123456789ABCDEF"; 46 | let color = "#"; 47 | for (let i = 0; i < 6; i++) { 48 | color += chars[Math.floor(Math.random() * 16)]; 49 | } 50 | 51 | this.setHex(color); 52 | } 53 | 54 | copyToClipboard() { 55 | const input = this.element.querySelector(".colour-input"); 56 | input.select(); 57 | document.execCommand("copy"); 58 | input.blur(); 59 | 60 | this.element.classList.add("copied"); 61 | setTimeout(() => { 62 | this.element.classList.remove("copied"); 63 | }, 1000); 64 | } 65 | } 66 | 67 | const colour_elements = document.querySelectorAll('.colours .colour'); 68 | 69 | const colours = []; 70 | 71 | for (let i = 0; i < colour_elements.length; i++) { 72 | const colour_element = colour_elements[i]; 73 | 74 | const input = colour_element.querySelector(".colour-input"); 75 | const lock_toggle = colour_element.querySelector(".lock-toggle"); 76 | const copy_btn = colour_element.querySelector(".copy-hex"); 77 | 78 | const hex = input.value; 79 | 80 | const colour = new Colour(hex, colour_element); 81 | 82 | input.addEventListener('input', (e) => colour.setHex(e.target.value)); 83 | lock_toggle.addEventListener('click', () => colour.toggleLocked()); 84 | copy_btn.addEventListener('click', () => colour.copyToClipboard()); 85 | 86 | colour.generateHex(); 87 | colours.push(colour); 88 | } 89 | 90 | document.querySelector(".generator-button").addEventListener("click", () => { 91 | for (let i = 0; i < colours.length; i++) { 92 | colours[i].generateHex(); 93 | } 94 | }); 95 | 96 | document.addEventListener('keypress', (e) => { 97 | if (e.code.toLowerCase() === "space") { 98 | document.querySelector(".generator-button").click(); 99 | } 100 | }) --------------------------------------------------------------------------------