Врукопашную. Завершите лотерею H5

JavaScript

Чтобы выполнить лотерею, подобную этой

идея

  1. Наградные предметы получаются через интерфейс (img)
  2. Результат вознаграждения получается через интерфейс (id)
  3. Анимация лотереи должна быть от медленной до быстрой, а затем медленной.
  4. Время вращения лотереи не может быть слишком коротким
  5. Требуется обратный звонок после окончания розыгрыша
  6. Бизнес-код и код функции должны быть разделены

Сначала завершите пользовательский интерфейс

Используйте flex для макета, легко, когдаcurGameIdxРавный текущим призамindexвыделять

html

    <div class="game-box">
        <template
        v-for="(val, idx) of boundList">
        <div v-if="idx == 4" class="game-item game-begin" 
            :key="idx"
            @click="beginGame">
            开始游戏
        </div>
        <div v-else :key="idx"
            class="game-item"
            :class="{
            active: idx === curGameIdx
            }">
            {{val}}
        </div>
        </template>
    </div>

css

    .game-box {
        display: flex;
        flex-wrap: wrap;
        text-align: center;
        .game-item {
            width: 1.25rem;
            height: 0.3rem;
            background: yellow;
            border: 1px solid transparent;
            transition: all 0.2s;
            &.game-begin {
                background: transparent;
            }
            &.active {
                border: 1px solid black;
            }
        }
    }

визуализация

начать анимацию

создать новыйGameизclass, EстьrunМетоды иfinishметод

начать работу

Скорость анимации варьируется, используйтеrequestAnimationFrameа такжеsetIntervalНемного неуместно, поэтому: можно использоватьsetTimeout + speed 参数для управления скоростью анимации.

class Game {
    constructor(idx) {
        this.idx = idx;
        this.speed = 400;
    }

    addIdx(){
    }

    speedControl() {
    }

    finish() {
    }

    run(cb) {
        this.addIdx();
        this.speedControl();
        setTimeout(() => {
            !this.isFinish && this.run(cb);
        }, this.speed);
    }
}

конец пробега

При получении уведомления о завершении операции необходимо сначала выполнить анимацию замедления, а затем остановиться на соответствующемnum, затем вызывается функция обратного вызова, поэтому сначала создайте обратный вызов конца и конечную точку и установите замедление анимации.

    finish(num, finishCb) {
        this.oil = false;
        this.endIdx = num;
        this.finishCb = finishCb;
    }

контроль скорости

  1. Скорость по умолчанию — ускорение (this.oil = true) для остановки ускорения в зависимости от того, достигнута ли желаемая скорость, и то же самое верно при замедлении.
  2. Чтобы достичь конечного эффекта смягчения, конечное время проходит: достигается минимальная скорость и достигается конечное положение.
    speedUp() {
        this.speed -= 60;
    }

    speedDown() {
        this.speed += 200;
    }

    speedControl() {    
        if (this.speed > this.Max_Speed) {
            if (this.oil) {
                this.speedUp();
            }
        }
        if (!this.oil) {
            if (this.speed < this.Min_Speed) {
                this.speedDown();
            } else if (this.endIdx === this.idx) {
                this.isFinish = true;
                typeof this.finishCb === 'function' && this.finishCb();
            }
        }
    }

коррекция индекса

На этом этапе вышеуказанный пользовательский интерфейс проходит черезv-for + flexотображается, а выполнение анимации кругом, значит надо поправитьindex

изменить вышеaddIdxметод, исправьте индекс и установите++indexостаток

    constructor(idx) {
        this.idx = idx;
        this.speed = 400;
        this.order = null;
        this.Order_List = [0,1,2,5,8,7,6,3];
        this.Game_Box_Num = 8;
    }

    addIdx() {
        this.idx = (++this.idx % this.Game_Box_Num);
        this.order = this.Order_List[this.idx];
    }

Код активности взаимодействует с бизнес-кодом

Передайте функцию, которая требует взаимодействия, вGameслучай

  // vue 代码
  methods: {
    updateGameIdx(order) {
      this.curGameIdx = order; 
    },
    gameFinish() {
      this.playing = false;
      console.log(this.curGameIdx, 'curGameIdx')
    },
    beginGame() {
      if (this.playing) return;
      this.playing = true;
      this.curGameIdx = 0;
      const game = new Game(this.curGameIdx);
      game.run(this.updateGameIdx);
      // 通过请求终止
      setTimeout(() => {
        game.finish(2, this.gameFinish)
      }, 3000);
    }
  }

Наконец, прикрепите полный код игры:

class Game {
  constructor(idx) {
    this.idx = idx;
    this.speed = 400;
    this.oil = true;
    this.isFinish = false;
    this.endIdx = null;
    this.finishCb = function() {}
    // 常量
    this.Max_Speed = 100;
    this.Min_Speed = 500;
    this.Order_List = [0,1,2,5,8,7,6,3];
    this.Game_Box_Num = 8;
  }

  speedUp() {
    this.speed -= 60;
  }

  speedDown() {
    this.speed += 200;
  }

  speedControl() {
    if (this.speed > this.Max_Speed) {
      if (this.oil) {
        this.speedUp();
      }
    }
    if (!this.oil) {
      if (this.speed < this.Min_Speed) {
        this.speedDown();
      } else if (this.endIdx === this.idx) {
        this.isFinish = true;
        typeof this.finishCb === 'function' && this.finishCb();
      }
    }
  }

  finish(num, finishCb) {
    this.oil = false;
    this.endIdx = num;
    this.finishCb = finishCb;
  }

  addIdx() {
    this.idx = (++this.idx % this.Game_Box_Num);
  }

  run(cb) {
    this.addIdx();
    typeof cb === 'function' && cb(this.Order_List[this.idx]);
    this.speedControl();
    setTimeout(() => {
      !this.isFinish && this.run(cb);
    }, this.speed);
  }
}

export default Game;

общий эффект

Реализованы основные функции.Хочешь быть красивее, можешь изменить CSS.Также нужно отладить время анимации. (Чтобы избежать подозрений, конкретные результаты не могут быть предоставлены - -.)

наконец

Переводчик написал UI-библиотеку React + Hooks, которую удобно изучать и использовать всем.

Битва проекта React + Hooks

Добро пожаловать в номер общественного интереса «Передний продвинутый курс», серьезно изучите передний план, продвинулись вместе.