Как сделать такой круговой слайдер?
Нужно сделать так, чтобы элементы слайдера вращались, а активный слайд плавно увеличивался, как на макете слева. Так же текст снизу должен меняться в зависимости от выбранного слайдера. Чем проще реализация, тем лучше) Прошу помочь, не дает проект закрыть эта зараза)
Ответы (1 шт):
Автор решения: hu-fo
→ Ссылка
Текст снизу не показываю как менять, потому что примеров в интернетах очень много
const outerCircle = document.querySelector('.circle-outer')
const items = document.querySelectorAll('.item')
// событие клика по внешнему кругу
outerCircle.addEventListener('click', (e) => {
// если клик произошел не по айтему - выход из функции
if (!e.target.classList.contains('item')) return
// вычисляется значение на сколько нужно повернуть круг,
// что бы элемент по которому произошел клик
// оказался внизу
// 180 - 123 123deg 123
const z = 180 - +e.target.style.getPropertyValue('--z').replace('deg', '')
// изменяется переменная -z на вычисленное выше значение
outerCircle.style.setProperty('--z', z + 'deg');
// перед тем как увеличить элемент по которому произошел клик
// уменьшаются(возвращаются в исходное состояние все элементы)
items.forEach(item => item.style.setProperty('--s', 1))
// увеличение элемента по которому произошел клик в 2 раза
e.target.style.setProperty('--s', 2);
})
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
:root {
--item-width: calc(3vw + 8vh);
--item-height: calc(4vw + 10vh);
--co-size: calc(15vw + 30vh);
--ci-size: calc(8vw + 20vh);
}
.slider {
position: relative;
height: 100vh;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
}
.circle-outer {
position: absolute;
width: var(--co-size);
height: var(--co-size);
display: flex;
align-items: center;
justify-content: center;
/* эта величина меняется через js */
transform: rotate(var(--z));
transition: 1s;
}
.circle-inner {
position: absolute;
width: var(--ci-size);
height: var(--ci-size);
border: 1px solid black;
border-radius: 50%;
z-index: -1;
}
.item {
position: absolute;
height: var(--item-height);
width: var(--item-width);
background-color: tomato;
transition: 1s;
}
/* РВК - размер внутренненго круга */
/* размер увеличения изменяется через js */
/* величина поворота берется из инлайн переменной в html */
.item-1 {
/*x = 0, y = -РВК / 1.2*/
transform: translate(0, calc(-1 * var(--ci-size) / 1.2)) rotate(var(--z)) scale(var(--s));
}
.item-2 {
/*x = РВК / 1.6, y = -РВК / 1.7*/
transform: translate(calc(var(--ci-size) / 1.6), calc(-1 * var(--ci-size) / 1.7)) rotate(var(--z)) scale(var(--s));
}
.item-3 {
/*x = РВК / 1.2, y = 0*/
transform: translate(calc(var(--ci-size) / 1.2), 0) rotate(var(--z)) scale(var(--s));
}
.item-4 {
/*x = РВК / 1.6, y = РВК / 1.7*/
transform: translate(calc(var(--ci-size) / 1.6), calc(var(--ci-size) / 1.7)) rotate(var(--z)) scale(var(--s));
}
.item-5 {
/*x = 0, y = РВК / 1.2*/
transform: translate(0, calc(var(--ci-size) / 1.2)) rotate(var(--z)) scale(var(--s));
}
.item-6 {
/*x = -РВК / 1.6, y = РВК / 1.7*/
transform: translate(calc(-1 * var(--ci-size) /1.6), calc(var(--ci-size) / 1.7)) rotate(var(--z)) scale(var(--s));
}
.item-7 {
/*x = -РВК / 1.2, y = 0*/
transform: translate(calc(-1 * var(--ci-size) / 1.2), 0) rotate(var(--z)) scale(var(--s));
}
.item-8 {
/*x = -РВК / 1.6, y = -РВК / 1.7*/
transform: translate(calc(-1 * var(--ci-size) / 1.6), calc(-1 * var(--ci-size) / 1.7)) rotate(var(--z)) scale(var(--s));
}
<div class="slider">
<!-- z - значение поворота; s - значение увеличеня -->
<div style="--z: 0deg" class="circle-outer">
<div style="--z: 0deg;--s: 1" class="item item-1"></div>
<div style="--z: 45deg;--s: 1" class="item item-2"></div>
<div style="--z: 90deg;--s: 1" class="item item-3"></div>
<div style="--z: 135deg;--s: 1" class="item item-4"></div>
<div style="--z: 180deg;--s: 1" class="item item-5"></div>
<div style="--z: 225deg;--s: 1" class="item item-6"></div>
<div style="--z: 270deg;--s: 1" class="item item-7"></div>
<div style="--z: 315deg;--s: 1" class="item item-8"></div>
</div>
<div class="circle-inner"></div>
</div>
