Рассчитать временные метки относительно анимации на CSS по уравнению Безье

Рейтинг: 0Ответов: 0Опубликовано: 07.02.2023

Есть приложение на Vue.js. Стоит задача реализовать колесо рулетки. При нажатии на кнопку, с бека приходит сгенерированное значение (номер сектора). Колесо должно сделать 4 полных оборота и остановиться на секторе, который пришёл с бека. На колесе 9 секторов и при прохождении каждого, должен воспроизводиться звуковой сигнал (треск, щелчок). Я написал функцию, где идёт расчёт временных меток по уравнению Безье и, используя их, воспроизвожу звук через setTimeout(). Но по-видимому где-то ошибся, потому что нет синхронизации звуков, с прохождением секторов относительно стрелки. Изначально стрелка установлена на половине сектора.

Колесо сделано из картинок (теги img):

    <div class="main__wheel">
      <div class="wheel">
        <img src="img/choose.svg" class="wheel__arrow">
        <img ref="roll" src="img/wheel-roll.png" class="wheel__roll">
      </div>
    </div>

Анимация вращения выполнена на CSS:

    transition: transform 5s cubic-bezier(0.075, 0.82, 0.165, 1);

Вот что происходит при нажатии на кнопку:

    this.sound((1440 + this.roll.offset), 5, 0, 0.075, 0.165, 1)
    this.$refs.roll.style.cssText = `
      transform: translate(-50%, -50%) rotate(-${(1440 + this.roll.offset}deg);
    `

Здесь this.roll.offset - это угловое смещение, которое зависит от значения, которое пришло с бека. this.sound() - функция, где и происходит все расчёты времени. Вот она:

    sound(angle, time, x0, x1, x2, x3) {
        const intervals = []
        for(let cut = 20; cut < angle; cut+=40) {
            const t = cut/angle
            const x = (Math.pow((1-t), 3)*x0) + 
                      (3*Math.pow((1-t), 2)*t*x1) + 
                      (3*(1-t)*Math.pow(t, 2)*x2) + 
                      (Math.pow(t, 3)*x3)
            intervals.push(((x*time)/x3)*1000)
        }
        intervals.forEach(interval => {
            setTimeout(() => {
                const audio = new Audio();
                audio.src = 'sound/sound.mp3';
                audio.autoplay = true;
            }, interval)
        })
    }

Цикл я начинаю с 20, потому что как сказал ранее начало идёт с середины сектора. каждый раз прибавляю 40, потому что 9 секторов (360/9 = 40), один сектор получается 40 градусов. Вся анимация - это поворот колеса на определённый угол (angle) исходя из этого я выполняю действие t = cut/angle, что бы найти ключевой кадр на кривой Безье. Далее идёт подсчёт координаты x - времени, но расчёт идёт в пределах единицы, поэтому далее я выполняю действие (x*time)/x3, что бы определить время, относительно времени длительности анимации и записываю всё в массив. И в самом конце запускаю аудио, по каждой временной метке в массиве. Я пробовал увеличить общее время, что бы наглядно посмотреть вращение и послушать звуки, так вот рассинхронизация очень сильная. что - то считается не правильно. Помогите найти ошибку пожалуйста.Ниже представлен скрин самого колеса

Ответы

Ответов пока нет.