<section class="slider" data-slideshow-autoplay="true" data-slideshow-speed="10000">
<div class="slider__inner">
<div class="slider__slides">
<div class="slider__slide" data-label="Erstes Slider-Thema" data-icon="position">
<div style="height: 40rem; background-color: purple;">slide1</div>
</div>
<div class="slider__slide" data-label="Noch eine Beschriftung" data-icon="online-consulting">
<div style="height: 40rem; background-color: yellow;">slide2</div>
</div>
<div class="slider__slide" data-label="Weiteres Slider-Thema" data-icon="employed">
<div style="height: 40rem; background-color: blue;">slide3</div>
</div>
</div>
<div class="slider__prev">
<button class="icon-button slider__control slider__control--hidden icon-button--functional" id="icon-button-3f22" type="button">
<svg class="icon icon--arrow-thin-left" id="icon-37a6" viewBox="0 0 200 200" role="img" aria-labelledby="title-icon-37a6">
<title id="title-icon-37a6">Previous slide</title>
<use xlink:href="#icon-arrow-thin-left"></use>
</svg>
</button>
</div>
<div class="slider__next">
<button class="icon-button slider__control icon-button--functional" id="icon-button-656d" type="button">
<svg class="icon icon--arrow-thin-right" id="icon-933e" viewBox="0 0 200 200" role="img" aria-labelledby="title-icon-933e">
<title id="title-icon-933e">Next slide</title>
<use xlink:href="#icon-arrow-thin-right"></use>
</svg>
</button>
</div>
</div>
</section>
-
//- Prepare attr object
attr = attr || {};
attr.class = classList(attr.class);
//- Tag
tag = tag ? tag : 'section';
//- Slideshow options
attr['data-slideshow-autoplay'] = 'true';
attr['data-slideshow-speed'] = 10000;
//- Render slider
#{tag}.slider&attributes(attr): .slider__inner
//- Slides
.slider__slides
if slides
each slide in slides
.slider__slide&attributes({ 'data-label': slide.label, 'data-icon': slide.icon })
!= renderPug(slide.content)
//- Previous slide
.slider__prev
!= include('@icon-button--functional', { attr: { class: 'slider__control slider__control--hidden' }, icon: 'arrow-thin-left', title: 'Previous slide' })
//- Next slide
.slider__next
!= include('@icon-button--functional', { attr: { class: 'slider__control' }, icon: 'arrow-thin-right', title: 'Next slide' })
{
"tag": "section",
"slides": [
{
"label": "Erstes Slider-Thema",
"icon": "position",
"content": "div(style='height: 40rem; background-color: purple;') slide1\n"
},
{
"label": "Noch eine Beschriftung",
"icon": "online-consulting",
"content": "div(style='height: 40rem; background-color: yellow;') slide2\n"
},
{
"label": "Weiteres Slider-Thema",
"icon": "employed",
"content": "div(style='height: 40rem; background-color: blue;') slide3\n"
}
]
}
import { lory } from 'lory.js';
import h from 'hyperscript';
import icon from '../../../javascripts/utils/icon';
class Slider {
constructor($el) {
this.$el = $el;
const { dataset } = this.$el;
this.config = {
autoplay: dataset.slideshowAutoplay === 'true',
speed: Number(dataset.slideshowSpeed) || 10000,
};
this.$sliderInner = this.$el.querySelector('.slider__inner');
this.$slides = this.$el.querySelectorAll('.slider__slide');
this.$controlPrev = this.$el
.querySelector('.slider__prev')
.querySelector('.slider__control');
this.initEvents();
this.initLory();
this.initControls();
}
initEvents() {
this.$el.addEventListener('after.lory.init', () => {
this.$el.classList.add('slider--initialized');
});
this.$el.addEventListener('before.lory.slide', () => {
if (this.config.autoplay) {
this.stopSlideshow();
}
});
this.$el.addEventListener('after.lory.slide', ({ detail }) => {
const { currentSlide } = detail;
const $navItems = this.$el.querySelectorAll('.slider__nav [data-slide-id]');
$navItems.forEach(
($navItem) => {
const isCurrentSlide = Number($navItem.dataset.slideId) === currentSlide;
if (isCurrentSlide) {
$navItem.classList.add('is-active');
} else {
$navItem.classList.remove('is-active');
}
},
);
if (this.config.autoplay) {
this.startSlideshow();
}
if (currentSlide === 0) {
this.$controlPrev.classList.add('slider__control--hidden');
} else {
this.$controlPrev.classList.remove('slider__control--hidden');
}
});
}
initLory() {
this.lory = lory(this.$el, {
infinite: false,
rewind: true,
slideSpeed: 1000,
rewindOnResize: false,
classNameFrame: 'slider__inner',
classNameSlideContainer: 'slider__slides',
classNamePrevCtrl: 'slider__prev',
classNameNextCtrl: 'slider__next',
});
if (this.config.autoplay) {
this.startSlideshow();
}
}
initControls() {
const hasPageNav = Array.from(this.$slides).some(
$slide => Boolean($slide.dataset.label)
);
const $dotNav = h('ul.slider__dot-nav',
this.$slides.map(
(_, slideIndex) => h('li.slider__dot-item',
h(`button.slider__dot-button${slideIndex === 0 ? '.is-active' : ''}`, {
type: 'button',
'data-slide-id': slideIndex,
onclick: e => this.showSlide(e),
}),
),
),
);
const $pageNav = hasPageNav
? h('ul.slider__page-nav',
this.$slides.map(
({ dataset }, slideIndex) => h('li.slider__page-item',
h(`button.slider__page-button${slideIndex === 0 ? '.is-active' : ''}`,
{
type: 'button',
'data-slide-id': slideIndex,
onclick: e => this.showSlide(e),
},
h('span.slider__page-clamp',
dataset.icon
? h('span.slider__page-icon', icon({ icon: dataset.icon }))
: null,
dataset.label
? h('span.slider__page-label', dataset.label)
: null,
),
h('span.slider__page-progress', { style: { 'animation-duration': `${this.config.speed}ms` } }),
),
),
),
)
: null;
const $pause = h('button.slider__pause', {
type: 'button',
onclick: e => this.toggleSlideshow(e),
});
this.$sliderInner.appendChild(
h(`.slider__nav${hasPageNav ? '.slider__nav--has-page-nav' : ''}`,
$pageNav,
$dotNav,
$pause,
),
);
}
toggleSlideshow({ currentTarget }) {
this.config.autoplay = !this.config.autoplay;
if (this.config.autoplay) {
currentTarget.classList.remove('slider__pause--active');
this.startSlideshow();
} else {
currentTarget.classList.add('slider__pause--active');
this.stopSlideshow();
}
}
startSlideshow() {
this.$el.classList.add('slider--autoplaying');
this.slideshowTimer = setInterval(() => {
this.lory.next();
}, this.config.speed);
}
stopSlideshow() {
this.$el.classList.remove('slider--autoplaying');
clearInterval(this.slideshowTimer);
}
showSlide({ currentTarget }) {
this.lory.slideTo(Number(currentTarget.dataset.slideId));
}
}
document.querySelectorAll('.slider').forEach($slider => new Slider($slider));
$slider-controls-margin: 4rem;
$slider-controls-margin-from-xl: 3rem;
$slider-controls-margin-from-xxl: calc(((100vw - #{$page-inner-max-width}) / 2) + 3rem);
$slider-controls-margin-from-page-max: (($page-max-width - $page-inner-max-width) / 2) + 3rem;
$slider-controls-dot-functional-size: 1.8rem;
@mixin pause-svg($color: #fff) {
background-image: svg-url('<svg viewBox="0 0 6 8" xmlns="http://www.w3.org/2000/svg"><path fill="' + $color + '" d="M0,1.3603254 L2.22044605e-16,6.61640556 C2.45376032e-16,7.16869031 0.44771525,7.61640556 1,7.61640556 C1.55228475,7.61640556 2,7.16869031 2,6.61640556 L2,1.3603254 C2,0.808040647 1.55228475,0.360325397 1,0.360325397 C0.44771525,0.360325397 -2.33314267e-17,0.808040647 0,1.3603254 Z" /><path fill="' + $color + '" d="M3.5,1.3603254 L3.5,6.61640556 C3.5,7.16869031 3.94771525,7.61640556 4.5,7.61640556 C5.05228475,7.61640556 5.5,7.16869031 5.5,6.61640556 L5.5,1.3603254 C5.5,0.808040647 5.05228475,0.360325397 4.5,0.360325397 C3.94771525,0.360325397 3.5,0.808040647 3.5,1.3603254 Z" /></svg>');
background-position: center;
background-size: 0.8rem;
}
.slider {
width: 100%;
}
.slider--initialized {
.slider__inner {
overflow: hidden;
}
@include mq($from: l) {
&:hover {
.slider__control:not(.slider__control--hidden) {
display: block;
}
}
.slider__control--hidden {
display: none;
}
}
}
.slider__inner {
overflow-x: scroll;
position: relative;
width: 100%;
}
.slider__slides {
display: flex;
z-index: 1;
}
.slider__slide {
flex-shrink: 0;
position: relative;
width: 100%;
}
.slider__control {
background-color: rgba($color-steelgrey-dark, 0.3);
color: #fff;
display: none;
height: 9rem;
margin: 0;
transition-duration: $default-transition-duration;
transition-property: background-color;
&:hover,
&:focus {
background-color: $color-steelgrey-dark;
}
}
.slider__prev,
.slider__next {
cursor: pointer;
display: block;
position: absolute;
top: 50%;
transform: translate(0, -50%);
z-index: 2;
}
.slider__next {
right: $slider-controls-margin;
@include mq($from: xl) {
right: $slider-controls-margin-from-xl;
}
@include mq($from: xxl) {
right: $slider-controls-margin-from-xxl;
}
@include mq($from: page-max) {
right: $slider-controls-margin-from-page-max;
}
}
.slider__prev {
left: $slider-controls-margin;
@include mq($from: xl) {
left: $slider-controls-margin-from-xl;
}
@include mq($from: xxl) {
left: $slider-controls-margin-from-xxl;
}
@include mq($from: page-max) {
left: $slider-controls-margin-from-page-max;
}
}
.slider__nav {
@include make-container();
align-items: flex-end;
bottom: 5rem;
display: flex;
left: 0;
position: absolute;
right: 0;
z-index: 1;
@include mq($from: m) {
bottom: 9rem;
}
}
.slider__nav--has-page-nav {
@include mq($until: l) {
.slider__page-nav {
display: none;
}
}
@include mq($from: l) {
align-items: center;
.slider__dot-nav {
display: none;
}
}
}
.slider__dot-nav {
@include list-reset();
display: flex;
margin-left: auto;
margin-right: 0.5rem;
}
.slider__dot-item {
display: inline-flex;
margin-left: 0.5rem;
margin-right: 0.5rem;
}
.slider__dot-button {
background-color: $color-steelgrey-dark;
cursor: pointer;
display: inline-block;
height: 0.7rem;
width: 2rem;
&:hover {
background-color: #fff;
}
&.is-active {
background-color: #fff;
}
}
.slider__page-nav {
@include list-reset();
align-items: center;
display: flex;
flex-grow: 1;
justify-content: center;
list-style: none;
margin-left: auto;
margin-right: auto;
}
.slider__page-item {
margin-left: 0.3rem;
margin-right: 0.3rem;
}
.slider__page-button {
background-color: #fff;
color: $color-blue;
cursor: pointer;
display: inline-block;
font-weight: normal;
line-height: 1;
min-width: 20rem;
padding: 1rem;
position: relative;
transition-duration: $default-transition-duration;
transition-property: color;
&:not(.is-active):hover {
color: $color-blue-light;
}
&.is-active {
cursor: default;
font-weight: bold;
}
}
.slider__page-clamp {
align-items: center;
display: flex;
}
.slider__page-icon {
flex-shrink: 0;
font-size: 1.6rem;
margin-right: 0.8rem;
}
.slider__page-label {
font-size: 1.4rem;
}
@keyframes sliderProgress {
0% {
width: 0;
}
100% {
width: 100%;
}
}
.slider__page-progress {
background-color: $color-blue;
bottom: -0.2rem;
height: 0.2rem;
left: 0;
position: absolute;
width: 0;
}
.slider__pause {
@include pause-svg();
background-color: $color-steelgrey-dark;
border-radius: 2px;
cursor: pointer;
display: inline-block;
height: $slider-controls-dot-functional-size;
width: $slider-controls-dot-functional-size;
}
.slider__pause--active {
background-color: $color-red;
}
// Hide page nav on smaller viewports
@include mq($until: l) {
.slider__nav--has-page-nav .slider__page-nav {
display: none;
}
}
@include mq($from: l) {
// Show page nav on larger viewports and hide redundant dot nav
.slider__nav--has-page-nav {
align-items: center;
.slider__dot-nav {
display: none;
}
}
// Enable progress animation on page nav buttons for active pages
.slider--autoplaying .slider__page-button.is-active .slider__page-progress {
animation-name: sliderProgress;
animation-timing-function: linear;
}
}
There are no notes for this item.