Carousel Card

User avatar Bartosz Palewicz

Carousel card

W tym artykule przedstawię krok po kroku jak samemu zrobić stosunkowo prostą, responsywną, przewijaną kartę, przy wykorzystaniu Bootstrapa, CSS'a i odrobiny jQuery.

Pierwszym krokiem będzie pobranie i rozpakowanie paczki MDBootsrap. Gdy już to zrobicie, waszym oczom ukaże się wiele plików, ale nas interesować będą tylko trzy z nich:

  • index.html
  • css/style.css
  • js/script.js (ten plik musicie stworzyć sami)

Następnie w pliku index.html usuwamy wszystko, co znajduje się pomiędzy komentarzami Start your project here - tam będzie mieścił się nasz kod.

Dla lepszego przedstawienia zamknijmy naszą kartę w containerze, pozwoli to nam określić jej wielkość położenie itp. W tym celu wpiszmy do HTML następujący kod:

<!-- Start your project here-->
<div class="container mt-5 col-12 col-md-8 p-0">
</div>
<!-- Start your project here-->

Do naszego containera dodaliśmy kilka klas w celu zapewnienia responsywności:

  • container określa, że jest to container
  • col-12 na małych ekranach zajmuje całą szerokość
  • col-md-8 na ekranach większych niż 768 pixeli zajmuje tylko 8/12 szerokości

Następnie stwórzmy już naszą właściwą kartę i nadajmy jej klasy, które pomogą nam zdefiniować jej właściwości bez potrzeby pisania ich w CSS.

<!-- Start your project here-->
<div class="container mt-5 col-12 col-md-8 p-0">
<div class="card carousel-card d-flex m-5 flex-column flex-lg-row">

</div>
</div>
<!-- Start your project here-->

  • card nasz div przybierze standarowy wygląd bootstrapowej karty
  • carousel-card ta klasa przyda nam się później przy CSS
  • d-flex określimy tym właściwość display i ustalimy ją na flex, co pozwoli nam na łatwiejsze ustawienie elementów w naszej karcie
  • m-5 ustala odpowiednie marginesy aby nasza karta zachowywała odstęp od innych elementów na stronie
  • flex-column dzięki tej klasie obiekty w środku naszego diva wyświetlane będą jeden pod drugim
  • flex-lg-row ta klasa nada naszej karcie responsywności i przy większych ekranach (minimum 992px) obiekty w divie będą wyświetane jeden obok drugiego

Naszą kartę podzielimy na 2 części, lewą zawierającą obrazek i prawą zawierającą tekst. W tym celu utworzymy sobie 2 kolejne divy i nadamy im odpowiednie klasy.

Lewa strona

Zacznijmy od strony lewej, która będzie mniej skomplikowana, bo jedyne, co musimy zrobić, to wejść na dokumentację i przekleić karuzelę zdjęć.

Link do dokumentacji

Kopiujemy pierwszy przykład i wklejamy go do naszej karty.

<!-- Start your project here-->
<div class="container mt-5 col-12 col-md-8 p-0">
<div class="card carousel-card d-flex m-5 flex-column flex-lg-row">
<div id="carouselExampleSlidesOnly" class="carousel slide carousel-card-image" data-ride="carousel" data-interval="false">
<div class="carousel-inner">
<div class="carousel-item active">
  <img class="d-block w-100" src="https://i.ibb.co/wsgXZ8N/game-cartridges-1373100-1.jpg">
</div>
<div class="carousel-item">
  <img class="d-block w-100" src="https://i.ibb.co/vDHfqwq/technology-computer-lines-board-50711.jpg">
</div>
<div class="carousel-item">
  <img class="d-block w-100" src="https://i.ibb.co/FBwHfry/person-playing-chess-1040157.jpg">
</div>
</div>
</div>
</div>
</div>
<!-- Start your project here-->

Jak już pewnie zdążyliście zauważyć - dodałem do naszej karuzeli klasę .carousel-card-image. Pozwoli nam ona na późniejsze dostosowanie naszej karuzeli w CSS.

Dodałem również atrybut data-interval="false", który sprawi, że zdjęcia nie będą przewijały się samoczynnie. Bez obaw - ta funkcja będzie dostępna, ale zrobimy ją po swojemu.

Prawa strona

Stwórzmy więc diva, który będzie zawierał w sobie całą prawą stronę, tj. przyciski, którymi będziemy mogli kontrolować naszą karuzelę, loader, który będzie przełączał nam automatycznie karty, a także sam content w postaci tekstu oraz odnośnika. Nadajmy mu również klasę, dzięki której później bedziemy mogli się do niego odwołać i umieśćmy go poniżej wklejonej przez nas niedawno karuzeli.

<div class="carousel-right flex-column d-flex">

</div>

Teraz podzielmy sobie naszego nowo stworzonego diva na dwie części. W pierwszej będą mieścić się narzędzia kontrolne, czyli przyciski i loader, a w drugiej umieścimy tekst.

<div class="carousel-right flex-column d-flex">
<div class='d-flex flex-row justify-content-between p-3'>
<div class='carousel-contents card-body carousel slide pt-0' data-interval="false" data-ride="carousel">
    <div class="carousel-inner h-100">
        <div class="carousel-item h-100 active">
    </div>
        <div class="carousel-item h-100">
    </div>
        <div class="carousel-item h-100">
    </div>
</div>
</div>

Do pierwszego diva dodamy 3 klasy:

  • d-flex określimy tym właściwość display i ustalimy ją na flex, co pozwoli nam na łatwiejsze ustawienie elementów w naszej karcie
  • flex-row aby elementy wewnątrz diva układały się jeden za drugim
  • justify-content-between aby elementy wewnątrz umiejscowione były możliwie jak najbardziej od siebie
  • p-3 tą klasą nadamy marginesy wewnętrzne

Drugi div będzie jednocześnie karuzelą, taką jak nasze zdjęcia, więc znowu kopiujemy z dokumentacji tą samą karuzelę po czym dodajemy do niej odpowiednie klasy:

  • card-body ustali nam ospowiednie marginesy oraz wygląd tekstu

Usuwamy również wszystkie zdjęcia, gdyż na ich miejsce chcemy wstawić tekst i odnośnik.

Aby wszystko lepiej wyglądało podzielimy nasz tekst na tytuł i content, a poniżej umieścimy odnośnik i to powtarzammy w każdym z trzech slajdów.

<div class='h-100 d-flex flex-column justify-content-between'>
<div cless='flex-column  d-flex'>
    <h5 class='card-title d-inline'>Lorem</h5>
    <p class='card-text'> Lorem ipsum dolor sit, amet consectetur adipisicing elit. Sit modi solut
    corrupti magni sunt iste nulla.</p>
</div>
<a class="font-weight-bold" href="#">Buy now<i class="fas fa-angle-right ml-2"></i></a>
</div>

Teraz zajmiemy się przyciskami, za pomocą których będziemy mogli kontrolować naszą karuzelę. Do wcześniej pominiętej sekcji .controls dodajemy dwa divy, które podzielą nam miejsce na przyciski i spiner odliczający czas do zmienienia się slajdu, a następnie używając font awesome nadamy przyciskom postać przyjaznych dla oka strzałek.

<div class='controls d-flex p-3'>
<div class='control-buttons d-inline'>
    <a class="close next-btn" aria-label="next"><i class="fas fa-angle-right m-1"></i></a>
    <a class="close prev-btn" aria-label="prev"><i class="fas fa-angle-left m-1"></i></a>
</div>
<div class='control-loader'>

</div>
</div>

Część z loaderem zostawmy sobe na razie na później.

CSS

W naszym arkuszu stylów nie bedziemy musieli dużo pisać z racji tego, że większość właściwości zdefiniowaliśmy poprzez klasy w HTML.

Jedyne, co musimy zrobić, to nadać odpowiednie proporcje elementom w naszej karcie. Osobiście uważam, że najlepiej wygląda, gdy obraz zajmuje 2/3 karty, a tekst pozostałe 1/3. Wykorzystamy tu fakt, że nasza karta ma display:flex, co pozwoli nam użyć właściwości flex definiującej, jak dużo miejsca ma zajmować dany element.

.carousel-card-image{
flex:2;
}
.carousel-right{
flex:1;
}                          
                

JavaScript

Teraz możemy się zająć prawdopodobnie najtrudniejszą częścią naszego projektu, czyli skryptem, który zapiszemy w języku JavaScript, w pliku script.js, który wcześniej stworzyliśmy. Aby ułatwić sobie pracę użyjemy biblioteki jQuery.

W pierwszej kolejności stworzymy funkcję, która pozwoli nam na przewinięcie karuzeli w dowolnym kierunku z dowolnego obiektu znajdującego się w naszej karcie. W tym celu wykorzystamy metodę parents(), aby z dowolnego elementu naszej karty znaleźć kartę główną, do której on naeży, a następnie znajdziemy dzieci tej karty, które będą kolejno karuzelą ze zdjęciem oraz karuzelą z tekstem. Gdy już to zrobimy, metodą carousel() będziemy mogli przewijać karuzelę do przodu lub do tyłu.

function carouselSwitch(direction, obj){
$('.carousel',$(obj).parents('.carousel-card')).carousel(direction);
}
                

Jak możecie zauważyć funkcja przyjmuje 2 zmienne: direction przyjmuje wartość 'next' lub 'prev', która definiuje kierunek, w którym chcemy poruszyć naszą karuzelę, natomiast zmienna obj będzie przechowywała obiekt HTML, z którego wywołujemy tą funkcje (w większości przypadków będzie to this).

Teraz możemy dodać tzw. obserwatory zdarzeń na nasze przyciski. Aby to zrobić dopisujemy do naszego skryptu następujący kod:

$('.next-btn').click(function(){
carouselSwitch('next', this);
})
$('.prev-btn').click(function(){
carouselSwitch('prev', this);
})
                

Teraz, gdy wrócimy na naszą stronę, ujrzymy w pełni funkcjonalne przyciski. W sekcji controls pozostało nam jeszcze jedno puste miejsce, którym właśnie teraz się zajmiemy, umieszczając tam spiner zmieniający nam karty co określoną ilość czasu. Dobrze się składa, bo niedawno zrobiłem projekt loaderów, które przydają się właśnie do takich celów.

Po krótce opiszę jego sposób działania i wykorzystania w praktyce, abyście mogli posłużyć się tą wiedzą w przyszłych projektach. Spinner mojego autorstwa opiera się o narzędzie HTML'a 5 zwane canvas. Służy ono do 'rysowania' po naszym dokumencie za pomocą metod w JavaScript. Aby zaimplementować go do naszej strony, wpisujemy w diva z klasą .control-loader następujący kod:

<canvas class="loader" width="20px" height="20px" data-color='#999A9C' data-interval="6000"
data-repeat='1' data-function="carouselSwitch('next', this.c)"></canvas>
                                    

Postaram się wytłumaczyć teraz krok po kroku do czego służy każdy atrybut

  • width definiuje szerokość
  • height definiuje wysokość
  • data-color definiuje kolor spinnera
  • data-interval określa czas, jaki ma zająć spinnerowi zrobienie całego kółka
  • data-repeat określa, czy załadowanie ma być jednorazowe (dla 0) lub powtarzane w nieskończoność (dla 1)
  • data-function zawiera funkcję, która ma być wywołana za każdym okrążeniem

Funkcja zawarta w data-function wywołuje wcześniej stworzoną przez nas funkcję carouselSwitch(). Jako nasz drugi parametr podajemy tym razem this.c gdyż pod taką nazwą w skrypcie loadera znajduje się zmienna przechowująca obiekt HTML naszego canvasa.

Aby zainicjować nasz loader, wklejamy do skryptu następujący kod:

class Loader{
constructor(c){
    this.c=c;
    this.ctx = c.getContext("2d");
    this.time =  parseInt(c.dataset.interval);
    this.speed=20;
    this.t=0;
    this.lw = c.width/4
    this.l = setInterval(this.draw.bind(this), this.speed)
    
}
draw(){
    this.ctx.clearRect(0, 0, this.c.width, this.c.height)
    if(!$(this.c).hasClass('paused')){
    this.t+=this.speed;
    }
    if(this.t>this.time){
    if(this.c.dataset.repeat!='1' && this.c.dataset.repeat!='true'){clearInterval(this.l)}
    this.t=0;
    eval(this.c.dataset.function)
    }
    this.ctx.beginPath()
    this.ctx.arc(this.c.width/2, this.c.height/2, this.c.width/2-this.lw/2, 1.5*Math.PI, this.t/this.time*2*Math.PI+1.5*Math.PI)
    this.ctx.lineWidth=this.lw
    this.ctx.strokeStyle=this.c.dataset.color;
    this.ctx.stroke()
    this.ctx.closePath()
}
}
let loaders = $('.loader').toArray()
for(i in loaders){
new Loader(loaders[i])
}

Teraz nasza karta jest już niemal w pełni funkcjonalna, lecz jeszcze pod jednym aspektem można polepszyć jej działaie. Mianowicie gdy próbujemy przeczytać jakiś tekst na naszej karcie, może się zdarzyć, że przewinie się ona zanim zdążymy doczytać do końca. Sprawmy więc, że nakierowanie kursora na kartę wstrzymuje loader i pozwala nam na spokojne przeczytanie treści.

Najprostszym na to sposobem będzie dodanie obserwatorów zdarzeń na kartę aby wykrywała, gdy użytkownik nakieruje na nią kursor lub gdy z niej zjedzie.

$('.carousel-card').mouseenter(function (){
$('.loader', this).addClass('paused')
})

$('.carousel-card').mouseleave(function (){
$('.loader', this).removeClass('paused')
})
                

Powyższy skrypt nadaje loaderowi klasę paused, która zatrzymuje go, a co za tym - idzie nasza karta nie będzie się już samoistnie zmieniać.

Koniec

Karta, którą stworzyliśmy jest już funkcjonalna i gotowa do użycia na naszej stronie, a końcowy efekt powinien wyglądać w taki sposób.

O autorze
User avatar

Uczeń technikum na kierunku informatycznym, zapalony programista, aktywny członek organizacji MDB Youth. W wolnych chwilach poza programowaniem i nauką lubi pograć na gitarze lub przeczytać dobrą książkę.

Najnowsze artykuły

MDB Youth

MDB Youth to organizacja stworzona przez młodych ludzi, których celem jest wspólna nauka programowania, technologii i przedsiębiorczości.

Dowiedz się więcej i dołącz do nas.

Dołącz do MDB Youth