Как сделать такой круговой слайдер?

Внешний вид слайдера

Нужно сделать так, чтобы элементы слайдера вращались, а активный слайд плавно увеличивался, как на макете слева. Так же текст снизу должен меняться в зависимости от выбранного слайдера. Чем проще реализация, тем лучше) Прошу помочь, не дает проект закрыть эта зараза)


Ответы (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>

→ Ссылка