Banner z obietnicami

Jeżeli należysz do naszego klubu superbohaterów, musisz go chwalebnie reprezentować. Powinieneś byś silny, wytrwały i nieugięty, jak każdy superbohater. Tak przynajmniej może się wydawać. Prawda jest jednak taka, że nawet najlepsi z nas czasami potrzebują wsparcia. Szczególnie ostatnie lata, lockdown, inflacja i wiele podobnych rzeczy każdego z nas może przemielić jak maszynka do mięsa.

Czy wiesz, że w obecnych czasach co piąte dziecko ma problemy psychiczne, a w naszym kraju mężczyźni znajdują się czołówce samobójstw w Europie? Można by tak wymieniać i wymieniać. Czasy nie są za miłe, a my nie jesteśmy niezniszczalni.

Gdzieś w początkowych rozdziałach wspomniałem tobie o pewnej najważniejszej rzeczy. Dalej jestem zdania, że jest to rzecz najważniejsza w programowaniu. Ale jak to mówi przysłowie - "w zdrowym ciele zdrowy duch". Ale i bez zdrowego ducha ciało nie może być zdrowe. I w tym miejscu wkraczają współtowarzysze superbohaterów - trenerzy, dietetycy ale i psychoterapeuci. Wszyscy oni będą mieli coraz więcej do zrobienia.


W poniższym tekście zajmiemy się stworzeniem przykładowego baneru. Osobiście nie jestem jakimś ekspertem od reklamy. Ale... Ostatnimi czasy coraz częściej męczę AI o różne tematy, tak i tym razem pogadałem sobie z nią o powyższych problemach. To z kolei wydało mi się ciekawym pomysłem na stworzenie naszego dzieła.

W każdym razie będziemy tworzyć takie cacko:

Magdalena RatajczykPsychoterapeuta, pedagogdzisiaj czytałem ze ponoć 20% młodzieży ma problemy depresyjne

Banner jest prezentacją oryginalnej rozmowy, jaką odbyłem z ChatGPT. Żeby ją przedstawić, będziemy potrzebowali kilku "klocków", z których zbudujemy banner. Po pierwsze przyda nam się mechanizm, który będzie służył do wypisywania tekstów litera po literze. Po drugie musimy zaanimować przejścia między kolejnymi wypowiedziami - tu zastopować, tam płynnie przejść itp.

Naszą pracę podzielmy na kilka punktów:

  1. napisanie klasy do wypisywania tekstów

  2. dodatkowe funkcje do animacji i spowalniania

  3. realne odpytywanie AI?

Klasa TypeWriter

Naszą pracę rozpoczniemy od stworzenia klasy TypeWriter.

Zasada działania naszej maszyny piszącej będzie całkiem prosta. Całe pisanie będzie składało się z wykonywanych po sobie kolejnych akcji, które za pomocą funkcji będziemy odkładać do osobnej tablicy.

export class TypeMachine {
    #actions = []; //tablica akcji
    #text = ''; //tekst który aktualnie wypisujemy
    #count = 0; //dodatkowa zmienna - przyda się do liczenia którą literę wypisujemy

    constructor() {
        //na razie pusty
    }
}

Wszystkie powyższe zmienne dzięki poprzedzeniu je znakiem # stworzyliśmy jako prywatne. W konstruktorze tworzymy opcje naszej maszyny - działanie takie samo jak w innych naszych projektach.

Funkcja write

Jak u Hitchcocka. Zaczynamy od najcięższej rzeczy czyli funkcji write().

Każda odkładana akcja będzie obietnicą na której wykonanie spokojnie poczekamy.

Po pierwsze dokładamy tekst, który za chwilę za pomocą funkcji typeText() i interwału będziemy wypisywać.

Tekst wypisywany będzie za każdym razem od jego początku do zmiennej #count, którą zwiększamy w interwale. Przykładowo:

Jeżeli ktoś odpali naszą funkcję z czasem 0, cały przekazany w parametrze tekst od razu wypiszemy dodając do zmiennej #count jego długość. Przyda to się, jeżeli w wypisywanym tekście będziemy chcieli zmienić wygląd za pomocą html.

Tak to będzie działać. Na koniec funkcji zwracamy this czyli samego siebie. Dzięki temu wszystkie funkcje będziemy mogli łączyć w łańcuch tak samo jak w przypadku innych metod dla innych obiektów:

Funkcja typeText

Kolejną metodą, którą napiszemy będzie prywatna funkcja typeText(). Posłuży ona do wypisywania samego tekst. Nasz tekst może być wypisywany w różnych miejscach. Czasami będziemy chcieli wypisać go w konsoli debuggera, a innym razem w kilku częściach baneru na stronie. Nie możemy więc tego zakodować na sztywno. Zamiast tego użyjemy funkcji zwrotnej, którą przekażemy do konstruktora:

Dzięki temu odpowiedni kod przekażemy przy tworzeniu pojedynczej instancji naszej maszyny:

Funkcja pause

Jak przypatrzysz się rozmowie z banera, wypisywanie tekstu nie jest jednolite. W pierwszej wypowiedzi zawahałem się (pauza), wprowadziłem korektę (usunięcie kilku liter), znowu zawahałem się, po czym pisałem dalej.

Zacznijmy od funkcji dodającej możliwość zaczekania z pisaniem kolejnych liter:

Funkcja back

Żeby zasymulować kasowanie tekstu, musimy cofnąć się ze zmienną #count. Posłuży do tego funkcja back():

Funkcja wymaga podania liczby znaków do cofnięcia. Jeżeli zamiast liczby podamy -1, wtedy zacznie kasować wszystkie litery aż do początku.

Możemy też stworzyć dodatkową funkcję pomocniczą, która posłuży do kasowania całego tekstu:

Funkcja runFn

Kolejną funkcją, która nam się przyda, będzie ta, która posłuży do odpalania naszego "customowego" kodu. Podczas pisania tekstu możesz chcieć w pewnej chwili odpalać dodatkowe funkcje - np. podczas cofania kursora może się dodawać jakaś dodatkowa klasa, albo zmieniać tło. Posłuż do tego funkcja runFn():

Funkcja start

Ostatnią funkcją będzie start(), która posłuży do wystartowania całego pisania.

Nasza klasa jest gotowa :). Przykładowe jej użycie może mieć postać:

Animowanie dymków rozmowy

Pierwszy krok mamy załatwiony. Przejdźmy więc do kolejnych, czyli animowania całej rozmowy.

Zacznijmy od pobrania odpowiednich elementów i utworzenia podstawowych zmiennych:

Nasza rozmowa składa się z 4 dymków, które mieszczą się w elemencie .banner-inner. Pokażmy pierwszy dymek, po czym użyjmy w nim naszej piszącej maszyny. Do pokazania dymku moglibyśmy użyć biblioteki GreenSock, która nie tylko ma praktycznie nieograniczone możliwości animacji, ale i jest bajecznie prosta w użyciu:

Mega wygodna sprawa (polecam!)...

W naszym przypadku jednak chcemy tylko animować zwykłe opacity. Możemy to zrobić samym CSS i dodaniem odpowiedniej klasy dla elementu. Ja skorzystam tutaj z metody animate.

Trochę więcej kodu, ale mniej do ściągnięcia danych przez użytkownika. Będziemy chcieli pokazywać resztę dymków, dlatego kod odpowiedzialny za animację wynieśmy do osobnej funkcji:

Po pokazaniu dymka, chcemy chwilkę odczekać zanim tekst zacznie się pisać, dzięki czemu efekt będzie bardziej realny. Napiszmy dodatkową funkcję służącą do opóźniania dalszego kodu:.

A następnie dodajmy samo pisanie tekstu korzystając z naszej klasy:

Drugim dymkiem będzie odpowiedź ChatGPT. Żeby to zasygnalizować, dodamy do dymku dodatkową klasę .is-wait, która za pomocą odpowiedniego stylowania stworzy dodatkowy element ::before, który będzie symulował mrugający kursor:

Pozostaje napisać funkcję pokazującą drugi dymek:

i podobnie pozostałe dwa dymki:

Demo masz na początku strony...

Jedyną rzeczą, którą w nim dodałem, do odpalanie całej animacji w momencie, gdy baner zacznie wjeżdżać na ekran.

Bonus - odpowiedzi z ChatGPT

W powyższym kodzie teksty były wpisane na sztywno (ale wiedz, że to są praktycznie oryginalne teksty).

W ramach testu możemy pokusić się o użycie na naszym banerze realnych odpowiedzi, które uzyskamy bezpośrednio od ChatGPT.

Po pierwsze musisz wejść na stronę https://platform.openai.com/docs/api-reference i w prawym górnym rogu się zarejestrować. Po zarejestrowaniu znowu na tej same stronie przy twoim awatarze (prawy górny róg) otwórz menu i z opcji wybierz "View API keys". Wygeneruj nowy klucz. Będziesz musiał go użyć przy połączeniu z API.

Połączenie zrobimy za pomocą zwykłego fetch według opisu ze strony api. W naszym przypadku musimy zmienić tylko funkcje, gdzie odpowiada AI.

Czy to się nadaje na realny baner? Nie za bardzo. Poniżej nagrałem ci film z pierwszego lepszego testu. Ogólnie jest nieźle, ale w poniższym przypadku dostałem odpowiedzi po polsku, po 3 próbie część przyszła po angielsku. Podejrzewam, że trzeba by się przyjrzeć parametrom, które udostępnia api. Ważniejsze jednak jest to, skąd mam wiedzieć, w jakim humorze AI będzie za kilka dni?. A jeżeli zacznie wrzucać ludzkości? Wtedy akurat najlepiej zacząć przenosić swoje kodowanie do schronu, no ale i nasz baner by ucierpiał...

Last updated