基于javascript的可以自定义设置圆几等份的抽奖示例
效果示例图
代码示例
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
* {
padding: 0px;
margin: 0px;
box-sizing: border-box;
}
.cricle-wrap {
border: 1px solid red;
border-radius: 50%;
width: 400px;
height: 400px;
margin: 50px auto;
position: relative;
}
.min-cricle {
border-radius: 50%;
width: 10px;
height: 10px;
background-color: red;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.cricle-line {
width: 50%;
height: 1px;
background-color: red;
position: absolute;
top: 50%;
left: 50%;
/*
* 默认情况下,元素的动作参考点为元素盒子的中心
* 使用transform-origin改变元素原点位置
* :center center (正中)它以我的线的中间为圆点,进行旋转
* :left center (靠左居中) 它以我的线的左边为圆点,进行旋转,即我的线的最左点是固定的,来旋转
* :right center (靠右居中) 它以我的线的左右边为圆点,进行旋转,即我的线的最右点是固定的,来旋转
*/
transform-origin: left center;
}
.cricle-angle {
width: 50%;
height: 0;
position: absolute;
top: 50%;
left: 50%;
transform-origin: left center;
}
.cricle-angle-children {
width: 100%;
height: 100%;
position: relative;
}
.grandson {
border: 1px solid red;
width: 50px;
height: 30px;
position: absolute;
top: 50%;
transform: translateY(-50%) rotate(90deg);
text-align: center;
line-height: 30px;
font-size: 12px;
}
.arrow {
border: 1px solid red;
border-radius: 50%;
width: 60px;
height: 60px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) rotate(0deg);
line-height: 60px;
text-align: center;
z-index: 1;
background-color: #fff;
background-image: url("img/arrow.png");
background-position: center;
background-repeat: no-repeat;
background-size: 100% 100%;
}
.add-transition {
transition: all 3s ease-in-out;
}
#draw {
display: block;
width: 100px;
height: 40px;
margin: 12px auto;
}
</style>
</head>
<body>
<div class="cricle-wrap" id="cricle">
<!-- 圆点 -->
<div class="min-cricle"></div>
<!-- 箭头 -->
<div class="arrow"></div>
</div>
<button id="draw">抽检</button>
</body>
<script type="text/javascript">
const options = {
cricleBox: document.querySelector("#cricle"), //获取当前圆
count: 9, //圆被均等分成n份
radius: 200, //圆的半径
prizeDisc: 10, //奖品所在位置0-50,值越小,距离圆心越远
}
turntable();
function turntable() {
//每一块的弧度
const angle = 360 / options.count;
for (let i = 0; i < options.count; i++) {
let rotateAngle = i * angle;
const scaleMark = createScaleMark(rotateAngle)
options.cricleBox.appendChild(scaleMark);
const prize = createPrize(rotateAngle, angle, i);
options.cricleBox.appendChild(prize);
}
/**
* 创建刻度线
* **/
function createScaleMark(rotateAngle) {
const divs = document.createElement("div");
divs.classList.add("cricle-line");
divs.style.transform = `rotate(${rotateAngle-90}deg)`
return divs
}
/**
* 创建奖品块
* **/
function createPrize(rotateAngle, skewAngle, i) {
const prizes = document.createElement("div");
prizes.classList.add("cricle-angle");
const childrenDIvs = document.createElement("div");
childrenDIvs.classList.add("cricle-angle-children");
const grandson = document.createElement("div");
grandson.classList.add("grandson");
grandson.style.right = `${options.prizeDisc}%`
grandson.innerText = (i + 1) + '等奖';
childrenDIvs.appendChild(grandson)
prizes.appendChild(childrenDIvs)
prizes.style.transform = `rotate(${rotateAngle-90+(skewAngle/2)}deg)`
return prizes
}
}
//中奖号码
let winningNumber = 0;
//箭头旋转的角度
let rotate = 0;
//点击抽奖按钮
const arrow = document.querySelector(".arrow");
document.querySelector("#draw").addEventListener("click", () => {
winningNumber = Math.floor(Math.random() * options.count) + 1;
rotateTurntable(winningNumber);
})
function rotateTurntable(n) {
//每一块的弧度
const angle = 360 / options.count;
const skewAngle = angle / 2;
rotate += n * angle - skewAngle + 360 * 10 + (360 - rotate % 360);
arrow.classList.add("add-transition");
arrow.style.transform = `translate(-50%, -50%) rotate(${rotate}deg)`;
}
//监听动画是否结束
arrow.addEventListener("transitionend", () => {
console.log("[动画结束]")
console.log("[中奖号码]", winningNumber)
arrow.classList.remove("add-transition");
arrow.style.transform = `translate(-50%, -50%) rotate(${rotate}deg)`;
})
</script>
</html>
使用class
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
* {
padding: 0px;
margin: 0px;
box-sizing: border-box;
}
.cricle-wrap {
border: 1px solid red;
border-radius: 50%;
width: 400px;
height: 400px;
margin: 50px auto;
position: relative;
}
.min-cricle {
border-radius: 50%;
width: 10px;
height: 10px;
background-color: red;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.cricle-line {
width: 50%;
height: 1px;
background-color: red;
position: absolute;
top: 50%;
left: 50%;
/*
* 默认情况下,元素的动作参考点为元素盒子的中心
* 使用transform-origin改变元素原点位置
* :center center (正中)它以我的线的中间为圆点,进行旋转
* :left center (靠左居中) 它以我的线的左边为圆点,进行旋转,即我的线的最左点是固定的,来旋转
* :right center (靠右居中) 它以我的线的左右边为圆点,进行旋转,即我的线的最右点是固定的,来旋转
*/
transform-origin: left center;
}
.cricle-angle {
width: 50%;
height: 0;
position: absolute;
top: 50%;
left: 50%;
transform-origin: left center;
}
.cricle-angle-children {
width: 100%;
height: 100%;
position: relative;
}
.grandson {
border: 1px solid red;
width: 50px;
height: 30px;
position: absolute;
top: 50%;
transform: translateY(-50%) rotate(90deg);
text-align: center;
line-height: 30px;
font-size: 12px;
}
.arrow {
border: 1px solid red;
border-radius: 50%;
width: 60px;
height: 60px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) rotate(0deg);
line-height: 60px;
text-align: center;
z-index: 1;
background-color: #fff;
background-image: url("img/arrow.png");
background-position: center;
background-repeat: no-repeat;
background-size: 100% 100%;
}
.add-transition {
transition: all 3s ease-in-out;
}
#draw {
display: block;
width: 100px;
height: 40px;
margin: 12px auto;
}
</style>
</head>
<body>
<div class="cricle-wrap" id="cricle">
<!-- 圆点 -->
<div class="min-cricle"></div>
<!-- 箭头 -->
<div class="arrow"></div>
</div>
<button id="draw">抽检</button>
</body>
<script type="text/javascript">
class Turntable {
//中奖号码
winningNumber = 0;
//箭头旋转的角度
rotate = 0;
static OPTIONS = {
cricleBox: document.querySelector("#cricle"), //获取当前圆
arrow: document.querySelector(".arrow"), //箭头的按钮
prizeBtn: document.querySelector("#draw"), //抽奖按钮
count: 5, //圆被均等分成n份
radius: 200, //圆的半径
prizeDisc: 10, //奖品所在位置0-50,值越小,距离圆心越远
success: null
}
constructor(options) {
this.options = Object.assign({}, Turntable.OPTIONS, options);
this.init();
}
init() {
//每一块的弧度
const angle = 360 / this.options.count;
for (let i = 0; i < this.options.count; i++) {
let rotateAngle = i * angle;
const scaleMark = this.createScaleMark(rotateAngle)
this.options.cricleBox.appendChild(scaleMark);
const prize = this.createPrize(rotateAngle, angle, i);
this.options.cricleBox.appendChild(prize);
}
this.clickEvent();
}
/**
* 创建刻度线
* rotateAngle :旋转的角度
* **/
createScaleMark(rotateAngle) {
const divs = document.createElement("div");
divs.classList.add("cricle-line");
divs.style.transform = `rotate(${rotateAngle-90}deg)`
return divs
}
/**
* 创建奖品块
* rotateAngle :旋转的角度
* skewAngle:偏移量的角度
* **/
createPrize(rotateAngle, skewAngle, i) {
const prizes = document.createElement("div");
prizes.classList.add("cricle-angle");
const childrenDIvs = document.createElement("div");
childrenDIvs.classList.add("cricle-angle-children");
const grandson = document.createElement("div");
grandson.classList.add("grandson");
grandson.style.right = `${this.options.prizeDisc}%`
grandson.innerText = (i + 1) + '等奖';
childrenDIvs.appendChild(grandson)
prizes.appendChild(childrenDIvs)
prizes.style.transform = `rotate(${rotateAngle-90+(skewAngle/2)}deg)`
return prizes
}
/**
* 点击抽奖,事件处理
* **/
clickEvent() {
this.options.prizeBtn.addEventListener("click", () => {
this.winningNumber = Math.floor(Math.random() * this.options.count) + 1;
this.rotateTurntable(this.winningNumber);
})
//监听动画是否结束
this.options.arrow.addEventListener("transitionend", () => {
console.log("[动画结束]")
this.options.arrow.classList.remove("add-transition");
this.options.arrow.style.transform = `translate(-50%, -50%) rotate(${this.rotate}deg)`;
this.options.success && this.options.success(this.winningNumber)
})
}
/**
* 转动箭头到指定奖品
* **/
rotateTurntable(n) {
//每一块的弧度
const angle = 360 / this.options.count;
const skewAngle = angle / 2;
this.rotate += n * angle - skewAngle + 360 * 10 + (360 - this.rotate % 360);
this.options.arrow.classList.add("add-transition");
this.options.arrow.style.transform = `translate(-50%, -50%) rotate(${this.rotate}deg)`;
}
}
new Turntable({
cricleBox: document.querySelector("#cricle"), //获取当前圆
arrow: document.querySelector(".arrow"), //箭头的按钮
prizeBtn: document.querySelector("#draw"), //抽奖按钮
count: 9, //圆被均等分成n份
radius: 200, //圆的半径
prizeDisc: 10, //奖品所在位置0-50,值越小,距离圆心越远
success: (response) => {
console.log(`${response}等奖`)
}
});
</script>
</html>