在线预览地址:
今天吃什么https://jujubefoxx.github.io/WhatDoWeHaveToEat-/
代码: https://github.com/jujubefoxx/WhatDoWeHaveToEat-https://github.com/jujubefoxx/WhatDoWeHaveToEat- 效果图:
下面是代码
HTML
<div id="toEat">
<div class="wrapper">
<div :class=['light',onRotation?'light-twinkling':''] v-for="light in foodList"></div>
<div class="panel">
<div class="sector" v-for="food in foodList">
<div class="sector-inner">
<span>{{ food }}</span>
</div>
</div>
<div :class=["pointer",onRotation?'pointer-trans':''] @transitionend="afterTransitionend"
@click="handleClick">吃什么呢
</div>
</div>
</div>
<div class="result">{{ result }}</div>
<div class="button" @click="showEdit=true">编辑配置</div>
<div v-if="showEdit" id="popBox">
<div class="close">
<a href="javascript:void(0)" @click="showEdit=false">关闭</a>
</div>
<div class="content">
<div class="content-title">
当前配置
</div>
<div>
<ul>
<li class="popBox-list" v-for="(food,index) in foodList">
{{ food }}
<a class="edit-button" href="javascript:void(0)" @click="handleEdit(index)">修改</a>
</li>
</ul>
</div>
</div>
</div>
</div>
样式部分参考自https://www.cnblogs.com/wenruo/p/9732704.html 包括下面JS中旋转的方法
/* 样式参考自https://www.cnblogs.com/wenruo/p/9732704.html*/
* { /* 重置默认样式 */
margin: 0;
padding: 0;
border: none;
outline: none;
user-select: none;
}
.wrapper {
position: relative;
height: 200px;
width: 200px;
padding: 20px;
background-color: #ff5555;
box-shadow: #000000 0px 0px 10px;
border-radius: 50%;
margin: 20px auto;
}
.light {
position: absolute;
height: 10px;
width: 10px;
border-radius: 50%;
top: 5px;
left: 115px;
transform-origin: 5px 115px;
}
.light-twinkling {
animation: 1s twinkling 3, 100ms 3s twinkling 3;
}
.light:nth-child(2n) {
background-color: #fafce7;
}
.light:nth-child(2n+1) {
background-color: #ffe58b;
}
.light:nth-child(2) {
transform: rotate(36deg);
}
.light:nth-child(3) {
transform: rotate(72deg);
}
.light:nth-child(4) {
transform: rotate(108deg);
}
.light:nth-child(5) {
transform: rotate(144deg);
}
.light:nth-child(6) {
transform: rotate(180deg);
}
.light:nth-child(7) {
transform: rotate(216deg);
}
.light:nth-child(8) {
transform: rotate(252deg);
}
.light:nth-child(9) {
transform: rotate(288deg);
}
.light:nth-child(10) {
transform: rotate(324deg);
}
.panel {
position: relative;
height: 200px;
width: 200px;
background-color: #b7b7b7;
border-radius: 100px;
}
.sector {
position: absolute;
left: 100px;
top: 0px;
width: 100px;
height: 200px;
font-size: 14px;
border-radius: 0px 100px 100px 0;
overflow: hidden;
transform-origin: left center;
}
.sector:nth-child(1) {
transform: rotate(-18deg);
}
.sector:nth-child(2) {
transform: rotate(18deg);
}
.sector:nth-child(3) {
transform: rotate(54deg);
}
.sector:nth-child(4) {
transform: rotate(90deg);
}
.sector:nth-child(5) {
transform: rotate(126deg);
}
.sector:nth-child(6) {
transform: rotate(162deg);
}
.sector:nth-child(7) {
transform: rotate(198deg);
}
.sector:nth-child(8) {
transform: rotate(234deg);
}
.sector:nth-child(9) {
transform: rotate(270deg);
}
.sector:nth-child(10) {
transform: rotate(306deg);
}
.sector:nth-child(2n+1) .sector-inner {
background: #fef6e0;
}
.sector:nth-child(2n) .sector-inner {
background: #ffffff;
}
.sector-inner {
text-align: center;
display: block;
width: 40px;
padding: 5px 3px 0 57px;
height: 195px;
transform: translateX(-100px) rotate(36deg);
transform-origin: right center;
border-radius: 100px 0 0 100px;
}
.sector-inner span {
display: block;
transform-origin: center;
transform: rotate(-19deg);
color: #d46854;
}
.pointer-trans {
transition: transform 3s cubic-bezier(.2, .93, .43, 1);
}
.pointer {
position: absolute;
left: 79px;
top: 79px;
z-index: 10;
height: 30px;
width: 30px;
padding: 6px;
color: #fff899;
line-height: 15px;
font-size: 12px;
text-align: center;
background-color: #ff5350;
border-radius: 50%;
border: 1px solid #ff5350;
}
.pointer::after {
content: '';
position: absolute;
left: 14px;
top: -24px;
border-width: 12px 6px;
border-style: solid;
border-color: transparent;
border-bottom-color: #ff5350;
transform-origin: center;
}
.button {
cursor: pointer;
padding: 5px;
margin: 20px auto;
width: 100px;
background-color: #d46854;
color: #fff;
text-align: center;
border-radius: 4px;
}
.result {
height: 50px;
line-height: 50px;
text-align: center;
/*margin: 20px 60px;*/
margin: 0 auto;
}
/*背景层*/
#popLayer {
display: none;
background-color: #B3B3B3;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 10;
-moz-opacity: 0.8;
opacity: .80;
filter: alpha(opacity=80); /* 只支持IE6、7、8、9 */
}
#popBox {
background-color: #FFFFFF;
z-index: 11;
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border-radius: 8px;
overflow: hidden;
box-shadow: 3px 3px 5px #2D2C3B;
}
#popBox .content {
padding: 15px;
font-size: 14px;
text-align: left;
line-height: 25px;
}
#popBox .close {
text-align: right;
margin-right: 5px;
font-size: 12px;
height: 25px;
line-height: 25px;
background-color: #F8F8F8;
}
/*关闭按钮*/
#popBox .close a {
color: #2D2C3B;
}
a {
text-decoration: none;
}
.content-title {
font-weight: 600;
margin-bottom: 10px;
}
.popBox-list {
display: flex;
justify-content: space-between;
align-items: center;
margin: 10px 0;
}
.edit-button {
height: 20px;
font-size: 12px;
line-height: 20px;
margin-left: 50px;
background: #d46854;
color: #f2f2f2;
padding: 3px;
font-family: 微软雅黑, 宋体, Arial, Helvetica, Verdana, sans-serif;
border-radius: 3px;
-webkit-transition: all linear 0.30s;
-moz-transition: all linear 0.30s;
transition: all linear 0.30s;
}
.edit-button:hover {
background: #385f9e;
}
@keyframes twinkling {
50% {
background: transparent;
}
}
JS部分
<!--引入cdn-->
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
const toEat = new Vue({
//挂载
el: "#toEat",
data() {
return {
foodList: ["北京烤鸭", "烧鸡", "快餐", "麻辣烫", "炒饭", "面", "寿司", "烤肉", "火锅", "饺子"],//食物列表
onRotation: false, // 记录当前是否正在旋转,如果正在旋转,就不能继续点击了
result: '点击中间按钮看看今天吃啥',//结果文案
nextStatus: {},//转盘的下一个状态
showEdit: false //是否处于编辑状态
}
},
methods: {
afterTransitionend() {
const {nextStatus} = this;
setTimeout(() => { // 等闪烁三下结束
this.onRotation = false; //结束旋转状态
this.result = nextStatus.text; //更新结果文案为下一步状态的文案
}, 300);
},
//获得当前结果
getReward() {
let getEle = document.getElementsByClassName.bind(document);
let pointer = getEle('pointer')[0]; //获取指针元素
let currentDeg = this.nextStatus.deg ? this.nextStatus.deg : 0; //如果当前已有角度则获取角度 无则为0
// 转三圈到四圈
let rotateDeg = Math.random() * 360 + 1080;
currentDeg += rotateDeg; //加上旋转的随机角度
let rewardText = this.foodList[Math.floor((currentDeg + 18) % 360 / 36)] //获取结果位置的食物
this.nextStatus = {
deg: currentDeg,
text: `就决定是你了!${rewardText}`
} //更新下一步状态
pointer.style.transform = `rotateZ(${this.nextStatus.deg}deg)`; //旋转+动画
},
//重置
reset() {
this.onRotation = false; //关闭旋转状态
this.result = ' '; //结果清空
},
// 功能1:转动转盘
// 1.点击中间按钮转动转盘
// 2.获得结果并显示
// 3.制作灯闪效果
handleClick() {
if (this.onRotation) return; //如果在旋转 不执行
this.reset(); //重置
this.onRotation = true; //开启旋转状态 禁止点击事件
this.getReward();//获取结果
},
handleEdit(index) {
const value = prompt(`请输入需要替换${this.foodList[index]}的事物`); //弹出输入框
if (value) {
Vue.set(this.foodList, index, value) //更新新的值
}
}
}
});
</script>