Как я создал свое приложение Pomodoro Clock и какие уроки я усвоил на этом пути

kak ya sozdal svoe prilozhenie pomodoro clock i kakie uroki?v=1656641890

от Синтии Ли

0*NTDCi8iO84iyCE8U

Я начал свое путешествие freeCodeCamp в декабре 2017 года и мне не хватает двух проектов, чтобы получить сертификат Front-End Development. Эта публикация документирует мой процесс завершения проекта Pomodoro Clock.

Что такое часы Pomodoro?

Техника Pomodoro – это система управления временем, которая так же проста, как и эффективна: вы используете таймер, чтобы разбить свою работу на временные блоки (обычно по 25 минут), разделенные 5-минутным перерывом. После каждые 4 помодоров можно сделать больший перерыв.

Мне пришлось выполнить следующие истории пользователей:

  • Я могу запустить 25-минутный помодор, и таймер выключится, когда пройдет 25 минут.
  • Я могу сбросить часы для своего следующего помодора.
  • Я могу настроить длину каждого помодора.

Дизайн / верстка

1*usZAFrV70goblyvT6zfFcA

Мой принцип дизайна состоит в том, чтобы пользовательский интерфейс был чистым и простым. Мне понравилась идея использовать помидор в качестве таймера. Имеется дисплей работы/перерыва, обратный отсчет таймера и кнопка воспроизведения/паузы.

Под таймером у меня была настройка для изменения продолжительности работы и перерыва, а также кнопка сброса.

Проблемы с макетом, с которыми я столкнулся

У меня возникли большие проблемы с размещением помидора на фоне под другими элементами. Как бы я хотел, чтобы был вариант макета, который я мог бы выбрать! ?

1*ANAEwK4kQz5UaGlDIGBW1A
Старые добрые параметры компоновки изображений Microsoft Word

Одно из предложений, которое я нашел, заключалось в том, чтобы сохранить изображение помидора на желаемом цвете фона как новое изображение, а затем использовать это изображение в фоновом режиме. Недостатком этого было то, что он стал выглядеть шатким, когда я проверил чувствительность макета.

В конце концов мне удалось правильно совместить absolute positioningменяя top и left проценты, и transform.

#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;}

Еще раз воспользовался transform чтобы переместить кнопку сброса для лучшего выравнивания.

1*g8a8NTOJi_tkSlmLzCckWA

Структурирую мой код, а затем разрываю его на части

Я считаю полезным придумать структуру своего кода, если я разбив требования:

  • Таймер будет переключаться между запуском и паузой при нажатии кнопки «Пуск».
  • Когда таймер достигнет нуля, сработает сигнал.
  • После рабочего сеанса всегда идет перерыв.
  • Продолжительность работы и перерывы можно изменять.
  • Кнопка «сбросить» (как вы догадались) сбросит таймер.

Раньше я закончил часы обратного отсчета на курсе Wes Bos JavaScript30, поэтому я знал, что могу использовать setInterval метод. Я также решил испытать себя, соблюдая ванильный JavaScript и не полагаясь на jQuery.

И потому я начал писать свой код JavaScript. Хотя мне удалось создать функциональные часы pomodoro, я не буду рассматривать первую версию своего кода здесь. Это потому, что я внес в него значительные изменения после получения конструктивного отклика от чудесного незнакомца Reddit. ?

Да, на Reddit попадаются приятные вещи!

Основными моментами отклика были:

  • setInterval(timer, 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");

После нажатия кнопки «Пуск» интервал очищается. Новый интервал устанавливается, если isPaused изменения от правда к ошибочный.

Кнопка «сбросить» очищает интервал и сбрасывает переменные.

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;})

The функция таймера здесь происходит магия обратного отсчета. Из него вычитается одна секунда секунд. Если секунд; 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;                  }

Тот же Redditor предложил мне использовать ассоциативный массив, который, по сути, является набором пар ключ-значения.

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.setInterval запускать функцию 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;

И это результат моего проекта!

Вы можете просмотреть мой окончательный проект здесь.

Последние мнения

Мой наибольший вывод из этого проекта заключается в том, что я должен стремиться к простоте с точки зрения дизайна кода, поскольку это предпосылка для надежности. Это сделает мой код легким для понимания, легкой настройки и легкого обновления.

Мне также напоминают о преимуществах парного программирования и просмотра кода, особенно если вы новичок в программировании.

Надо еще многому научиться. Но пока позвольте мне вознаградить себя тарелкой Pasta al pomodoro.

0*OnSu8IZp3yv85Qe_
Фото OLA Мищенко на Unsplash

Добавить комментарий

Ваш адрес email не будет опубликован.