转盘
实现一个九宫格,其中点击按钮居中,剩余八个方格为礼品格,实现抽奖动画
布局
实现九宫格布局采用grid
布局,其中采用grid-template-areas
属性可指定所划分的九宫格各个格子的名称,方便之后对这些方格进行填充
.plate-container {
display: grid;
grid-template-rows: repeat(3, auto);
grid-template-columns: repeat(3, auto);
grid-template-areas: 'a b c'
'd e f'
'h i j';
}
抽奖按钮需要指定到抽奖盘正中间区域,可以采用grid-area
属性指定布置区域
.plate-button {
grid-area: e;
}
剩余位置自适应布置即可
抽奖动画
高亮效果实现方式
当轮盘转到某一个礼品方块的时候,该方块高亮,此处采取方式为将该方块的box-shadow
属性调节为亮色,实现视觉上的高亮效果
less实现
@gift-shadow-color: #815F22;
@gift-active-shadow-color: #fff;
.plate-gift {
box-shadow: 0 4px 4px @gift-shadow-color;
}
.plate-gift-active {
box-shadow: 0 0 40px #fff;
}
JavaScript实现
item.style.boxShadow = '0 0 40px #fff';
指定特定抽奖格高亮
此处采取的方式是给每一个对应的礼品方块格加上相应的类item-idx
,此处的idx
对应0~8
由于填充grid
布局的抽奖转盘的方式是v-for
,因此可采用如下方式添加相应的class
<div class="plate-container">
<img class="plate-button" src="..." @click="getGiftFunc" />
<img class="plate-gift" v-for="(item, idx) in giftArr" :src="item.url" :key="idx" :class="`item-${matchOrder[idx]}`" <!--添加动态类唯一标识-->
</div>
此处的matchOrder
是一个按行排列映射到逆时针旋转方式排列的映射表
排序 | 顺序 | |||||
---|---|---|---|---|---|---|
1 | 2 | 3 | 1 | 2 | 3 | |
4 | 5 | ——》 | 8 | 4 | ||
6 | 7 | 8 | 7 | 6 | 5 |
即matchOrder=[0,1,2,7,3,6,5,4]
动画实现
// vue2的method中
// 控制转盘速度先慢后快再慢
bounce(now, sum) {
// 一元二次方程
const n = 0.2 * ((now - sum / 2) ** 2) + 20
return n
}
getGiftFunc() {
// 判断是否已登录
// 判断是否有剩余抽奖机会
this.getTheGift()
// 抽奖机会减一
}
getTheGift() {
const time = this.times, // 获取已经执行动画次数
n = time % 8,
className = `item-${n}`,
item = document.getElementsByClassName(className)[0];
if(time === 0){
// 随机生成一个转盘转数
this.randomTimes = Math.floor(Math.random() * 8 + 56)
}
else if(time === this.randomTimes) {
this.times = 0
// 获得奖品逻辑
return;
}
// 实现转速变化
const delay = this.bounce(time, this.randomTimes)
item.style.boxShadow = '0 0 40px #fff'
setTimeout(() => {
this.times++
item.style.boxShadow = '0 4px 4px #815f22'
this.getTheGift();
}, delay)
}