Чтобы выполнить лотерею, подобную этой
идея
- Наградные предметы получаются через интерфейс (img)
- Результат вознаграждения получается через интерфейс (id)
- Анимация лотереи должна быть от медленной до быстрой, а затем медленной.
- Время вращения лотереи не может быть слишком коротким
- Требуется обратный звонок после окончания розыгрыша
- Бизнес-код и код функции должны быть разделены
Сначала завершите пользовательский интерфейс
Используйте 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;
}
контроль скорости
- Скорость по умолчанию — ускорение (
this.oil = true) для остановки ускорения в зависимости от того, достигнута ли желаемая скорость, и то же самое верно при замедлении. - Чтобы достичь конечного эффекта смягчения, конечное время проходит: достигается минимальная скорость и достигается конечное положение.
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, которую удобно изучать и использовать всем.
Добро пожаловать в номер общественного интереса «Передний продвинутый курс», серьезно изучите передний план, продвинулись вместе.