Како сам направио своју апликацију Помодоро Цлоцк и лекције које сам научио успут

Кренуо сам на своје бесплатно путовање у ЦодеЦамп у децембру 2017. године и плашим се два пројекта попуњавања Фронт-Енд развојног сертификата. Овај пост документује мој процес завршетка пројекта Помодоро Цлоцк.

Шта је Помодоро сат?

Помодоро техника је оквир управљања временом који је једноставан колико и ефикасан - користите тајмер да бисте свој рад разломили на временске блокове (обично 25 минута), одвојене паузом од 5 минута. После свака 4 помодороса можете направити дужу паузу.

Морао сам да испуним следеће корисничке приче:

  • Могу започети помодоро од 25 минута, а тајмер ће се искључити након што протекне 25 минута.
  • Могу да ресетујем сат за мој следећи помодоро.
  • Могу да прилагодим дужину сваког помодора.

Дизајн / изглед

Мој принцип дизајна је да кориснички интерфејс буде чист и једноставан. Свидела ми се идеја да парадајз користим као тајмер. Постоји приказ рада / прекида, одбројавање тајмера и дугме за репродукцију / паузу.

Испод тајмера имао сам подешавања за модификовање рада и трајања паузе и дугме за ресетовање.

Проблеми са изгледом на које сам наишао

Имао сам великих проблема са постављањем слике парадајза у позадину испод осталих елемената. Како бих волео да постоји опција распореда коју бих могао да одаберем! ?

Један предлог који сам пронашао је да слику парадајза сачувам на жељеној боји позадине као нову слику, а затим користим ту слику у позадини. Лоша страна тога је што је почео изгледати несигурно када сам тестирао одзив изгледа.

На крају сам успео да то исправим комбинацијом 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%);}

Доња подешавања су била прилично једноставна. Користила сам ЦСС мрежу да бих одвојила компоненте у три колоне, при чему је средња колона била половина ширине спољних колона.

.settings { margin: auto; width: 80%; display: grid; grid-template-columns: 2fr 1fr 2fr; align-items: center;}

Још једном сам transformпомерао дугме за ресетовање ради бољег поравнања.

Структурирање мог кода - и онда његово кидање

Корисно ми је да дођем до своје структуре кода ако разбијем захтеве:

  • Тајмер ће се пребацивати између покретања и паузирања када кликнем на дугме „старт“.
  • Кад тајмер достигне нулу, аларм ће се огласити.
  • Радну сесију увек прати пауза.
  • Трајање рада и прекида може се изменити.
  • Дугме „ресетовање“ ће (погађате) ресетовати тајмер.

Претходно сам завршио сат одбројавања на курсу Вес Бос ЈаваСцрипт30, тако да сам знао да могу да користим setIntervalметоду. Такође сам одлучио да изазовем себе држећи се ванилин ЈаваСцрипт-а и избегавам ослањање на јКуери.

И тако сам почео да пишем свој ЈаваСцрипт код. Иако сам успео да створим функционалан помодоро сат, овде нећу проћи кроз прву верзију свог кода. То је зато што сам направио значајне промене у њему након што сам добио конструктивне повратне информације од невероватног незнанца на Реддиту. ?

Да, лепе ствари се дешавају на Реддиту!

Главне тачке повратних информација биле су:

  • setInterval(timer, 1000)за покретање је потребно најмање 1000 мс, али може потрајати и дуже. Дакле, требало би да проверите колико је времена заиста протекло, или ваш сат може бити нетачан.
  • Групирајте сва ХТМЛ ажурирања у један одељак, јер ово олакшава ажурирање и отклањање грешака у вашем коду.
  • Генерално је добра идеја направити код, а да уопште не размишљате о представљању.
  • Будите сигурни у логику тајмера и отарасите се непотребног кода.
  • Уверите се да су називи променљивих описни. Оставите коментаре када је потребно.

Можете погледати мој први урезивање на ГитХуб-у.

Рефакторизирање мог кода

Након што сам добио све те драгоцене повратне информације, неколико пута сам преправљао свој код док нисам био задовољан њиме.

Прво сам дефинисао све променљиве. Како нисам користио јКуери, осигурао сам да сам снимио све своје елементе користећи 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", "//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 timer function is where the countdown magic happens. It deducts one second from seconds. If seconds <; 0, the alarm is played, and the function determines if the next countdown should be a work session or break session.

function timer() { seconds --; if (seconds < 0) { clearInterval(countdown); alarm.currentTime = 0; alarm.play(); seconds = (isBreak ? breakTime : workTime) * 60; isBreak = !isBreak; }}

Now it’s time to work on the +/- buttons for the work and break durations. Initially, I created an onclick function for every button. While it was functional, there was definitely room for improvement.

document.querySelector("#work-plus").onclick = function() { workDuration  5 ? workDuration -= increment : workDuration; }document.querySelector("#break-plus").onclick = function() { breakDuration  5 ? breakDuration -= increment : breakDuration; }

That same kind Redditor suggested that I use an associative array, which is essentially a set of key value pairs.

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

It’s time to update the HTML!

I created functions to update the countdown display and button display, and incorporated those functions into an overarching function that also updated the Work/Break status and durations.

На крају, document.onclickпокренуо сам функцију упдатеХТМЛ сваки пут када корисник кликне на страницу. Такође сам користио 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;

И то је завршетак мог пројекта!

Мој коначни пројекат можете погледати овде.

Последње мисли

Моје највеће повлачење из овог пројекта је да бих требао тежити једноставности у погледу дизајна кода, јер је то предуслов за поузданост. То ће мој код учинити лако разумљивим, лако отклонити грешке и лако га ажурирати.

Такође ме подсећају на предности упареног програмирања и прегледа кодова, посебно када је кодирање ново.

Има још толико тога да се научи. Али за сада, дозволите ми да се наградим тањиром Паста ал помодоро.