diff --git a/Domains/Frontend/MiniProjects/Stopwatch/._index.html b/Domains/Frontend/MiniProjects/Stopwatch/._index.html new file mode 100644 index 00000000..f6cc6074 Binary files /dev/null and b/Domains/Frontend/MiniProjects/Stopwatch/._index.html differ diff --git a/Domains/Frontend/MiniProjects/Stopwatch/README.md b/Domains/Frontend/MiniProjects/Stopwatch/README.md new file mode 100644 index 00000000..7c76d57a --- /dev/null +++ b/Domains/Frontend/MiniProjects/Stopwatch/README.md @@ -0,0 +1,12 @@ +**Contributor:** Aaditya-2407 + +## Description +A functional stopwatch application built with vanilla JavaScript. It allows users to start, stop, and reset the timer, as well as record lap times. + +## Tech Stack +- HTML +- CSS +- JavaScript (Vanilla) + +## How to Run +1. Open the `index.html` file in your web browser. \ No newline at end of file diff --git a/Domains/Frontend/MiniProjects/Stopwatch/index.html b/Domains/Frontend/MiniProjects/Stopwatch/index.html new file mode 100644 index 00000000..94003e36 --- /dev/null +++ b/Domains/Frontend/MiniProjects/Stopwatch/index.html @@ -0,0 +1,26 @@ + + + + + + Stopwatch + + + +
+

Stopwatch

+
+ 00:00:00.00 +
+
+ + +
+
+ +
+
+ + + \ No newline at end of file diff --git a/Domains/Frontend/MiniProjects/Stopwatch/script.js b/Domains/Frontend/MiniProjects/Stopwatch/script.js new file mode 100644 index 00000000..0a8c4831 --- /dev/null +++ b/Domains/Frontend/MiniProjects/Stopwatch/script.js @@ -0,0 +1,101 @@ +const timerDisplay = document.getElementById('timer-display'); +const startStopBtn = document.getElementById('start-stop-btn'); +const lapResetBtn = document.getElementById('lap-reset-btn'); +const lapsList = document.getElementById('laps-list'); + +let startTime; +let updatedTime; +let difference; +let timerInterval; +let running = false; +let lapCounter = 1; + +function startTimer() { + if (!running) { + startTime = new Date().getTime() - (difference || 0); + timerInterval = setInterval(updateTimer, 10); // Update every 10ms for centiseconds + + startStopBtn.textContent = 'Stop'; + startStopBtn.classList.remove('start'); + startStopBtn.classList.add('stop'); + + lapResetBtn.textContent = 'Lap'; + lapResetBtn.disabled = false; + + running = true; + } +} + +function stopTimer() { + if (running) { + clearInterval(timerInterval); + difference = new Date().getTime() - startTime; + + startStopBtn.textContent = 'Start'; + startStopBtn.classList.remove('stop'); + startStopBtn.classList.add('start'); + + lapResetBtn.textContent = 'Reset'; + + running = false; + } +} + +function resetTimer() { + clearInterval(timerInterval); + timerDisplay.textContent = '00:00:00.00'; + startStopBtn.textContent = 'Start'; + startStopBtn.classList.remove('stop'); + startStopBtn.classList.add('start'); + + lapResetBtn.textContent = 'Lap'; + lapResetBtn.disabled = true; + + difference = 0; + running = false; + lapCounter = 1; + lapsList.innerHTML = ''; +} + +function updateTimer() { + updatedTime = new Date().getTime() - startTime; + timerDisplay.textContent = formatTime(updatedTime); +} + +function formatTime(time) { + let minutes = Math.floor((time % (1000 * 60 * 60)) / (1000 * 60)); + let seconds = Math.floor((time % (1000 * 60)) / 1000); + let centiseconds = Math.floor((time % 1000) / 10); + + minutes = String(minutes).padStart(2, '0'); + seconds = String(seconds).padStart(2, '0'); + centiseconds = String(centiseconds).padStart(2, '0'); + + return `${minutes}:${seconds}:${centiseconds}`; +} + +function addLap() { + if (running) { + const lapTime = timerDisplay.textContent; + const li = document.createElement('li'); + li.innerHTML = `Lap ${lapCounter} ${lapTime}`; + lapsList.prepend(li); + lapCounter++; + } +} + +startStopBtn.addEventListener('click', () => { + if (running) { + stopTimer(); + } else { + startTimer(); + } +}); + +lapResetBtn.addEventListener('click', () => { + if (running) { + addLap(); + } else { + resetTimer(); + } +}); \ No newline at end of file diff --git a/Domains/Frontend/MiniProjects/Stopwatch/style.css b/Domains/Frontend/MiniProjects/Stopwatch/style.css new file mode 100644 index 00000000..f24baf63 --- /dev/null +++ b/Domains/Frontend/MiniProjects/Stopwatch/style.css @@ -0,0 +1,102 @@ +body { + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; + display: flex; + justify-content: center; + align-items: center; + height: 100vh; + background-color: #1c1c1e; + color: #ffffff; + margin: 0; +} + +.stopwatch-container { + width: 90%; + max-width: 400px; + padding: 2.5rem; + background-color: #2c2c2e; + border-radius: 16px; + box-shadow: 0 10px 20px rgba(0, 0, 0, 0.3); + text-align: center; +} + +h1 { + margin-bottom: 2rem; + font-weight: 600; +} + +.timer-display { + font-size: 3.5rem; + font-weight: 300; + font-family: "SF Mono", "Menlo", "Courier New", monospace; + margin-bottom: 2rem; + letter-spacing: 1px; +} + +.button-controls { + display: flex; + justify-content: space-around; + margin-bottom: 2rem; +} + +.button-controls button { + font-size: 1.1rem; + font-weight: 600; + width: 80px; + height: 80px; + border-radius: 50%; + border: none; + cursor: pointer; + transition: all 0.2s ease; +} + +#start-stop-btn.start { + background-color: #34c759; + color: white; +} + +#start-stop-btn.stop { + background-color: #ff3b30; + color: white; +} + +#lap-reset-btn { + background-color: #5856d6; + color: white; +} + +#lap-reset-btn:disabled { + background-color: #3a3a3c; + color: #8e8e93; + cursor: not-allowed; +} + +.laps-container { + max-height: 200px; + overflow-y: auto; + text-align: left; + background-color: #1c1c1e; + border-radius: 8px; + padding: 0.5rem 0; +} + +#laps-list { + list-style: none; + padding: 0 1rem; + margin: 0; +} + +#laps-list li { + font-family: "SF Mono", "Menlo", "Courier New", monospace; + padding: 0.75rem 0.5rem; + border-bottom: 1px solid #3a3a3c; + display: flex; + justify-content: space-between; +} + +#laps-list li:last-child { + border-bottom: none; +} + +#laps-list li .lap-label { + color: #8e8e93; +} \ No newline at end of file diff --git a/Domains/Frontend/MiniProjects/UnitConverter/._index.html b/Domains/Frontend/MiniProjects/UnitConverter/._index.html new file mode 100644 index 00000000..ebd89909 Binary files /dev/null and b/Domains/Frontend/MiniProjects/UnitConverter/._index.html differ diff --git a/Domains/Frontend/MiniProjects/UnitConverter/README.md b/Domains/Frontend/MiniProjects/UnitConverter/README.md new file mode 100644 index 00000000..d7adafc0 --- /dev/null +++ b/Domains/Frontend/MiniProjects/UnitConverter/README.md @@ -0,0 +1,12 @@ +**Contributor:** Aaditya-2407 + +## Description +A simple web app that converts between different units of measurement, such as length (cm/in), weight (kg/lb), and temperature (C/F). + +## Tech Stack +- HTML +- CSS +- JavaScript (Vanilla) + +## How to Run +1. Open the `index.html` file in your web browser. \ No newline at end of file diff --git a/Domains/Frontend/MiniProjects/UnitConverter/index.html b/Domains/Frontend/MiniProjects/UnitConverter/index.html new file mode 100644 index 00000000..3fc01d6d --- /dev/null +++ b/Domains/Frontend/MiniProjects/UnitConverter/index.html @@ -0,0 +1,39 @@ + + + + + + Unit Converter + + + +
+

Unit Converter

+
+ + +
+
=
+
+ + +
+

+
+ + + \ No newline at end of file diff --git a/Domains/Frontend/MiniProjects/UnitConverter/script.js b/Domains/Frontend/MiniProjects/UnitConverter/script.js new file mode 100644 index 00000000..1b757f33 --- /dev/null +++ b/Domains/Frontend/MiniProjects/UnitConverter/script.js @@ -0,0 +1,79 @@ +const inputValue = document.getElementById('input-value'); +const fromUnit = document.getElementById('from-unit'); +const outputValue = document.getElementById('output-value'); +const toUnit = document.getElementById('to-unit'); +const errorMsg = document.getElementById('error-msg'); + +const conversionRates = { + // Length + 'cm-in': 0.393701, + 'in-cm': 2.54, + // Weight + 'kg-lb': 2.20462, + 'lb-kg': 0.453592, + // Compatibility groups + length: ['cm', 'in'], + weight: ['kg', 'lb'], + temp: ['c', 'f'], +}; + +function getCompatibilityGroup(unit) { + if (conversionRates.length.includes(unit)) return 'length'; + if (conversionRates.weight.includes(unit)) return 'weight'; + if (conversionRates.temp.includes(unit)) return 'temp'; + return null; +} + +function convertUnits() { + const from = fromUnit.value; + const to = toUnit.value; + const input = parseFloat(inputValue.value); + + const fromGroup = getCompatibilityGroup(from); + const toGroup = getCompatibilityGroup(to); + + if (fromGroup !== toGroup || !fromGroup) { + outputValue.value = ''; + errorMsg.textContent = 'Conversion not possible (Incompatible units).'; + return; + } + + errorMsg.textContent = ''; // Clear error + + if (isNaN(input)) { + outputValue.value = ''; + return; + } + + let result; + + // Handle special case: Temperature + if (fromGroup === 'temp') { + if (from === 'c' && to === 'f') { + result = (input * 9/5) + 32; + } else if (from === 'f' && to === 'c') { + result = (input - 32) * 5/9; + } else { + result = input; // c to c or f to f + } + } else { + // Handle length and weight + const conversionKey = `${from}-${to}`; + if (conversionRates[conversionKey]) { + result = input * conversionRates[conversionKey]; + } else if (from === to) { + result = input; // cm to cm or kg to kg + } + } + + outputValue.value = result.toFixed(2); +} + +// Add event listeners to all inputs +[inputValue, fromUnit, toUnit].forEach(input => { + input.addEventListener('input', convertUnits); + input.addEventListener('change', convertUnits); +}); + +// Initial conversion on load +convertUnits(); \ No newline at end of file diff --git a/Domains/Frontend/MiniProjects/UnitConverter/style.css b/Domains/Frontend/MiniProjects/UnitConverter/style.css new file mode 100644 index 00000000..aa7bec3c --- /dev/null +++ b/Domains/Frontend/MiniProjects/UnitConverter/style.css @@ -0,0 +1,72 @@ +body { + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; + display: flex; + justify-content: center; + align-items: center; + height: 100vh; + background-color: #f0f2f5; + margin: 0; +} + +.converter-container { + width: 90%; + max-width: 450px; + padding: 2.5rem; + background-color: #ffffff; + border-radius: 16px; + box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1); +} + +h1 { + text-align: center; + color: #007aff; + margin-bottom: 2rem; +} + +.input-group { + display: flex; + gap: 1rem; + margin-bottom: 1rem; +} + +.input-group input, +.input-group select { + width: 100%; + padding: 0.75rem; + border: 1px solid #ddd; + border-radius: 8px; + font-size: 1rem; + background-color: #f9f9f9; +} + +.input-group input:focus, +.input-group select:focus { + outline: none; + border-color: #007aff; + box-shadow: 0 0 0 3px rgba(0,122,255,0.1); +} + +input[type="number"]::-webkit-inner-spin-button, +input[type="number"]::-webkit-outer-spin-button { + -webkit-appearance: none; + margin: 0; +} +input[type="number"] { + -webkit-appearance: textfield; + -moz-appearance: textfield; + appearance: textfield; +} + +.equals-sign { + text-align: center; + font-size: 2rem; + font-weight: 600; + color: #007aff; + margin: 1rem 0; +} + +.error { + color: #ff3b30; + text-align: center; + height: 1.2em; +} \ No newline at end of file