From efcffc46a28257428dd59ab0de960c32c466d9c5 Mon Sep 17 00:00:00 2001 From: do0ori Date: Sat, 16 Dec 2023 01:06:40 +0900 Subject: [PATCH] do0ori's Progress Bar --- README.md | 30 ++++++++++++++++++ index.html | 17 +++++++++++ progressbar.js | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++ style.css | 54 ++++++++++++++++++++++++++++++++ 4 files changed, 184 insertions(+) create mode 100644 README.md create mode 100644 index.html create mode 100644 progressbar.js create mode 100644 style.css diff --git a/README.md b/README.md new file mode 100644 index 0000000..d4b396f --- /dev/null +++ b/README.md @@ -0,0 +1,30 @@ +# ✅Progress Bar +간단한 progress bar입니다. + +## Motivation Behind the Project +notion에 강의를 들으며 정리를 하는데 강의 진행률을 시각화하고 싶어서 notion progress bar widget에 대해 열심히 찾아봤지만 notion 자체로는 [table view database의 수식을 이용하는 방법](https://www.notion.so/do0ori/Progress-Bar-b908b8a1e4804ca5a6ababb313b216bc)이 최선이었고 notion의 link embed를 활용한 third-party widget도 존재하지 않았습니다. 여러모로 만족스럽지 않아 직접 만들게 되었습니다. + +## Usage +🔗[Progress Bar 바로가기](https://do0ori.github.io/progress-bar/) + +| progress bar 클릭 위치 | 동작 | +| --- | --- | +| 왼쪽 | -1 | +| 오른쪽 | +1 | +| 가운데 | total 숫자 설정 | + +## Key Features +- 공간 차지를 많이 하지 않습니다. +- 필요한 기능만 넣었습니다. +- 이식성이 높습니다. +- LocalStorage에 데이터를 저장하여 domain별로 반영구적으로 unique하게 사용 가능합니다. + +## Technology Stack +

+ + + +

+ +## Contributions +버그를 발견하거나 새로운 기능을 제안은 언제나 환영입니다! [이슈](https://github.com/do0ori/progress-bar/issues)를 작성해주세요. \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..00d6ff8 --- /dev/null +++ b/index.html @@ -0,0 +1,17 @@ + + + + + + do0ori's Progress Bar + + + +
+
+ 0 / 0 +
+ +
+ + \ No newline at end of file diff --git a/progressbar.js b/progressbar.js new file mode 100644 index 0000000..3ac7441 --- /dev/null +++ b/progressbar.js @@ -0,0 +1,83 @@ +const totalKey = "total"; +const progressKey = "progress"; + +document.addEventListener("DOMContentLoaded", function () { + let total = parseInt(localStorage.getItem(totalKey)) || 1; + let progress = parseInt(localStorage.getItem(progressKey)) || 0; + + const updateProgressBar = () => { + const progressBar = document.getElementById("progress-bar"); + const progressPercentage = (progress / total) * 100; + progressBar.style.width = progressPercentage + "%"; + } + + const updateCountDisplay = () => { + const countDisplay = document.getElementById("count-display"); + countDisplay.textContent = progress + " / " + total; + } + + const resetProgress = () => { + const totalInput = document.getElementById("total-input"); + const userInput = totalInput.value.trim(); + const newTotal = parseInt(userInput); + + // Initialize only when user modified input value + if (!isNaN(newTotal) && newTotal > 0 && newTotal !== total) { + total = newTotal; + localStorage.setItem(totalKey, total); + progress = 0; + localStorage.setItem(progressKey, progress); + totalInput.value = total; + updateProgressBar(); + updateCountDisplay(); + } + } + + const decreaseProgress = () => { + if (progress > 0) { + progress--; + localStorage.setItem(progressKey, progress); + updateProgressBar(); + updateCountDisplay(); + } + } + + const increaseProgress = () => { + if (progress < total) { + progress++; + localStorage.setItem(progressKey, progress); + updateProgressBar(); + updateCountDisplay(); + } + } + + const handleClick = (event) => { + const progressContainer = document.getElementById("progress-container"); + const clickPosition = event.clientX - progressContainer.offsetLeft; + const third = progressContainer.clientWidth / 3; + + if (clickPosition < third) { + // click left of the progress bar + decreaseProgress(); + } else if (clickPosition > 2 * third) { + // click right of the progress bar + increaseProgress(); + } else { + // click middle of the progress bar + const totalInput = document.getElementById("total-input"); + totalInput.style.display = "block"; + totalInput.focus(); + } + } + + // Attach event listeners + document.getElementById("progress-container").addEventListener("click", handleClick); + document.getElementById("total-input").addEventListener("blur", function () { + resetProgress(); + this.style.display = "none"; + }); + + // Initialize display + updateProgressBar(); + updateCountDisplay(); +}); \ No newline at end of file diff --git a/style.css b/style.css new file mode 100644 index 0000000..969a7bf --- /dev/null +++ b/style.css @@ -0,0 +1,54 @@ +body { + font-family: 'Arial', sans-serif; + text-align: center; + margin: 0; + height: 100vh; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} + +#progress-container { + width: 85vw; + border: 1px solid #ccc; + position: relative; + margin: 20px auto; + padding: 5px; +} + +#progress-bar { + height: 20px; + background-color: #4CAF50; + width: 0; + transition: width 0.3s ease; + position: relative; +} + +#count-display { + display: none; + position: absolute; + top: 30px; + right: 0; + transform: translateX(50%); + background-color: #333; + color: #fff; + padding: 5px 10px; + border-radius: 5px; + white-space: nowrap; +} + +#total-input { + display: none; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + width: 50px; + padding: 5px; + border: 1px solid #ccc; +} + +#progress-container:hover #count-display { + display: block; +} \ No newline at end of file