The slideshow component is a component built initially for the UoL homepage. This provides a prominent visual slideshow with full width images transitioning in to each other. This can support any number of images, but care should be applied as more images will mean longer load time. Each image appears on screen for a configurable number of seconds, during this time period the image subtlely zooms in, and as one image is at the end of it’s time, it then fades out as the next image fades in. At the end of the loop, the first image appears again and this repeats. The user can stop the animation and restart it via the pause and play controls.
‘slideDuration’: (number of seconds)
array of ‘items’ for images. Each item has a single parameter ‘url’ which gives the relative or absolute path to the image.
``` context: { ‘name’: ‘Slideshow’, ‘handle’: ‘uol-slideshow’, ‘status’: ‘prototype’, ‘slideDuration’: 8, ‘items’: [ { ‘url’: ‘new-homepage/banner-25-01-wide.jpg’, }, { ‘url’: ‘new-homepage/banner-25-02-wide.jpg’, }, { ‘url’: ‘new-homepage/banner-25-03.jpg’, } ] }
<section aria-hidden="true">
<div id="bannerSlideshow" class="bannerSlideshow">
<ul class="slideshowImages">
{% for item in items %}
<li class="image" style="background-image: url(/placeholders/{{item.url}}); animation-delay: {{loop.index0 * slideDuration}}s; animation-duration: {{loop.length * slideDuration}}s"></li>
{% endfor %}
</ul>
</div>
<div class="bannerSlideshowControls">
<div class="slideshowControlsInner">
<button id="playButton" class="slideshowControl uol-button uol-icon uol-icon--mdiPlay uol-icon--icon-only uol-icon--icon-only--large" type="button">Play slideshow</button>
<button id="pauseButton"class="slideshowControl uol-button uol-icon uol-icon--mdiPause uol-icon--icon-only uol-icon--icon-only--large" type="button">Pause slideshow</button>
</div>
</div>
</section>
<section aria-hidden="true">
<div id="bannerSlideshow" class="bannerSlideshow">
<ul class="slideshowImages">
<li class="image" style="background-image: url(/placeholders/new-homepage/1.png); animation-delay: 0s; animation-duration: 24s"></li>
<li class="image" style="background-image: url(/placeholders/new-homepage/4.png); animation-delay: 8s; animation-duration: 24s"></li>
<li class="image" style="background-image: url(/placeholders/new-homepage/8.png); animation-delay: 16s; animation-duration: 24s"></li>
</ul>
</div>
<div class="bannerSlideshowControls">
<div class="slideshowControlsInner">
<button id="playButton" class="slideshowControl uol-button uol-icon uol-icon--mdiPlay uol-icon--icon-only uol-icon--icon-only--large" type="button">Play slideshow</button>
<button id="pauseButton" class="slideshowControl uol-button uol-icon uol-icon--mdiPause uol-icon--icon-only uol-icon--icon-only--large" type="button">Pause slideshow</button>
</div>
</div>
</section>
// adding comment line to initiate dev build again
// Slideshow CSS
$slideZoomRatio: 1.2;
$bannerHeightSmall: 220px;
$bannerHeightMedium: 300px;
$bannerHeightLarge: 400px;
$maxWidth: 1600px;
$controlMargin: 16px;
#bannerSlideshow {
width: 100%;
height: $bannerHeightSmall;
position: relative;
overflow: hidden;
@include media(">=uol-media-m") {
height: $bannerHeightMedium;
}
@include media(">=uol-media-l") {
height: $bannerHeightLarge;
}
.slideshowImages {
width: 100%;
overflow: hidden;
.image {
height: $bannerHeightSmall;
position: absolute;
top: 0;
left: 0;
width: 100%;
animation-name: fade;
animation-iteration-count: infinite;
opacity: 0;
background-position: 50%;
background-repeat: no-repeat;
background-size: cover;
@include media(">=uol-media-m") {
height: $bannerHeightLarge;
}
}
@keyframes fade {
0% { opacity: 0; }
11.11% { opacity: 1; }
33.33% { opacity: 1; }
44.44% { opacity: 0; transform: scale($slideZoomRatio);}
100% { opacity: 0; transform: scale(1);}
}
}
}
.bannerSlideshowControls {
width: 100%;
max-width: $maxWidth;
margin: 0 auto;
position: relative;
.slideshowControlsInner {
position: absolute;
right: 0;
bottom: 0;
background: $color-brand-teal;
display: flex;
align-items: center;
justify-content: center;
.slideshowControl {
align-items: center;
cursor: pointer;
border: 2px solid white;
margin: $controlMargin $controlMargin 0;
}
#pauseButton {
display: flex; // change between flex and none using JS
}
#playButton {
display: none; // change between flex and none using JS
}
}
}
export const slideshowJs = () => {
const bannerSlideshow = document.querySelectorAll('.bannerSlideshow');
bannerSlideshow.forEach( ( slideshow ) => {
const pauseButton = document.getElementById("pauseButton");
const playButton = document.getElementById("playButton");
const images = slideshow.getElementsByClassName("image");
pauseButton.addEventListener('click', () => {
playButton.style.display = "flex";
pauseButton.style.display = "none";
for (let image of images) {
image.style.animationPlayState = "paused";
}
});
playButton.addEventListener('click', () => {
playButton.style.display = "none";
pauseButton.style.display = "flex";
for (let image of images) {
image.style.animationPlayState = "running";
}
});
})
}
{
"slideDuration": 8,
"items": [
{
"url": "new-homepage/1.png"
},
{
"url": "new-homepage/4.png"
},
{
"url": "new-homepage/8.png"
}
]
}