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’, } ] }
<div id="bannerSlideshow" class="bannerSlideshow">
<div class="slideshowImages">
{% for item in items %}
<div class="image" style="background-image: url(/placeholders/{{item.url}}); animation-delay: {{loop.index0 * slideDuration}}s; animation-duration: {{loop.length * slideDuration}}s"></div>
{% endfor %}
</div>
</div>
<div class="bannerSlideshowControls">
<div class="slideshowControlsInner">
<div class="slideshowControl" id="playButton">
<span class="triangle"></span>
</div>
<div class="slideshowControl" id="pauseButton">
<div></div>
<div></div>
</div>
</div>
</div>
<div id="bannerSlideshow" class="bannerSlideshow">
<div class="slideshowImages">
<div class="image" style="background-image: url(/placeholders/new-homepage/banner-25-01-wide.jpg); animation-delay: 0s; animation-duration: 24s"></div>
<div class="image" style="background-image: url(/placeholders/new-homepage/banner-25-02-wide.jpg); animation-delay: 8s; animation-duration: 24s"></div>
<div class="image" style="background-image: url(/placeholders/new-homepage/banner-25-03.jpg); animation-delay: 16s; animation-duration: 24s"></div>
</div>
</div>
<div class="bannerSlideshowControls">
<div class="slideshowControlsInner">
<div class="slideshowControl" id="playButton">
<span class="triangle"></span>
</div>
<div class="slideshowControl" id="pauseButton">
<div></div>
<div></div>
</div>
</div>
</div>
// new colours
$newBrand1: #00D0A0;
// Slideshow CSS
$slideZoomRatio: 1.2;
$bannerHeight: 500px;
$maxWidth: 1600px;
$controlPadding: 10px;
$controlMargin: 20px;
$controlHeight: 14px;
#bannerSlideshow {
width: 100%;
height: $bannerHeight;
position: relative;
overflow: hidden;
.slideshowImages {
width: 100%;
overflow: hidden;
.image {
height: $bannerHeight;
position: absolute;
top: 0;
left: 0;
width: 100%;
animation-name: fade;
animation-iteration-count: infinite;
opacity: 0;
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}
@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: $newBrand1;
display: flex;
align-items: center;
justify-content: center;
.slideshowControl {
align-items: center;
cursor: pointer;
border: 1px solid black;
margin: $controlMargin $controlMargin 0;
width: calc(#{$controlHeight} + #{$controlPadding} * 2 + 2px);
height: calc(#{$controlHeight} + #{$controlPadding} * 2 + 2px);
}
#pauseButton {
display: flex; // change between flex and none using JS
justify-content: space-evenly;
div {
width: 5px;
height: $controlHeight;
margin: $controlMargin 0;
background: black;
}
}
#playButton {
display: none; // change between flex and none using JS
justify-content: center;
.triangle {
width: 0px;
height: 0px;
border-style: solid;
border-width: calc(#{$controlHeight} / 2) 0 calc(#{$controlHeight} / 2) calc(#{$controlHeight}* 0.86);
border-color: transparent transparent transparent black;
transform: rotate(0deg);
}
}
}
}
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/banner-25-01-wide.jpg"
},
{
"url": "new-homepage/banner-25-02-wide.jpg"
},
{
"url": "new-homepage/banner-25-03.jpg"
}
]
}