Слайдер с отзывами
Я пока учусь, и ещё плохо знаю js, нужно реализовать вот такой свайпер, как на фото. Есть задумка (просьба не смеяться, это лишь моя догадка) Если взять Swiper pagination dynamic, и дальше вопрос - могу я вместо точек сделать там изображения? Да так, чтоб они были разные, и ткнув к примеру на самую крайнюю фото, чтоб у меня в слайдере появлялось такое же фото с отзывом. И как мне их сделать полумесяцем а не в одну строку?
Ответы (2 шт):
В целом, задумка с Swiper интересная и имеет место быть, но, мне кажется, Flickity подойдет для этих целей больше, если использовать карусель. Единственное, это нужно грамотно стилизовать при помощи CSS.
То есть HTML-вид будет таким:
<div class="carousel">
<div class="carousel-cell"><img src="image1.jpg" alt="Image 1"></div>
<div class="carousel-cell"><img src="image2.jpg" alt="Image 2"></div>
<div class="carousel-cell"><img src="image3.jpg" alt="Image 3"></div>
</div>
CSS будет таким:
.carousel {
width: 100%;
height: 300px; /* Установите нужную высоту */
overflow: hidden;
position: relative;
}
.carousel-cell {
width: 200px; /* Установите ширину ячейки */
height: 100%;
position: absolute;
bottom: 0; /* Выравнивание по нижнему краю */
transition: transform 0.5s ease;
}
.carousel-cell img {
width: 100%;
height: auto;
border-radius: 50%; /* Закругление углов для полумесяца */
}
.carousel-cell:nth-child(1) { transform: translateX(-50%); }
.carousel-cell:nth-child(2) { transform: translateX(0); }
.carousel-cell:nth-child(3) { transform: translateX(50%); }
/* Процент поворота вручную нужно считать в зависимости от кол-ва изображений */
Ну и сам JS с подключением Flickity:
<script src="https://unpkg.com/flickity@2/dist/flickity.pkgd.min.js"></script>
<script>
var flkty = new Flickity('.carousel', {
// Опции Flickity
cellAlign: 'left',
contain: true,
wrapAround: true,
autoPlay: true
});
</script>
... могу я вместо точек сделать там изображения?
Да. В документации довольно подробно описана стилизация.
И как мне их сделать полумесяцем а не в одну строку?
Чтобы не заморачиваться с позиционирование, можно воспользоваться таким css-свойством, как offset
и расположить кнопки вдоль пути с необходимой траекторией.
let resps = [{ avatar: 'avatar_man_dutch.jpg', name: 'Голландец', desc: '' }, { avatar: 'avatar_woman_algerian.jpg', name: 'Алжирка', desc: '' }, { avatar: 'avatar_man_kenyan.jpg', name: 'Кениец', desc: '' }, { avatar: 'avatar_woman_australian.jpg', name: 'Австралийка', desc: '' }, { avatar: 'avatar_man_korean.jpg', name: 'Кореец', desc: '' }, { avatar: 'avatar_woman_brazilian.jpg', name: 'Бразильянка', desc: '' }, { avatar: 'avatar_man_mexican.jpg', name: 'Мексиканец', desc: '' }, { avatar: 'avatar_woman_irish.jpg', name: 'Ирландка', desc: '' }, { avatar: 'avatar_man_turkish.jpg', name: 'Турок', desc: '' }, { avatar: 'avatar_woman_russian.jpg', name: 'Русская', desc: '' }];
let swiperWrapper = document.querySelector('.swiper-wrapper');
let swiperWrapperTemplate = swiperWrapper.querySelector('.swiper-slide-template');
let swiperBulletImages = ``;
resps.forEach((resp, index) => {
let newSlide = swiperWrapperTemplate.content.cloneNode(true);
let src = `https://umodel.narod.ru/shareweb/image/avatars/${resp.avatar}`;
newSlide.querySelector('.avatar').src = src;
newSlide.querySelector('.name').textContent = resp.name;
swiperBulletImages += `
div.swiper-pagination span.swiper-pagination-bullet:nth-of-type(${index + 1}) {
background-image: url('${src}');
offset-distance: ${(100 / (resps.length - 1)) * index}%;
}
`;
newSlide.querySelector('.text').textContent = resp.desc || 'Lorem, ipsum dolor sit amet consectetur adipisicing elit. Corporis quibusdam inventore voluptatem, fugiat harum fuga sapiente error id aspernatur ea consectetur incidunt assumenda ipsa, tenetur iure voluptas velit ipsum laboriosam.';
swiperWrapper.append(newSlide);
});
// Initial Swiper
const swiper = new Swiper('.swiper', {
loop: true, pagination: { el: '.swiper-pagination', clickable: true }
});
document.head.appendChild(document.createElement('style')).textContent = swiperBulletImages;
.swiper {
height: 600px; width: 600px;
box-shadow: 0 0 2px #000;
}
/* Slide */
.swiper-slide {
display: flex;
flex-flow: column nowrap;
justify-content: center;
align-items: center;
height: 600px; width: 600px;
box-shadow: 0 0 2px #0000;
user-select: none;
}
/* Content */
.swiper-slide p {
height: 400px; width: 400px;
border-radius: 50%;
text-align: justify; text-align-last: center;
word-spacing: -0.5px;
overflow: hidden;
}
.shape-rounded { display: contents; }
.shape-rounded::before,
.shape-rounded::after {
content: "";
float: left;
height: 100%; width: 50%;
shape-outside: radial-gradient(farthest-side at 100%, transparent 100%, red);
shape-margin: 1em;
}
.shape-rounded::after {
float: right;
shape-outside: radial-gradient(farthest-side at 0, transparent 100%, red);
}
.swiper-slide img.avatar {
display: inline-block;
height: 150px; width: 150px;
border-radius: 50%;
object-fit: contain;
}
.swiper-slide span.name {
display: inline-block;
padding: 1em;
font: bold 24px/1em sans-serif;
}
.swiper-slide span.text {
font: 14px/1em sans-serif;
text-overflow: ellipsis;
overflow: hidden;
}
/* Bullets */
.swiper-pagination {
bottom: 0 !important;
height: 200px; width: 100% !important;
background-color: #fc00;
pointer-events: none;
}
div.swiper-pagination span.swiper-pagination-bullet {
margin: 0 -20px !important;
height: 32px; width: 32px;
offset: path('M -220 40, q 235 200 470 0') 0deg;
opacity: 1;
background-size: cover;
box-shadow: 0 0 8px 12px #fff;
transition: 0.3s transform, 0.3s margin;
pointer-events: auto;
}
div.swiper-pagination span.swiper-pagination-bullet.swiper-pagination-bullet-active {
margin: 0 !important;
transform: scale(2);
box-shadow: 0 0 1px 4px #fc8, 0 0 1px 8px #fc86;
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/swiper@8/swiper-bundle.min.css" />
<script src="https://cdn.jsdelivr.net/npm/swiper@8/swiper-bundle.min.js"></script>
<div class="swiper">
<div class="swiper-wrapper">
<!-- Slides -->
<template class="swiper-slide-template">
<div class="swiper-slide">
<p><span class="shape-rounded"></span><img class="avatar"><span class="name"></span><br><span class="text"></span></p>
</div>
</template>
</div>
<div class="swiper-pagination"></div>
</div>