Skip to content

Commit c1b5c74

Browse files
feat: Add simple color converter toool
1 parent 596be77 commit c1b5c74

File tree

5 files changed

+240
-0
lines changed

5 files changed

+240
-0
lines changed

Index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,3 +111,4 @@
111111
| [Pomodoro Timer](https://github.com/Ayushparikh-code/Web-dev-mini-projects/tree/main/Pomodoro-Timer) | A simple Pomodoro Timer using React.js, where you can track the time spent on work and break. |
112112
| [TravelPro](https://github.com/Ayushparikh-code/Web-dev-mini-projects/tree/main/TravelPro) | A simple static website to enhance HTML & CSS skills |
113113
|[Audio Visualization with three.js](https://github.com/Ayushparikh-code/Web-dev-mini-projects/tree/main/Audio%20Visualization%20with%20three.js) | audio visualization using the powerful 3D graphics library, three.js |
114+
|[Simple Color converter tool](https://github.com/Ayushparikh-code/Web-dev-mini-projects/tree/main/simple-color-converter) | Simple RGB <> HEX color converter tool |

simple-color-converter/README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# Simple Color converter
2+
> Simple CSS color converter tool from RGB to hex and vice-versa
3+
4+
## To run
5+
- No config needed. Start a HTTP server in the current directory
6+
- You can run the following command provided you have `node`, `npx` installed
7+
8+
``` shell
9+
npx serve -p 8080
10+
```
11+
- Open [http://localhost:8080](http://localhost:8080) to see the changed
12+
13+
## Screenshots
14+
15+
16+
## Contribute
17+
Change UI, play around, tweak as you like.
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
body {
2+
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
3+
background-color: #121212;
4+
color: white;
5+
text-align: center;
6+
align-items: center;
7+
}
8+
9+
.container .main-app-container .input-container {
10+
display: flex;
11+
margin: 0 20%;
12+
justify-content: space-around;
13+
}
14+
15+
.container .main-app-container .input-container .mode-dropdown-container .mode-dropdown {
16+
width: 150px;
17+
height: 40px;
18+
border-radius: 5px;
19+
}
20+
21+
.container .main-app-container input {
22+
width: 200px;
23+
height: 30px;
24+
border: 1px solid #333;
25+
border-radius: 5px;
26+
padding: 5px;
27+
}
28+
29+
.container .main-app-container .input-container .convert-button-container button {
30+
width: 100px;
31+
height: 40px;
32+
border: 1px solid #333;
33+
cursor: pointer;
34+
border-radius: 5px;
35+
}

simple-color-converter/index.html

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<link rel ="stylesheet" href="css/style.css">
7+
<title>Color Converter</title>
8+
</head>
9+
<body>
10+
<div class="container">
11+
<h1>Color Converter</h1>
12+
<div class="main-app-container">
13+
<div class="input-container"></div>
14+
<div class="output-container"></div>
15+
</div>
16+
</div>
17+
<script src="js/index.js"></script>
18+
</body>
19+
</html>

simple-color-converter/js/index.js

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
const MODES = {
2+
RGB_TO_HEX: 'RGB to HEX',
3+
HEX_TO_RGB: 'HEX to RGB'
4+
};
5+
6+
let selectedMode = MODES.RGB_TO_HEX;
7+
8+
function modeChangeHandler(event) {
9+
const newMode = event.target.value;
10+
if (selectedMode === newMode) return;
11+
12+
selectedMode = newMode;
13+
14+
const inputContainer = document.querySelector('.input-container');
15+
const oldInputsContainer = inputContainer.querySelector('.mode-inputs-container');
16+
if (oldInputsContainer) {
17+
inputContainer.removeChild(oldInputsContainer);
18+
}
19+
20+
renderModeInputs(inputContainer, selectedMode);
21+
}
22+
23+
function renderModeDropdown(container) {
24+
const divElement = document.createElement('div');
25+
divElement.className = 'mode-dropdown-container';
26+
container.appendChild(divElement);
27+
28+
const dropdownLabel = document.createElement('label');
29+
dropdownLabel.textContent = 'Select Conversion Mode: ';
30+
dropdownLabel.setAttribute('for', 'mode-dropdown');
31+
32+
const modeDropdown = document.createElement('select');
33+
modeDropdown.className = 'mode-dropdown';
34+
modeDropdown.addEventListener('change', modeChangeHandler);
35+
36+
Object.values(MODES).forEach(mode => {
37+
const option = document.createElement('option');
38+
option.value = mode;
39+
option.textContent = mode;
40+
if (mode === selectedMode) {
41+
option.selected = true;
42+
}
43+
modeDropdown.appendChild(option);
44+
});
45+
46+
divElement.appendChild(dropdownLabel);
47+
divElement.appendChild(modeDropdown);
48+
}
49+
50+
function renderModeInputs(container, mode) {
51+
const inputsContainer = document.createElement('div');
52+
inputsContainer.className = 'mode-inputs-container';
53+
container.appendChild(inputsContainer);
54+
55+
if (mode === MODES.RGB_TO_HEX) {
56+
['R', 'G', 'B'].forEach(label => {
57+
const input = document.createElement('input');
58+
input.type = 'number';
59+
input.placeholder = `${label} (0-255)`;
60+
input.min = 0;
61+
input.max = 255;
62+
input.style.width = '80px';
63+
inputsContainer.appendChild(input);
64+
});
65+
} else if (mode === MODES.HEX_TO_RGB) {
66+
const hexInput = document.createElement('input');
67+
hexInput.type = 'text';
68+
hexInput.placeholder = 'HEX (#RRGGBB)';
69+
inputsContainer.appendChild(hexInput);
70+
}
71+
}
72+
73+
function renderConvertButton(inputContainer) {
74+
const convertButtonDiv = document.createElement('div');
75+
convertButtonDiv.className = 'convert-button-container';
76+
inputContainer.appendChild(convertButtonDiv);
77+
78+
const convertButton = document.createElement('button');
79+
convertButton.textContent = 'Convert';
80+
convertButton.addEventListener('click', renderOutput);
81+
82+
convertButtonDiv.appendChild(convertButton);
83+
}
84+
85+
function getHexFromRGB(r, g, b) {
86+
const toHex = (value) => {
87+
const hex = value.toString(16);
88+
return hex.length === 1 ? '0' + hex : hex;
89+
};
90+
return `#${toHex(r)}${toHex(g)}${toHex(b)}`.toUpperCase();
91+
}
92+
93+
function getRGBFromHex(hex) {
94+
if (hex.startsWith('#')) {
95+
hex = hex.slice(1);
96+
}
97+
if (hex.length !== 6) {
98+
return 'Invalid HEX format';
99+
}
100+
const r = parseInt(hex.slice(0, 2), 16);
101+
const g = parseInt(hex.slice(2, 4), 16);
102+
const b = parseInt(hex.slice(4, 6), 16);
103+
return `RGB(${r}, ${g}, ${b})`;
104+
}
105+
106+
function getTextColor(selectedMode, inputs) {
107+
if (selectedMode === MODES.RGB_TO_HEX) {
108+
const r = parseInt(inputs[0].value) || 0;
109+
const g = parseInt(inputs[1].value) || 0;
110+
const b = parseInt(inputs[2].value) || 0;
111+
return (r + g + b > 382) ? 'black' : 'white';
112+
} else if (selectedMode === MODES.HEX_TO_RGB) {
113+
let hexValue = inputs[0].value;
114+
if (hexValue.startsWith('#')) {
115+
hexValue = hexValue.slice(1);
116+
}
117+
if (hexValue.length !== 6) {
118+
return 'black'; // default color for invalid HEX
119+
}
120+
return (parseInt(hexValue.slice(0, 2), 16) + parseInt(hexValue.slice(2, 4), 16) + parseInt(hexValue.slice(4, 6), 16) > 382) ? 'black' : 'white';
121+
}
122+
return 'black';
123+
}
124+
125+
function getBgColor(selectedMode, inputs) {
126+
return selectedMode === MODES.RGB_TO_HEX
127+
? `rgb(${inputs[0].value || 0}, ${inputs[1].value || 0}, ${inputs[2].value || 0})`
128+
: inputs[0].value || '#ffffff';
129+
}
130+
131+
function renderOutput() {
132+
const outputContainer = document.querySelector('.output-container');
133+
outputContainer.style.marginTop = '20px';
134+
outputContainer.innerHTML = '';
135+
136+
const inputContainer = document.querySelector('.input-container');
137+
const inputsContainer = inputContainer.querySelector('.mode-inputs-container');
138+
const inputs = inputsContainer.querySelectorAll('input');
139+
140+
let outputText = '';
141+
142+
if (selectedMode === MODES.RGB_TO_HEX) {
143+
outputText = getHexFromRGB(
144+
parseInt(inputs[0].value),
145+
parseInt(inputs[1].value),
146+
parseInt(inputs[2].value)
147+
);
148+
} else if (selectedMode === MODES.HEX_TO_RGB) {
149+
outputText = getRGBFromHex(inputs[0].value);
150+
}
151+
152+
outputContainer.textContent = outputText;
153+
document.body.style.backgroundColor = getBgColor(selectedMode, inputs);
154+
155+
// Set text color based on background brightness
156+
document.body.style.color = getTextColor(selectedMode, inputs);
157+
}
158+
159+
function main() {
160+
const mainAppContainer = document.querySelector('.main-app-container');
161+
const inputContainer = mainAppContainer.querySelector('.input-container');
162+
163+
renderModeDropdown(inputContainer);
164+
renderConvertButton(inputContainer);
165+
renderModeInputs(inputContainer, selectedMode);
166+
}
167+
168+
document.addEventListener('DOMContentLoaded', main);

0 commit comments

Comments
 (0)