Вращение колеса фортуны к заданому сектору

Необходимо вращать колесо фортуны к заранее определенным секторам. Есть массив объектов для вывода в дом значений на секторах в колесе фортуны (sectors). Также есть массив выигрышных вариантов (winningSectors). Необходимо вращать колесо к заданным секторам. Колиество попвыток вращения определяется длинной массива winningSectors Ниже код из компонента Vue. Пример на основании которого сверстал колесо можно глянуть здесь https://codepen.io/stoumann/pen/yLWJPMr

Можете подсказать в чем моя ошибка.

<script setup>
import { ref, onMounted } from 'vue'

// Секторы с призами
const sectors = [
  { id: 1, value: 1000, name: 'название' }, // 0 deg
  { id: 2, value: 2000, name: 'название' }, // 45 deg
  { id: 3, value: 3000', name: 'название' }, // 90 deg
  { id: 4, value: 4000, name: 'название' }, // 135 deg
  { id: 5, value: 5000', name: 'название' }, // 180 deg
  { id: 6, value: 6000, name: 'название' }, // 225 deg
  { id: 7, value: 7000, name: 'название' }, // 270 deg
  { id: 8, value: 8000, name: 'название' } // 315 deg
]
const winningSectors = [5, 6] // 180 deg, 225 deg

let currentSpin = 0

const isSpinning = ref(false)
const isModalVisible = ref(false)
const wheelRef = ref(null)
const isButtonDisabled = ref(false)
let previousEndDegree = ref(0)

const emit = defineEmits(['updateModal', 'updateSpinning'])

const extractValue = (value) => {
  const match = String(value).match(/[\d.]+/)
  return match ? match[0] : ''
}

const spinWheel = () => {
  if (currentSpin >= winningSectors.length) {
    isButtonDisabled.value = true
    return
  }

  isSpinning.value = true

  const spins = Math.floor(Math.random() * 2) + 3 // От 3 до 4 полных оборотов
  console.log('spins:', spins)
  const sectorsCount = sectors.length
  const degreesPerSector = 360 / sectorsCount // Угол одного сектора 360 / 8 = 45
  const winningSector = winningSectors[currentSpin] // Текущий выигрышный сектор
  console.log('winningSector:', winningSector) // 5, 6

  const winningAngle = (winningSector - 1) * degreesPerSector 
  console.log('winningAngle:', winningAngle)

  const totalRotation = 360 * spins + winningAngle
  console.log('totalRotation:', totalRotation)

  const wheel = wheelRef.value
  let animation

  if (animation) {
    animation.cancel() // Сбросить предыдущую анимацию
  }

  animation = wheel.animate(
    [
      { transform: `rotate(${previousEndDegree.value}deg)` },
      { transform: `rotate(${previousEndDegree.value + totalRotation}deg)` }
    ],
    {
      duration: 4000,
      direction: 'normal',
      easing: 'cubic-bezier(0.440, -0.205, 0.000, 1.130)',
      fill: 'forwards',
      iterations: 1
    }
  )

  previousEndDegree.value += totalRotation // Обновляем предыдущий угол

  setTimeout(() => {
    isSpinning.value = false
    currentSpin++ 

    if (currentSpin === winningSectors.length) {
      isModalVisible.value = true
      emit('updateModal', true)
    }

    emit('updateSpinning', false)
  }, 4000)
}

onMounted(() => {
  const wheel = wheelRef.value
  wheel.style.transform = `rotate(${previousEndDegree.value}deg)`
})
</script>

<template>
  <div class="wheel">
    <div class="wheel__inner">
      <fieldset class="wheel-of-fortune" ref="wheelRef">
        <ul>
          <li
            v-for="sector in sectors"
            :key="sector.value"
            class="wheel__prize"
            :class="`wheel__prize-${sector.id}`"
          >
            <span class="wheel__prize-group">
              <span>
                <span>+</span>
                <span class="wheel__prize-value">
                  {{ extractValue(sector.value) }}
                </span>
                <span v-if="sector.name === 'депозит'">%</span>
              </span>
              <span class="wheel__prize-text">{{ sector.name }}</span>
            </span>
          </li>
        </ul>
      </fieldset>
      <div class="wheel__cursor">
        <img
          src="@/assets/images/cursor.png"
          alt="Cursor image"
          width="137"
          height="107"
        />
      </div>
    </div>

    <button
      class="btn-cta"
      style="flex-shrink: 0"
      @click="spinWheel"
      :disabled="isSpinning"
    >
      <span class="btn-cta__text">Крутить</span>
    </button>
  </div>
</template>

.wheel-of-fortune {
  --_items: 8;
  all: unset;
  aspect-ratio: 1 / 1;
  container-type: inline-size;
  direction: ltr;
  display: grid;
  position: relative;
  width: 100%;

  position: relative;
  background: linear-gradient(0deg, #8133ff, #8133ff),
    linear-gradient(45.93deg, #a600f4 30.63%, #5142ff 84.05%);
  // padding: 20px;
  padding: 1.38888cqi;
  padding: calc((20 * 100%) / 430);
  // box-shadow: inset 0px 3.30732px 40.9281px #260044;
  border-radius: 50%;

  &--spinning {
    // animation: spin 3s cubic-bezier(0.5, 0, 0.5, 1) forwards;

    // animation:
    //   spin 3s cubic-bezier(0.5, 0, 0.5, 1) forwards,
    //   wobble 0.5s ease-in-out 3s infinite;

    animation:
      spin 4s cubic-bezier(0.25, 1, 0.5, 1) forwards,
      wobble 1s ease-in-out 4s infinite;
  }

  &::before {
    content: '';
    position: absolute;
    z-index: 999;
    display: block;
    width: 100%;
    height: 100%;
    border-radius: 50%;
    box-shadow: inset 0px 3.30732px 40.9281px #260044;
  }

  & > * {
    position: absolute;
  }

  ul {
    all: unset;
    clip-path: inset(0 0 0 0 round 50%);
    display: grid;
    inset: 0;
    place-content: center start;

    li {
      align-content: center;
      aspect-ratio: 1 / calc(2 * tan(180deg / var(--_items)));
      // clip-path: polygon(0% 10%, 100% 50%, 0% 90%);
      clip-path: polygon(0% 0%, 100% 50%, 0% 100%);
      display: grid;
      font-size: 5.3cqi;
      grid-area: 1 / -1;
      padding-left: 0.7ch;
      rotate: calc(360deg / var(--_items) * calc(var(--_idx) - 1));
      transform-origin: center right;
      user-select: none;
      width: 50cqi;

      &:nth-of-type(1) {
        --_idx: 1;
      }
      &:nth-of-type(2) {
        --_idx: 2;
      }
      &:nth-of-type(3) {
        --_idx: 3;
      }
      &:nth-of-type(4) {
        --_idx: 4;
      }
      &:nth-of-type(5) {
        --_idx: 5;
      }
      &:nth-of-type(6) {
        --_idx: 6;
      }
      &:nth-of-type(7) {
        --_idx: 7;
      }
      &:nth-of-type(8) {
        --_idx: 8;
      }
    }
  }
}

Написал скрипт для вращения колеса, но не могу определить точную останоку колеса на заданных выигрышных вариантах.


Ответы (0 шт):