jQuery:
var carouselID = 1, change = 8000;
function carouselStart() {
if ($('div[data-carousel="carousel"]').length < 1) {
return false;
};
$('div[data-carousel="carousel"]').each(function() {
$(this).removeAttr('data-carousel').attr('id', 'carousel_' + carouselID);
carousel('#carousel_' + carouselID);
carouselID++;
});
};
$(() => {
carouselStart();
window.setInterval(carouselStart, 3000);
});
function carousel(carouselID) {
var $slr, $sls, interval, $selectors, $btns, currentIndex, nextIndex;
var cycle = index => {
var $currentSlide, $nextSlide, $currentSelector, $nextSelector;
nextIndex = index !== undefined ? index : nextIndex;
$currentSlide = $($sls.get(currentIndex));
$currentSelector = $($selectors.get(currentIndex));
$nextSlide = $($sls.get(nextIndex));
$nextSelector = $($selectors.get(nextIndex));
$currentSlide.removeClass('sl-active').css('z-index', '0');
$nextSlide.addClass('sl-active').css('z-index', '1');
$currentSelector.removeClass('sl-current');
$nextSelector.addClass('sl-current');
currentIndex = index !== undefined ? nextIndex : currentIndex < $sls.length - 1 ? currentIndex + 1 : 0;
nextIndex = currentIndex + 1 < $sls.length ? currentIndex + 1 : 0;
};
currentIndex = 0;
nextIndex = 1;
$slr = $(carouselID);
$sls = $(carouselID + ' .sl');
$selectors = $(carouselID + ' .selector');
$btns = $(carouselID + ' .sl-btn');
$sls.first().addClass('sl-active');
$selectors.first().addClass('sl-current');
interval = window.setInterval(cycle, change);
$selectors.on('click', e => {
var target = $selectors.index(e.target);
if (target !== currentIndex) {
window.clearInterval(interval);
cycle(target);
interval = window.setInterval(cycle, change);
};
});
$btns.on('click', e => {
window.clearInterval(interval);
if ($(e.target).hasClass('sl-prev')) {
var target = currentIndex > 0 ? currentIndex - 1 : $sls.length - 1;
cycle(target);
}
else if ($(e.target).hasClass('sl-next')) {
cycle();
};
interval = window.setInterval(cycle, change);
});
};
CSS:
.slr {
position: relative;
width: 100%;
height: 400px;
overflow: hidden;
background-color: #3178b5;
background-position: center center;
background-repeat: no-repeat;
margin: 5px 0 15px 0;
}
.slr ul {
list-style: none;
margin: 0;
padding-left:0;
}
#sls .sl {
position: absolute;
display: flex;
width: 100%;
height: 100%;
}
#sls .sl .sl-text {
position: absolute;
margin: 5px;
bottom: 0;
z-index: 2;
padding: 12px 10px 12px 10px;
background: rgba(0, 0, 0, 0.6);
transform: translateY(200%);
transition: all 1000ms ease-in-out;
}
#sls .sl .sl-text a {
color: #BBBBBB;
}
#sls .sl .sl-text a:hover {
text-decoration: underline;
}
#sls .sl.sl-active .sl-text {
transform: translateY(0);
transition-delay: 0.3s;
}
#sls .sl .sl-text .sl-title {
font-size: 20px;
color: #FFFFFF;
font-family: 'Roboto', sans-serif;
margin-bottom: 5px;
}
#sls .sl .sl-text .sl-data {
font-size: 15px;
color: #FFFFFF;
}
#sls .sl .sl-text .sl-link {
margin: 15px 0 2px 0;
}
#sls .sl .sl-text .sl-read {
text-decoration: none;
position: relative;
font-size: 12px;
padding: 5px 10px;
color: #FFFFFF;
font-weight: bold;
font-family: 'Roboto', sans-serif;
background: #337AB7;
cursor: pointer;
}
#sls .sl .sl-text .sl-read:hover,
#sls .sl .sl-text .sl-read:active,
#sls .sl .sl-text .sl-read:focus {
color: #FFFFFF;
}
#sls .sl .sl-text .sl-read:after,
#sls .sl .sl-text .sl-read:before {
position: absolute;
height: 4px;
left: 50%;
background: #337AB7;
bottom: -8px;
content: "";
transition: all 280ms ease-in-out;
width: 0;
}
#sls .sl .sl-text .sl-read:before {
top: -8px;
}
#sls .sl .sl-text .sl-read:hover:after,
#sls .sl .sl-text .sl-read:hover:before,
#sls .sl .sl-text .sl-read:active:after,
#sls .sl .sl-text .sl-read:active:before,
#sls .sl .sl-text .sl-read:focus:after,
#sls .sl .sl-text .sl-read:focus:before {
width: 100%;
left: 0;
}
#sls .sl .sl-partial {
position: absolute;
width: 100%;
height: 100%;
overflow: hidden;
transition: transform 1s ease-in-out;
}
#sls .sl .sl-partial img {
position: absolute;
z-index: 1;
width: 100%;
height: 100%;
transition: transform 1s ease-in-out;
}
#sls .sl .sl-left {
top: 0;
left: 0;
transform: translateX(-100%);
clip-path: polygon(0 0, 2% 0, 100% 98%, 100% 100%, 0 100%);
}
#sls .sl .sl-left img {
top: 0;
right: 0;
}
#sls .sl .sl-right {
top: 0;
right: 0;
transform: translateX(100%);
clip-path: polygon(0 2%, 0 0, 100% 0, 100% 100%, 98% 100%);
}
#sls .sl .sl-right img {
top: 0;
left: 0;
}
#sls .sl.sl-active .sl-partial,
#sls .sl.sl-active .sl-partial img {
transform: translateX(0);
}
.slr .sl-btn {
position: absolute;
top: 20px;
right: 130px;
z-index: 100;
height: 50px;
width: 50px;
z-index: 100;
cursor: pointer;
overflow: visible;
}
.slr .sl-btn.sl-next {
right: 40px;
}
.slr .sl-btn polygon,
.slr .sl-btn path {
transition: all 0.5s cubic-bezier(0.2, 1, 0.3, 1);
fill: #FFFFFF;
}
.slr .sl-btn:hover polygon,
.slr .sl-btn:hover path {
transition: all 1s cubic-bezier(0.2, 1, 0.3, 1);
fill: #FFFFFF;
}
.slr .sl-btn:hover .sl-btn-pl {
animation: sl-btn-anim 1s cubic-bezier(0.2, 1, 0.3, 1) infinite;
}
.slr .sl-btn:hover .sl-btn-pl-fixed {
animation: sl-btn-fixed-anim 1s cubic-bezier(0.2, 1, 0.3, 1) infinite;
}
.sl-select {
position: absolute;
left: 8px;
top: 10px;
z-index: 100;
}
.sl-select li {
cursor: pointer;
margin: 0 0 4px 0;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
font-weight: bold;
}
.sl-select .selector {
height: 28px;
width: 28px;
border-radius: 50%;
background-color: #FFFFFF;
opacity: 0.5;
transition: background-color 0.5s ease-in-out;
}
.sl-select .selector.sl-current {
opacity: 1;
}
@keyframes sl-btn-anim {
0% {
opacity: 1;
transform: translateX(0);
}
5% {
transform: translateX(-0.1rem);
}
100% {
transform: translateX(1rem);
opacity: 0;
}
}
@keyframes sl-btn-fixed-anim {
5% {
opacity: 0;
}
20% {
opacity: 0.4;
}
100% {
opacity: 1;
}
}
@media screen and (max-width:767px) {
#sls .sl .sl-text {
position: absolute;
margin: 5px;
bottom: 0;
z-index: 2;
padding: 10px;
}
#sls .sl .sl-text .sl-title {
font-size: 20px;
line-height: 25px;
margin-bottom: 2px;
}
#sls .sl .sl-text .sl-data {
font-size: 13px;
line-height: 18px;
}
#sls .sl .sl-text .sl-link {
margin: 12px 0 2px 0;
}
}
HTML:
<div class="slr" data-carousel="carousel">
<ul id="sls">
{foreach from=$carousel item=block}
<li class="sl">
<div class="sl-partial sl-left"><img src="{$block.img}"/></div>
<div class="sl-partial sl-right"><img src="{$block.img}"/></div>
<div class="sl-text">
<div class="sl-title">{$block.title|shorten:70:'...'}</div>
{if isset($block.text)}
<div class="sl-data">{$block.text|parse|shorten:180:'...'}</div>
{/if}
{if isset($block.links)}
<div class="sl-link">
{foreach from=$block.links item=link}
<a href="{$link.url}" class="sl-read">{$link.title}</a>
{/foreach}
</div>
{/if}
</div>
</li>
{/foreach}
</ul>
<svg class="sl-btn sl-prev" viewBox="0 0 18 17" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g transform="translate(8.500000, 8.500000) scale(-1, 1) translate(-8.500000, -8.500000)">
<polygon class="sl-btn-pl" points="16.3746667 8.33860465 7.76133333 15.3067621 6.904 14.3175671 14.2906667 8.34246869 6.908 2.42790698 7.76 1.43613596"></polygon>
<polygon class="sl-btn-pl-fixed" points="16.3746667 8.33860465 7.76133333 15.3067621 6.904 14.3175671 14.2906667 8.34246869 6.908 2.42790698 7.76 1.43613596"></polygon>
<path d="M-1.48029737e-15,0.56157424 L-1.48029737e-15,16.1929159 L9.708,8.33860465 L-2.66453526e-15,0.56157424 L-1.48029737e-15,0.56157424 Z M1.33333333,3.30246869 L7.62533333,8.34246869 L1.33333333,13.4327013 L1.33333333,3.30246869 L1.33333333,3.30246869 Z"></path>
</g>
</svg>
<svg class="sl-btn sl-next" viewBox="-1 0 18 17" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g>
<polygon class="sl-btn-pl" points="16.3746667 8.33860465 7.76133333 15.3067621 6.904 14.3175671 14.2906667 8.34246869 6.908 2.42790698 7.76 1.43613596"></polygon>
<polygon class="sl-btn-pl-fixed" points="16.3746667 8.33860465 7.76133333 15.3067621 6.904 14.3175671 14.2906667 8.34246869 6.908 2.42790698 7.76 1.43613596"></polygon>
<path d="M-4.58892184e-16,0.56157424 L-4.58892184e-16,16.1929159 L9.708,8.33860465 L-1.64313008e-15,0.56157424 L-4.58892184e-16,0.56157424 Z M1.33333333,3.30246869 L7.62533333,8.34246869 L1.33333333,13.4327013 L1.33333333,3.30246869 L1.33333333,3.30246869 Z"></path>
</g>
</svg>
<ul class="sl-select">
{for $i = 1; $i <= count($carousel); $i++}
<li class="selector">{$i}</li>
{/for}
</ul>
</div>
Собирать массив для карусели, можно так:
$carousel = [];
foreach ($photos as $photo)
{
$carousel[] = [
'img' => 'imgURL',
'title' => 'imgTitle',
'text' => 'imgDescription',
'links' => [
[
'url' => 'link', // Ссылка с фотографии 1
'title' => 'title' // Анкор ссылки 1
],
[
'url' => 'link', // Ссылка с фотографии 2
'title' => 'title' // Анкор ссылки 2
]
]
];
}
Пример, к сожалению, показать не могу.