├── 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 | })
--------------------------------------------------------------------------------