First steps with JavaScript [PL] PART3

W Szczebrzeszynie chrząszcz brzmi w trzcinie! Takie cudo zaserwowałem moim zagranicznymi kolegom, czy było warto?

Jestem obecnie kursantem na udemy.com i bardzo intensywnie podszedłem do tematu. Cały swój wolny czas poświęcam temu aby albo jak najlepiej zrozumieć zakładane treści albo próbować rzeźbić samemu dodatkowe projekty. I tak właśnie powstały kiszki-kiszki.pl. Będzie to moja strona, na której podzielę się z Wami i z szerszą publicznością moimi małymi projektami w JavaScript.

Dlaczego zdecydowałem się na oddzielny kanał komunikacji w sieci? Dlatego, że technicznie rzecz biorąc WordPressa chcę zostawić w spokoju. Ciężko mi sobie wyobrazić pobranie go do mojego IDE (korzystam tymczasem z Webstorm) i edycję bloga bezpośrednio na komputerze, łącznie z dodawaniem podstron, plików CSS i innych. Czuję instynktownie, że mogłoby się to po prostu nieźle posypać. Nie biorę go na siebie, bo nie jest to mój priorytet. Zaglądajcie proszę na kiszki-kiszki.pl, obiecuję że będzie się działo. Zajrzeli tam też moi koledzy i koleżanki z kursu na udemy.com, dostałem bardzo pozytywny feedback, który mocno motywuje do pójścia dalej. Chociaż nie wiem czy ktokolwiek z nich jest w stanie przeczytać ‘W Szczebrzeszczcyniea…”- pewnie mniej więcej na tym momencie zakończyli by z kretesem historię!

W poprzednim wpisie zaprosiłem Was do zagrania w grę Color Game, dzięki której możemy poćwiczyć swój zmysł łączenia ze sobą podstawowych barw. Szczerze muszę powiedzieć, że 80% idei projektu pochodziło z treści wspomnianego kursu na udemy.com. Choć kto teraz nie korzysta z gotowych rozwiązań? Natchniony tą myślą spędziłem dziś prawie cały dzień na edycji tego rozwiązania i stworzenie nowej gry: zgadywania czcionek Google Fonts.

Gra jest zupełnie prosta, choć jeśli nie jesteś developerem lub grafikiem to na niewiele Ci się zda- kto by zapamiętał przecież jak wygląda ponad 900 czcionek??

Mi natomiast w całym ćwiczeniu przesłaniała oczy i dumę jedna rzecz- na bazie wiedzy z Color Game muszę stworzyć coś swojego. Zakładałem, że należy zmienić tak dużo, żeby nie było podejrzeń o to, że ‘silnik’ rozwiązania jest po prostu taki sam. I faktycznie nie jest, uff ile było z tym roboty (dla doświadczonego developera pewnie 30 min).

Dziś chciałbym wysokopoziomowo podzielić się z Tobą tym, co udało mi się zrobić w ciągu zaledwie 1 dnia. Do tego czasu oczywiście należy dodać wszystkie możliwe czynności administracyjne z postawieniem IDE, połączeniem z serwerem, skorzystaniem i zaadoptowaniem templejtu graficznego nowej strony z moim Portfolio. Miałem z tym dużo frajdy, muszę przyznać.

Zobacz jak wygląda całość mojego rozwiązania tutaj.

Plan działania, które doprowadziło mnie do mojego rozwiązania podzieliłbym na kilka części:

  • stworzenie HTML ze strukturą projektu, odpowiednimi komponentami,
  • stworzenie silnika liczącego w JavaScript,
  • stworzenie CSS, za pomocą którego dodałem kolorki, wygląd i wszystkie potrzebne classy, za pomocą których JavaScript steruje stroną,
  • refaktoryzacja kodu- tego jeszcze nie zrobiłem. Dlaczego? Wydaję mi się, że nie powinno się robić tego na raz. Chciałbym znaleźć w pierwszej kolejności jak najwięcej problemów z aplikacją a dopiero potem refaktoryzować kod.

Poniżej prezentuję Ci strukturę HTML, którą użyłem aby przedstawić Ci moją grę:

<div class=”row h-100 align-items-center justify-content-center text-center”>
    <!–<div class=”col-lg-10 align-self-end”>
        <h1 class=”text-uppercase text-white font-weight-bold”>Here you can find my projects</h1>
        <hr class=”divider my-4″>
    </div>–>
    <div class=”col-lg-8 align-self-baseline”>
        <!–put game here–>
        <h2>PICK THE RIGHT GOOGLE FONT<br>
            <span id=”fontDisplay”></span>
        </h2>
        <div id=”menu” class=”squareContainer col-lg-12 align-self-baseline”>
            <button id=”restart”>New Fonts</button>
            <button id=”easyMode”>Easy mode</button>
            <button id=”hardMode” class=”selected”>Hard mode</button>
        </div>
    </div>


    <div class=”squareContainer col-lg-8 align-self-baseline”>
        <div class=”fontSquare col-lg-4 col-sm-6″>W Szczebrzeszynie chrzaszcz brzmi w trzcinie.
        </div>
        <div class=”fontSquare col-lg-4 col-sm-6″>W Szczebrzeszynie chrzaszcz brzmi w trzcinie.
        </div>
        <div class=”fontSquare col-lg-4 col-sm-6″>W Szczebrzeszynie chrzaszcz brzmi w trzcinie.
        </div>
    </div>
    <div class=”squareContainer col-lg-8 align-self-baseline”>
        <div class=”fontSquare col-lg-4 col-sm-6″>W Szczebrzeszynie chrzaszcz brzmi w trzcinie.
        </div>
        <div class=”fontSquare col-lg-4 col-sm-6″>W Szczebrzeszynie chrzaszcz brzmi w trzcinie.
        </div>
        <div class=”fontSquare col-lg-4 col-sm-6″>W Szczebrzeszynie chrzaszcz brzmi w trzcinie.
        </div>
    </div>
</div>

Co jest najważniejsze w powyższym kodzie?

  • id=”fontDisplay” – jest to miejsce, w którym wyświetlana będzie nazwa czcionki, którą użytkownik ma zgadnąć,
  • id=”restart”– jest to przycisk, za pomocą którego podczas rozgrywki użytkownik będzie mógł ponownie wylosować czcionkę do wyboru oraz przycisk za pomocą którego rozpocznie rozgrywkę w przypadku zakończenia jej sukcesem,
  • “easyMode” – jest to przycisk, za pomocą którego każdy gracz będzie mógł obniżyć poziom trudności i z 6 opcji do odgadnięcia pozostanie mu tylko 3,
  • “hardMode”– domyślną liczbą kafelków do zgadnięcia jest 6. Gdy użytkownik wybierze przyciskiem tylko 3 kafelki, przyski hardMode pozwoli powrócić do trudniejszej rozgrywki,
  • fontSquare (występujący sześc razy)- jest to div, w którym wszystko się dzieję- czyli miejsce, w którym zapisany tekst “W Szczebrzeszynie chrzaszcz brzmi w trzcinie.” jest wyświetlany w randomowej czcionce. Jeden z nich pasuje do “fontDisplay” i w przypadku, gdyż użytkownik kliknie na ten właściwy rozgrywka się kończy i wszystkie kafelki zmieniają swój kolor na zielony z napisem Passed w czcionce zgodnej z “fontDisplay”.

Aby zapewnić właściwe działanie aplikacji, potrzebny jest poniższy kod logiczny JavaScript:

/*Tablica ze wszystkimi czcionkami Google Fonts */
fonts = [
    “‘Roboto’, sans-serif”,
];

/*Założenia do aplikacji oraz zaznaczenie wskazanych w strukturze HTML elementów*/
let squareNumber = 6;
let squareFonts = squareRandomFonts(squareNumber);
let squares = document.querySelectorAll(“.fontSquare”);
let pickedFont = pickRandomFont();
let fontDisplay = document.getElementById(“fontDisplay”);
fontDisplay.textContent = pickedFont.toUpperCase();
let h2 = document.querySelector(“h2”);
let restart = document.getElementById(“restart”);

/*Rozpoczęcie Gry*/
game();

/*Dodanie obsługi przycisku easyMode*/
easyMode.addEventListener(“click”, function () {
    easyMode.classList.add(“selected”);
    hardMode.classList.remove(“selected”);
    squareNumber = 3;
    start();
    for (let i = 0; i < squares.length; i++) {
        if (squareFonts[i]) {
            squares[i].style.fontFamily = squareFonts[i];
            squares[i].style.display = “block”;
            squares[i].textContent = “W Szczebrzeszynie chrzaszcz brzmi w trzcinie.”;
            squares[i].classList.remove(“doneSquare”);
        } else {
            squares[i].style.display = “none”;
        }
    }
});

/*Dodanie obsługi przycisku hardMode*/
hardMode.addEventListener(“click”, function () {
    easyMode.classList.remove(“selected”);
    hardMode.classList.add(“selected”);
    squareNumber = 6;
    start();
    for (let i = 0; i < squares.length; i++) {
        squares[i].style.fontFamily = squareFonts[i];
        squares[i].style.display = “block”;
        squares[i].textContent = “W Szczebrzeszynie chrzaszcz brzmi w trzcinie.”;
        squares[i].classList.remove(“doneSquare”)
    }
});

/*Dodanie obsługi przycisku restart*/
restart.addEventListener(“click”, function () {
    start();
    for (let i = 0; i < squares.length; i++) {
        squares[i].style.fontFamily = squareFonts[i];
        squares[i].textContent = “W Szczebrzeszynie chrzaszcz brzmi w trzcinie.”;
        squares[i].classList.remove(“doneSquare”)
    }
    game();
});

/*Funkcja rozpoczynająca grę*/
function game() {
    for (let i = 0; i < squareFonts.length; i++) {
        squares[i].style.fontFamily = squareFonts[i];
        squares[i].addEventListener(“click”, function () {
            let clickedFont = this.style.fontFamily;
            if (clickedFont.toString().replace(/[ ,'”+]/g, “”).toUpperCase() === pickedFont.toString().replace(/[ ,'”+]/g, “”).toUpperCase()) {
                fontAllSquares(clickedFont);
                restart.textContent = “Play again?”;
                fontDisplay.style.fontFamily = clickedFont;
            } else {
                this.textContent = “Nope! It was: ” + this.style.fontFamily.replace(/”/g, “‘”);
                restart.textContent = “Pick new Fonts”;
            }
        })
    }
}

/*Potrzebne dodatkowe funkcje, za pomocą których dokonane zostały losowania*/

/*Funkcja wywołana po właściwym odgadnięciu Fontu*/

function fontAllSquares(font) {
    for (let i = 0; i < squares.length; i++) {
        squares[i].style.fontFamily = font;
        squares[i].textContent = “PASSED”;
        squares[i].classList.add(‘doneSquare’);

    }
}

/*Funkcja wybierająca jedną z wylosowanych randomowych czcionek */
function pickRandomFont() {
    let random = Math.floor(Math.random() * squareFonts.length);
    return squareFonts[random];
}


/*Funkcja tworząca tablicę losowych czcionek*/
function squareRandomFonts(number) {
    let arr = [];
    for (let i = 0; i < number; i++) {
        arr.push(randomFont());
    }
    return arr;
}

/*Funkcja wybierająca z tablicy fonts[] losową czcionkę*/

function randomFont() {
    return fonts[Math.floor(Math.random() * fonts.length)];
}

/*Funkcja start, w której upakowałem czynności potrzebne przy buttonach*/
function start() {
    fontDisplay.style.fontFamily = “\”Merriweather Sans\”, -apple-system, BlinkMacSystemFont, \”Segoe UI\”, Roboto, \”Helvetica Neue\”, Arial, \”Noto Sans\”, sans-serif, \”Apple Color Emoji\”, \”Segoe UI Emoji\”, \”Segoe UI Symbol\”, \”Noto Color Emoji\””;
    squareFonts = squareRandomFonts(squareNumber);
    pickedFont = pickRandomFont();
    fontDisplay.textContent = pickedFont;
    restart.textContent = “New fonts”.toUpperCase();
}

Co jest najważniejsze w powyższym kodzie? Przede wszystkim logika obsługi poszczególnych czynności na stronie- ciekawe ile by miała linijek w najbardziej optymalnym rozwiązaniu tego problemu- chyba muszę zrobić konkurs!

Jeżeli coś jest dla Ciebie niejasne, zapraszam do dyskusji w komentarzu.

Dodatkowo aby odpowiednio pokolorować rozwiązanie, dodałem rozwiązanie CSS, które odnosi się do powyższych elementów:

/Wygląd kafelków na początku gry/
.fontSquare {
width: 30%;
float: left;
border-radius: 15%;
transition: background-color 0.35s;
-webkit-transition: background-color 0.35s;
-moz-transition: background-color 0.35s;
text-align: center;
margin: 1% 1.66% 1.66%;
font-size: 22px;
padding: 1%;
max-height: 30%;
background-color: #232323;
color: ghostwhite;
}

/Wygląd kafelków po odgadnięciu przez użytkownika prawdiłowego Fontu/
.doneSquare{
width: 30%;
float: left;
border-radius: 15%;
transition: background-color 0.35s;
-webkit-transition: background-color 0.35s;
-moz-transition: background-color 0.35s;
text-align: center;
margin: 1% 1.66% 1.66%;
font-size: 22px;
padding: 1%;
max-height: 30%;
background-color: #60e568;
color: ghostwhite;
}

Cała powyższa kombinacja kodu zaszyta na mojej stronie kiszki-kiszki.pl doprowadziła mnie do finalnego rozwiązania i udostępnienia gotowej aplikacji. Dajcie znać co sądzicie w sekcji komentarzy.

Dodatkowo chciałbym Was poinformować, że jeżeli chcecie być na bieżąco i wesprzeć mój Blog, zapraszam Was do skorzystania z gotowej już opcji ‘Subscribe’. Będąc na mojej liście otrzymasz informacje o progresie rozwoju Bloga, a gdy tylko odkopię się z nauczania początków w tych technologiach, podzielę się z Wami konkretnymi, bezpłatnymi szkoleniami z przygotowania Waszej pierwszej działającej aplikacji. Uczcie się pilnie i do kolejnego napisania!

Spokojnego weekendu!

Michał Fedorczyk

Leave a Reply

Your email address will not be published. Required fields are marked *