【css】转盘游戏实现

前言

  • 转盘游戏是经常要制作的小游戏,看别人用渐变实现很有意思,一个转盘也是很复杂的。
  • 本文实现参考了徐小夕大佬的公众号。

样式部分

  • 单个扇形实现:利用border-radius和linear-gradient来渐变。
  • 做扇形还有一种思路,就是先做正方形,然后用skew进行形变,变成菱形,再定位到相应位置,拿容器overflow hidden一下就行。
  • 这里采用linear-gradient,另外上面那个指针,我是用宽高为0的div的边框做的。
    效果:
    在这里插入图片描述
$pieceHeight = 300px  //这个可以控制大小
$degree =30deg       //控制片数 360/30=12
$pieceWidth = $pieceHeight/2
$linearwidth = $pieceWidth/2  //度数变更需要调整线性变化使得截取长度固定
$lineardegree = 90+$degree
$piece = 360/$degree
$pointHeight = 50px
$pointWidth = 20px

body
  font-family:'Microsoft YaHei';
  margin: 0
  padding: 0
  overflow hidden //旋转的容器过长,防止因旋转产生滑块
#viewport
  margin 0 auto
  width 300px
  height: 300px
  transform-origin: left
  left:($pieceWidth)
  position relative
  for i in (1..$piece)
    div:nth-child({i})
      transform: rotate(($degree)*i) 
      transform-origin: left
      if (i%2==0)
        background-image: linear-gradient(($lineardegree),red $linearwidth, transparent $linearwidth);
      else
        background-image: linear-gradient(($lineardegree),grey $linearwidth, transparent $linearwidth);
.slice
  width $pieceWidth
  height $pieceHeight
  border-radius: 0 $pieceWidth $pieceWidth 0
  position absolute
  left 0
  top 0
  span
    display: inline-block
    margin-top:12px
    transform:rotate(13deg)//调整文字旋转
    margin-left:8px
    color #fff
    background transparent
.pwrap
  margin 0 auto
  width ($pointWidth*2)
  height $pointHeight
#point
  width:0 
  height 0
  position absolute
  border-width: $pointWidth
  border-top-width: $pointHeight
  border-style: solid 
  transform  translateY(($pointHeight/2)) 
  border-color: black transparent transparent transparent
  z-index 1
.start
  display: flex
  justify-content: center
  margin-top: 10px
  span 
    float left  //不支持flex使用此兼容
    font-size: 20px
    padding: 5px
    background brown
    border-radius: 5px
    color: white
    box-shadow: black 0 0 10px 2px
    cursor pointer

JS部分

在这里插入图片描述

  • 这里一共有12片,我们思路就可以随机0到11,这样可以直接知道中奖的是哪个,然后多转几个360度就可以。所以这里我们需要旋转的度数等于初始的第一个元素位置的度数+中奖度数*每片所占度数+每片所占度数的一半(让指针停在中间)。
  • 核心逻辑就是这个,另外抽完了需要重置transform和transition,不然下次就已经转了这么多圈。
import './main.styl'

let bouns = ['一等奖','二等奖','三等奖','四等奖','五等奖','六等奖',
'纪念奖','参与奖','没有奖','特别奖','六等奖','五等奖']
let fragment = document.createDocumentFragment()
bouns.forEach((item,index)=>{
    let piece = document.createElement('div')
    piece.className='slice slice-'+index
    piece.innerHTML='<span>'+item+'</span>'
    fragment.appendChild(piece)
})
document.querySelector('#viewport').appendChild(fragment)
let degree = 30
let initdegree  = 720//转2圈
let time = 16*1000  //转动时间
let isclick = true 
document.querySelector('.start > span').onclick=function(e){
    if(isclick){
        let n = randomArr(0,(360/degree)-1)//n就是抽中第几个 12片就是0-11
        let totaldegree = -(degree*(n+1)+initdegree+degree*0.5 )//转的度数还要加上扇形一半,这样每次转到中间
        isclick =false
        let div = document.querySelector('#viewport')
        div.style.transform='rotate('+totaldegree+'deg)'
        div.style.transition='transform 16s cubic-bezier(0,.47,.31,1.03)'
        setTimeout(() => {
            alert('抽中了'+bouns[n]+'!');
            isclick=true
            div.style.transform='rotate('+ 0 +'deg)'
            div.style.transition='none'
        }, time);
    }
}
function randomArr (start,end){
    return Math.round(start+Math.random()*(end-start))
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

业火之理

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值