<div class="carousel">
<div class="swiper-container js-carousel">
<div class="swiper-wrapper">
<div class="swiper-slide js-carousel__item carousel__item">
<div class="carousel__img-area">
<img src="/mocks/img/casa-f-principle.jpg" alt="Alt" class="carousel__image">
</div>
</div>
<div class="swiper-slide js-carousel__item carousel__item">
<div class="carousel__img-area">
<img src="/mocks/img/kone_syv.png" alt="Alt" class="carousel__image">
</div>
</div>
<div class="swiper-slide js-carousel__item carousel__item">
<video class="video" style="width: 100%" controls muted>
<source src=/mocks/video/sample-5s.mp4 type="video/mp4">
Your browser does not support the video tag.
</video>
</div>
<div class="swiper-slide js-carousel__item carousel__item">
<video class="video" style="width: 100%" controls muted>
<source src=/mocks/video/sample-5s.mp4 type="video/mp4">
Your browser does not support the video tag.
</video>
</div>
<div class="swiper-slide js-carousel__item carousel__item">
<div class="carousel__img-area">
<img src="/mocks/img/kone_syv.png" alt="Alt" class="carousel__image">
</div>
</div>
<div class="swiper-slide js-carousel__item carousel__item">
<div class="carousel__img-area">
<img src="/mocks/img/kone_syv.png" alt="Alt" class="carousel__image">
</div>
</div>
</div>
</div>
<div class="thumbnail-carousel">
<div class="swiper-container js-thumbnail-carousel thumbnail-carousel__container">
<div class="swiper-wrapper">
<div class="swiper-slide carousel__item js-thumbnail-item">
<div class="carousel__img-holder">
<img src="/mocks/img/casa-f-principle.jpg" alt="Alt" class="carousel__image">
</div>
<div class="carousel__thumbnail-info">
<div class="carousel__thumbnail-name">Gold PX</div>
<div class="carousel__thumbnail-descr">Amet, consectetur Amet, consectetur Amet, consectetur Amet, consectetur Amet, consectetur</div>
</div>
</div>
<div class="swiper-slide carousel__item js-thumbnail-item">
<div class="carousel__img-holder">
<img src="/mocks/img/kone_syv.png" alt="Alt" class="carousel__image">
</div>
<div class="carousel__thumbnail-info">
<div class="carousel__thumbnail-name">Gold PX</div>
<div class="carousel__thumbnail-descr">Amet, consectetur</div>
</div>
</div>
<div class="swiper-slide carousel__item js-thumbnail-item">
<div class="carousel__video-img-holder">
<img src="/mocks/img/kone_auki_syv.png" alt="Alt" class="carousel__image">
</div>
<div class="carousel__thumbnail-info">
<div class="carousel__thumbnail-name">Gold PX</div>
<div class="carousel__thumbnail-descr">Amet, consectetur</div>
</div>
</div>
<div class="swiper-slide carousel__item js-thumbnail-item">
<div class="carousel__video-img-holder">
<img src="/mocks/img/casa-f-principle.jpg" alt="Alt" class="carousel__image">
</div>
<div class="carousel__thumbnail-info">
<div class="carousel__thumbnail-name">Gold PX</div>
<div class="carousel__thumbnail-descr">Amet, consectetur</div>
</div>
</div>
<div class="swiper-slide carousel__item js-thumbnail-item">
<div class="carousel__img-holder">
<img src="/mocks/img/kone_syv.png" alt="Alt" class="carousel__image">
</div>
<div class="carousel__thumbnail-info">
<div class="carousel__thumbnail-name">Gold PX</div>
<div class="carousel__thumbnail-descr">Amet, consectetur</div>
</div>
</div>
<div class="swiper-slide carousel__item js-thumbnail-item">
<div class="carousel__img-holder">
<img src="/mocks/img/kone_syv.png" alt="Alt" class="carousel__image">
</div>
<div class="carousel__thumbnail-info">
<div class="carousel__thumbnail-name">Gold PX</div>
<div class="carousel__thumbnail-descr">Amet, consectetur</div>
</div>
</div>
</div>
</div>
<!-- If we need navigation buttons -->
<div class="swiper-button-prev">
<svg class="icon " focusable="false">
<use xlink:href="#icon-slider-arrow"></use>
</svg>
</div>
<div class="swiper-button-next">
<svg class="icon " focusable="false">
<use xlink:href="#icon-slider-arrow"></use>
</svg>
</div>
</div>
</div>
<div class="carousel">
<div class="swiper-container js-carousel">
<div class="swiper-wrapper">
{{#each slides}}
<div class="swiper-slide js-carousel__item carousel__item">
{{#if video}}
<video class="video" style="width: 100%" controls muted>
<source src={{video}} type="video/mp4">
Your browser does not support the video tag.
</video>
{{else}}
<div class="carousel__img-area">
<img src="{{image}}" alt="Alt" class="carousel__image">
</div>
{{/if}}
</div>
{{/each}}
</div>
</div>
<div class="thumbnail-carousel">
<div class="swiper-container js-thumbnail-carousel thumbnail-carousel__container">
<div class="swiper-wrapper">
{{#each slides}}
<div class="swiper-slide carousel__item js-thumbnail-item">
<div {{#if video}} class="carousel__video-img-holder" {{else}}class="carousel__img-holder" {{/if}}>
<img src="{{thumbnailImage}}" alt="Alt" class="carousel__image">
</div>
<div class="carousel__thumbnail-info">
<div class="carousel__thumbnail-name">{{thumbnailTitle}}</div>
<div class="carousel__thumbnail-descr">{{thumbnailDescr}}</div>
</div>
</div>
{{/each}}
</div>
</div>
<!-- If we need navigation buttons -->
<div class="swiper-button-prev">
{{> @icon id="slider-arrow"}}
</div>
<div class="swiper-button-next">
{{> @icon id="slider-arrow"}}
</div>
</div>
</div>
{
"layoutMaxWidth": "754px",
"slides": [
{
"image": "/mocks/img/casa-f-principle.jpg",
"thumbnailImage": "/mocks/img/casa-f-principle.jpg",
"thumbnailTitle": "Gold PX",
"thumbnailDescr": "Amet, consectetur Amet, consectetur Amet, consectetur Amet, consectetur Amet, consectetur"
},
{
"image": "/mocks/img/kone_syv.png",
"thumbnailImage": "/mocks/img/kone_syv.png",
"thumbnailTitle": "Gold PX",
"thumbnailDescr": "Amet, consectetur"
},
{
"video": "/mocks/video/sample-5s.mp4",
"image": "/mocks/img/kone_auki_syv.png",
"thumbnailImage": "/mocks/img/kone_auki_syv.png",
"thumbnailTitle": "Gold PX",
"thumbnailDescr": "Amet, consectetur"
},
{
"video": "/mocks/video/sample-5s.mp4",
"image": "/mocks/img/casa-f-principle.jpg",
"thumbnailImage": "/mocks/img/casa-f-principle.jpg",
"thumbnailTitle": "Gold PX",
"thumbnailDescr": "Amet, consectetur"
},
{
"image": "/mocks/img/kone_syv.png",
"thumbnailImage": "/mocks/img/kone_syv.png",
"thumbnailTitle": "Gold PX",
"thumbnailDescr": "Amet, consectetur"
},
{
"image": "/mocks/img/kone_syv.png",
"thumbnailImage": "/mocks/img/kone_syv.png",
"thumbnailTitle": "Gold PX",
"thumbnailDescr": "Amet, consectetur"
}
]
}
import Swiper from 'swiper';
class Carousel {
constructor(el) {
this.el = el;
this.carouselSelector = this.el.querySelector('.js-carousel');
this.carouselItems = this.carouselSelector.querySelectorAll('.js-carousel__item');
this.thumbnailCarouselSelector = this.el.querySelector('.js-thumbnail-carousel');
this.thumbnails = this.thumbnailCarouselSelector.querySelectorAll('.js-thumbnail-item');
this.init();
}
init() {
const self = this;
this.carousel = new Swiper(this.carouselSelector, {
effect: 'fade',
fadeEffect: { crossFade: true },
on: {
'slideChange': function () {
const index = this.activeIndex;
self.highlightActiveThumbnail(index);
}
}
});
this.thumbnailCarousel = new Swiper(this.thumbnailCarouselSelector, {
slidesPerView: 2,
navigation: {
nextEl: '.swiper-button-next',
prevEl: '.swiper-button-prev'
},
breakpoints: {
480: {
slidesPerView: 3
},
640: {
slidesPerView: 4
}
}
});
this.attachTriggers();
this.highlightActiveThumbnail(0);
}
attachTriggers() {
for (let i = 0; i < this.thumbnails.length; i++) {
const thumbnail = this.thumbnails[i];
thumbnail.addEventListener('click', () => {
this.goToSlide(i);
// Selected video
const video = this.carouselItems[i].querySelector('.video');
// All videos
const videos = this.carouselSelector.querySelectorAll('.video');
if (video) {
// Pause all videos
videos.forEach(video => {
video.pause();
});
// Play the selected video
video.play();
} else {
// Pause all videos
videos.forEach(video => {
video.pause();
});
}
});
}
}
highlightActiveThumbnail(index) {
const selectedThumbnail = this.thumbnails[index];
const activeThumbnail = this.thumbnailCarouselSelector.querySelector('.js-thumbnail-item.carousel__item--active');
selectedThumbnail.classList.add('carousel__item--active');
const activeImage = selectedThumbnail.querySelector('img');
for (let i = 0; i < this.thumbnails.length; i++) {
this.thumbnails[i].querySelector('img').removeAttribute('data-testid');
}
activeImage.setAttribute('data-testid', 'img-active');
if (activeThumbnail) {
activeThumbnail.classList.remove('carousel__item--active');
}
}
goToSlide(index) {
this.carousel.slideTo(index);
}
}
export default Carousel;
.carousel__item {
cursor: pointer;
user-select: none;
&--active {
.carousel__img-holder,
.carousel__video-img-holder {
border-color: $color-green;
z-index: 2;
&:before {
border-color: $color-green;
}
}
}
}
.carousel__img-area {
position: relative;
height: 0;
overflow: hidden;
padding-top: percentage(8 / 10);
flex: auto;
}
.carousel__img-holder {
position: relative;
height: 0;
overflow: hidden;
padding-top: percentage(8 / 10);
flex: auto;
margin: 0 size(0.5) size(1);
border: 1px solid $color-gray-2;
&::before {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
content: '';
border: 1px solid transparent;
z-index: 1;
}
img {
max-height: 100%;
}
}
.carousel__video-img-holder {
position: relative;
height: 0;
overflow: hidden;
padding-top: percentage(8 / 10);
flex: auto;
margin: 0 size(0.5) size(1);
border: 1px solid $color-gray-2;
&::before {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
content: '';
border: 1px solid transparent;
z-index: 1;
background-color: black;
opacity: .4;
}
&::after {
content: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjMiIGhlaWdodD0iMjMiIHZpZXdCb3g9IjAgMCAyMyAyMyIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTExLjQ0NzMgMjIuODA3MkMxNy43MTEzIDIyLjgwNzIgMjIuNzg5MiAxNy44MjQ5IDIyLjc4OTIgMTEuNjc5QzIyLjc4OTIgNS41MzMwNSAxNy43MTEzIDAuNTUwNzgxIDExLjQ0NzMgMC41NTA3ODFDNS4xODMzOSAwLjU1MDc4MSAwLjEwNTQ2OSA1LjUzMzA1IDAuMTA1NDY5IDExLjY3OUMwLjEwNTQ2OSAxNy44MjQ5IDUuMTgzMzkgMjIuODA3MiAxMS40NDczIDIyLjgwNzJaIiBmaWxsPSJ3aGl0ZSIvPgo8cGF0aCBkPSJNOS4xNzk2OSA3LjIyNjU2TDE1Ljk4NDggMTEuNjc3OEw5LjE3OTY5IDE2LjEyOTFWNy4yMjY1NloiIGZpbGw9IiM0MzQzNDMiLz4KPC9zdmc+Cg==');
position: absolute;
bottom: calc(50% - 12px);
left: calc(50% - 12px);
width: 24px;
height: 24px;
z-index: 1;
}
img {
max-height: 100%;
height: 100%;
width: 100%;
object-fit: cover;
}
}
.carousel__image {
position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
max-height: 90%;
}
.carousel__thumbnail-info {
font-size: size(1.5);
line-height: size(2);
padding: 0 4px;
}
.carousel__thumbnail-descr {
color: $color-gray-4;
}
.thumbnail-carousel {
position: relative;
padding: 0 59px 0 size(7.5);
.swiper-container {
padding: 0 1px 0 0;
}
.carousel__item {
&:first-child {
.carousel__img-holder {
margin-left: 0;
}
.carousel__thumbnail-info {
padding: 0;
}
}
&:last-child {
.carousel__img-holder {
margin-right: 0;
}
}
}
}
.swiper-wrapper {
display: flex;
align-items: stretch;
}
.swiper-container-fade .swiper-slide {
align-items: center;
justify-content: center;
display: flex;
height: auto;
}
.swiper-button-next,
.swiper-button-prev {
width: size(4);
height: size(4);
top: size(2.5);
margin-top: auto;
&:after {
font-family: auto;
font-size: 0;
}
&:focus {
outline: none;
-webkit-appearance: none;
}
@include breakpoint($xxs) {
top: size(5);
}
@include breakpoint($xs) {
top: size(5.75);
}
}
.swiper-button-next,
.swiper-button-prev {
color: $color-gray-4;
z-index: 3;
svg {
width: 100%;
height: 100%;
}
}
.swiper-button-prev {
transform: rotate(180deg);
}
.swiper-button-next.swiper-button-disabled,
.swiper-button-prev.swiper-button-disabled {
display: none;
}
import Carousel from './Carousel';
const els = document.querySelectorAll('.carousel');
for (let el of els) {
new Carousel(el);
};
No notes defined.