Автор оригинала: FreeCodeCamp Community Member.
Cynthia Lee.
Я приступил к моему путешествию FreeCodeCamp в декабре 2017 года, и два проекта застенчивы от завершения сертификата по развитию передней части. Этот пост документирует мой процесс завершения проекта Pomodoro Clock.
Что такое часы Pomodoro?
Техника Помодоро Это структура управления временем, которая так же проста, как эффективна – вы используете таймер, чтобы разбить вашу работу во временных блоках (обычно 25 минут), разделенных 5-минутным перерывом. После каждого 4 Pomodoros вы можете взять более длительный перерыв.
Я должен был выполнить следующие истории пользователей:
- Я могу начать 25 минут Pomodoro, и таймер уйдет раз, раз истек 25 минут.
- Я могу сбросить часы для моего следующего Pomodoro.
- Я могу настроить длину каждого Pomodoro.
Дизайн/макет
Мой принцип дизайна – сохранить пользовательский интерфейс чистый и простой. Мне понравилось идею использования помидоров в качестве таймера. Есть дисплей работы/разрыва, обратный отсчет таймера и кнопка воспроизведения/паузы.
Ниже таймера у меня были настройки, чтобы изменить продолжительность работы и разрыва и кнопку сброса.
Проблемы макета, которые я столкнулся с
У меня были серьезные проблемы с получением изображения томата, расположенного на заднем плане под другими элементами. Как бы я хотел, чтобы там была опция макета, которую я мог выбрать! ?
Одно предположение, что я обнаружил, что для спасения томатного изображения на моем предпочтительном фоновом цвете в качестве нового изображения, а затем используйте это изображение на заднем плане. Недостаток к этому было то, что он начал смотреть, как только проверил отзывчивость макета.
В конце концов мне удалось получить это правильно с комбинацией Абсолютное позиционирование модифицировать верх и левый проценты, а трансформировать Отказ
#status { position: absolute; top: 45%; left:50%; transform: translate(-50%, -50%);}.timerDisplay { position: absolute; top: 60%; left: 50%; transform: translate(-50%, -50%);}#start-btn { position: absolute; bottom: 8%; left: 48%; transform: translate(-50%, -50%);}Нижние настройки были довольно простыми. Я использовал CSS Grid, чтобы отделить компоненты в три столбца, причем средний столбец в половине ширины наружных колонн.
.settings { margin: auto; width: 80%; display: grid; grid-template-columns: 2fr 1fr 2fr; align-items: center;}Еще раз я использовал трансформировать Чтобы сдвинуть кнопку сброса для лучшего выравнивания.
Структурирование моего кода – а затем разрывая его
Я считаю, что это полезно придумать мою структуру кода, если я сломаю требования:
- Таймер будет переключаться между запуском и приостановить, когда я нажимаю кнопку «Пуск».
- Как только таймер достигнет нуля, сигнал тревоги будет выключен.
- Рабочая сессия всегда сопровождается сеансом перерыва.
- Продолжительность работы и разрыва могут быть изменены.
- Кнопка «RESET» будет (вы угадаете) сбросить таймер.
Я ранее завершил часы обратного отсчета в WES BOS JavaScript 30 курс, поэтому я знал, что смогу использовать Setinterval метод. Я также решил бросить вызов себе, придерживаясь ванильного JavaScript и избегаю полагаться на jQuery.
И поэтому я начал писать свой код JavaScript. Хотя мне удалось создать функциональные часы Pomodoro, я не буду проходить через первую версию моего кода здесь. Это потому, что я внес значительные изменения в нем после получения конструктивной обратной связи от удивительного незнакомца на Reddit. ?
Да, хорошие вещи случаются на Reddit!
Основными точками обратной связи были:
SetInterval (таймер, 1000)занимает как минимум 1000 мс, но может занять больше времени. Таким образом, вы должны проверить, сколько времени на самом деле прошло, или ваши часы могут быть неточными.- Группа Все обновления HTML в одном разделе, так как это облегчает обновление и отладку вашего кода.
- Как правило, хорошая идея сделать код, не думая о представлении вообще.
- Будьте уверены в логике таймера и избавьтесь от ненужного кода.
- Убедитесь, что имена переменных являются описательными. Оставьте комментарии при необходимости.
Вы можете просматривать мой первый коммит на Github Отказ
Рефакторинг моего кода
После того, как все это ценные отзывы, я несколько раз позаботился о моем коде, пока я не удовлетворен этим.
Во-первых, я определил все переменные. Как я не использовал jQuery, я гарантировал, что я запечатлел все мои элементы, используя Document.QuerySelector .
let countdown = 0; // variable to set/clear intervalslet seconds = 1500; // seconds left on the clocklet workTime = 25;let breakTime = 5;let isBreak = true;let isPaused = true;
const status = document.querySelector("#status");const timerDisplay = document.querySelector(".timerDisplay");const startBtn = document.querySelector("#start-btn");const resetBtn = document.querySelector("#reset");const workMin = document.querySelector("#work-min");const breakMin = document.querySelector("#break-min");Далее я создал аудиоэлемент.
const alarm = document.createElement('audio'); alarm.setAttribute("src", "https://www.soundjay.com/misc/sounds/bell-ringing-05.mp3");Когда кнопка «Пуск» нажат, интервал очищен. Новый интервал устанавливается, если ISPAZED изменения с правда к ложь Отказ
Кнопка «RESET» очищает интервал и сбрасывает переменные.
startBtn.addEventListener('click', () => { clearInterval(countdown); isPaused = !isPaused; if (!isPaused) { countdown = setInterval(timer, 1000); }})resetBtn.addEventListener('click', () => { clearInterval(countdown); seconds = workTime * 60; countdown = 0; isPaused = true; isBreak = true;})Функция таймера где происходит магия обратного отсчета. Это вычитает одну секунду из секунды . Если секунд < ; 0, сигнал тревоги воспроизводится, и функция определяет, должен ли следующий обратный отсчет должен быть рабочей сессией или сеансом разбивания.
function timer() { seconds --; if (seconds < 0) { clearInterval(countdown); alarm.currentTime = 0; alarm.play(); seconds = (isBreak ? breakTime : workTime) * 60; isBreak = !isBreak; }}Теперь пришло время работать на кнопках +/- для работы и разрыва. Первоначально я создал OnClick Функция для каждой кнопки. Хотя было функционально, был определенно комната для улучшения.
document.querySelector("#work-plus").onclick = function() { workDuration < 60 ? workDuration += increment : workDuration; }document.querySelector("#work-minus").onclick = function() { workDuration > 5 ? workDuration -= increment : workDuration; }document.querySelector("#break-plus").onclick = function() { breakDuration < 60 ? breakDuration += increment : breakDuration; }document.querySelector("#break-minus").onclick = function() { breakDuration > 5 ? breakDuration -= increment : breakDuration; }Тот же родимый реддитор предложил, чтобы я использовал ассоциативный массив , который по существу является набором пар ключевых ценностей.
let incrementFunctions = {"#work-plus": function () { workTime = Math.min(workTime + increment, 60)}, "#work-minus": function () { workTime = Math.max(workTime - increment, 5)}, "#break-plus": function () { breakTime = Math.min(breakTime + increment, 60)}, "#break-minus": function () { breakTime = Math.max(breakTime - increment, 5)}};for (var key in incrementFunctions) { if (incrementFunctions.hasOwnProperty(key)) { document.querySelector(key).onclick = incrementFunctions[key]; }}Пришло время обновить HTML!
Я создал функции, чтобы обновить дисплей отсчета и дисплей кнопки, и включить те функции в всеобъемлющую функцию, которая также обновила состояние работы/разрыва и продолжительностью.
Наконец я использовал document.onclick Чтобы запустить UpdateHtml Функция Каждый раз, когда пользователь нажимает на странице. Я также использовал Window.SetIntererval Чтобы запустить функцию 10 раз в секунду для хорошей меры.
function countdownDisplay() { let minutes = Math.floor(seconds / 60); let remainderSeconds = seconds % 60; timerDisplay.textContent = `${minutes}:${remainderSeconds < 10 ? '0' : ''}${remainderSeconds}`;}function buttonDisplay() { if (isPaused && countdown === 0) { startBtn.textContent = "START"; } else if (isPaused && countdown !== 0) { startBtn.textContent = "Continue"; } else { startBtn.textContent = "Pause"; }}function updateHTML() { countdownDisplay(); buttonDisplay(); isBreak ? status.textContent = "Keep Working" : status.textContent = "Take a Break!"; workMin.textContent = workTime; breakMin.textContent = breakTime;}window.setInterval(updateHTML, 100);
document.onclick = updateHTML;
И это завершение моего проекта!
Вы можете просмотреть мой последний проект здесь Отказ
Последние мысли
Моя самая большая вынос от этого проекта заключается в том, что я должен стремиться к простоте с точки зрения дизайна кода, потому что это предпосылка для надежности. Это сделает мой код простой для понимания, легко отладки и легко обновлять.
Я также напомнил о преимуществах парных программирования и кода отзывы, особенно когда один новый для кодирования.
Есть еще так много, чтобы учиться. Но на данный момент позвольте мне вознаградить себя тарелкой пасты Аль-Помодоро.
Оригинал: “https://www.freecodecamp.org/news/how-i-built-my-pomodoro-clock-app-and-the-lessons-i-learned-along-the-way-51288983f5ee/”