html转盘抽奖,conic-gradient+transform,复制即用~
首先了解下conic-gradient
CSS 函数
conic-gradient()
创建一个由渐变组成的图像,渐变的颜色围绕一个中心点旋转(而不是从中心辐射);用conic-gradient()
即可画出转盘扇形布局,如下
html
<!-- 由此我们可以画出4块扇形 -->
<div style="margin: 0 auto">
<div class="conic-gradient"></div>
</div>
<style>
.conic-gradient {
width: 200px;
height: 200px;
border-radius: 9999px;
background-image: conic-gradient(
green 0deg,
green 90deg,
red 90deg,
red 180deg,
pink 180deg,
pink 270deg,
blue 270deg,
blue 360deg
);
}
</style>
如图:
transfrom
如此我们可以借助transfrom:rotate旋转+transition过渡+时间缓动函数写一个转盘旋转效果;
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
<style>
.conic-gradient {
width: 200px;
height: 200px;
border-radius: 9999px;
background-image: conic-gradient(
green 0deg,
green 90deg,
red 90deg,
red 180deg,
pink 180deg,
pink 270deg,
blue 270deg,
blue 360deg
);
transition: transform 3s cubic-bezier(0.25, 0.1, 0.25, 1);
transform: rotate(0deg);
}
</style>
</head>
<body>
<div
style="
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
"
>
<div class="conic-gradient"></div>
<button style="margin-top: 50px">旋转1800度</button>
</div>
<script>
const btn = document.querySelector("button");
btn.addEventListener("click", () => {
const conic = document.querySelector(".conic-gradient");
conic.style.transform = "rotate(1800deg)";
});
</script>
</body>
</html>
如图所示,现在一个简单的转盘旋转效果就完成啦~
接着定义抽奖数组,初始化转盘
js
//抽奖数组
let prizes = [
{ name: 'iPhone 15 Pro', imageUrl: '📱', uid: '1' },
{ name: 'iPad Air', imageUrl: '📱', uid: '2' },
{ name: 'AirPods Pro', imageUrl: '🎧', uid: '3' },
{ name: 'Apple Watch', imageUrl: '⌚', uid: '4' },
{ name: 'MacBook Pro', imageUrl: '💻', uid: '5' },
{ name: '现金红包', imageUrl: '💰', uid: '6' },
{ name: '优惠券', imageUrl: '🎫', uid: '7' },
{ name: '谢谢惠顾', imageUrl: '😭😭', uid: '0' }
]
//在定义几个需要的变量
/* 旋转角度 */
let rotateDeg = 0;
/* 是否正在旋转 */
let isSpinning = false;
/* 是否正在过渡 */
let transitionActive = true;
//初始化转盘
function initWheel() {
const wheel = document.getElementById('wheel');
const prizeCount = prizes.length;
const anglePerPrize = 360 / prizeCount;
wheel.innerHTML = '';
//根据奖品数组,生成奖品子元素
prizes.forEach((prize, idx) => {
const prizeElement = document.createElement('div');
prizeElement.className = 'prize';
prizeElement.style.transform = `rotate(${idx * 360 / prizes.length + 360 / prizes.length / 2}deg) translateY(-180px)`;
prizeElement.innerHTML = `
<div>${prize.name}</div>
<div class="prize-icon">${prize.imageUrl}</div>
`;
wheel.appendChild(prizeElement);
});
// 更新转盘样式
updateWheelStyle();
}
// 计算转盘样式
function getWheelStyle() {
//计算扇形角度
const deg = 360 / prizes.length;
//扇形颜色,这里我复用了3个颜色
const colors = ['#fff5e1', '#ffbb93', '#ffe4ca'];
//拼接conic-gradient
const prizesGradient = prizes.map((item, idx) => {
return `${colors[idx > 2 ? idx % 3 : idx]} ${idx * deg}deg ${(idx + 1) * deg}deg`;
}).join(',');
return {
transform: `rotate(${rotateDeg}deg)`,
transition: transitionActive ? 'transform 3s cubic-bezier(0.25, 0.1, 0.25, 1)' : 'none',
background: `conic-gradient(${prizesGradient})`
};
}
// 更新转盘样式
function updateWheelStyle() {
const wheel = document.getElementById('wheel');
const style = getWheelStyle();
wheel.style.transform = style.transform;
wheel.style.transition = style.transition;
wheel.style.background = style.background;
}
初始化后样式如图:
抽奖函数
js
function startLottery() {
if (isSpinning) return;
isSpinning = true;
/* 模拟接口请求 */
setTimeout(() => {
/* 中奖下标 */
const prizeIndex = Math.floor(Math.random() * prizes.length);
/* 奖品数量 */
const prizeCount = prizes.length;
/* 每个奖品的角度 */
const anglePerPrize = 360 / prizeCount;
/* 旋转4圈 */
const baseRotate = 360 * 4;
/* 目标角度,正好旋转到奖品中间 */
const targetDeg = baseRotate + (360 - prizeIndex * anglePerPrize) - anglePerPrize / 2
/* 取消过渡 */
transitionActive = false;
/* 旋转角度 */
rotateDeg = rotateDeg % 360;
/* 更新样式 */
updateWheelStyle();
setTimeout(() => {
transitionActive = true;
/* 更新样式-开始过渡 */
updateWheelStyle();
setTimeout(() => {
/* 中奖奖品角度 */
rotateDeg = targetDeg;
/* 更新样式-旋转到目标角度 */
updateWheelStyle();
setTimeout(() => {
/* 过渡时间是3秒,所以三秒后再赋值为false,抽奖完成 */
isSpinning = false;
console.log(prizes[prizeIndex])
alert(prizes[prizeIndex].name)
}, 3000);
}, 20);
}, 300);
}, 500)
}