lucky-canvas(大转盘)使用文档

6 篇文章 0 订阅
1 篇文章 0 订阅

大转盘 LuckyWheel 使用文档

安装

npm install luck-cmft --save

引用

import { LuckyWheel  } from luck-cmft

使用

<template>
    <div class="wrap">
        <div id="wheel-test"></div>
    </div>
</template>
   let luckyWheel = new LuckyCanvas.LuckyWheel({
     el: '#my-lucky',
     width: '300px',
     height: '300px',
   }, {
     // 参数
   }) 

参数

背景 - blocks

  • blocks?: Array<object> 背景
    • padding?: string 内边距 (为了保证大转盘是一个标准的圆, 所以 padding 只能输入一个值)
    • background?: string 背景颜色 (可填写16进制颜色哈希值或 rgba)
    • imgs?: Array<object> 图片列表 (新增)
      • src: string 图片路径
      • top?: string | number 距离顶部的高度 (可以写 20px 也可以是 20%,默认为 0)
      • width?: string 图片宽度 (关于图片宽高有四种可能,如下)
      • height?: string 图片高度 (关于图片宽高有四种可能,如下)
      • rotate?: boolean 是否跟随旋转 (默认为 false)

      1.宽高都未设置:则使用图片原大小;
      2.有宽度无高度:则高度随着宽度等比缩放;
      3.有高度无宽度:则宽度随着高度等比缩放;
      4.既有宽度也有高度:则图片宽高均等于设置的值(会被拉伸)

关于绘制背景

在这里插入图片描述

  • 第一个橘色的 block 的直径等于200px,等于父容器的宽
  • 第二个红色的 block:直径等于180px,因为第一个 block 的padding上下左右同时挤出10px
  • 第三个白色的 block:直径等于160px,因为第二个 block 的padding同样也挤出10px
  • 最后白色 block 挤出的部分就是奖品区域了
<template>
  <LuckyWheel
    width="200px"
    height="200px"
    :blocks="blocks"
  />
</template>

<script>
export default {
  data () {
    return {
      blocks: [
        { padding: '10px', background: '#ffc27a' },
        { padding: '10px', background: '#ff4a4c' },
        { padding: '0px', background: '#fff' }
      ]
    }
  }
}
</script>
关于背景图

在这里插入图片描述

  • rotate用来控制背景图是否跟随旋转, 默认为 false 不旋转
  • 如果你的背景图里面就自带了奖品, 那你依然要控制好prizes的数量, 以及defaultConfig.offsetDegree, 因为我必须知道你有几个奖品才能准确的抽奖
  • 理论上来说, 你可以仅凭一张背景图和一个按钮图片完成抽奖需求
<template>
  <LuckyWheel
    ref="LuckyWheel"
    width="240px"
    height="240px"
    :blocks="blocks"
    :prizes="prizes"
    :buttons="buttons"
    @start="startCallBack"
  />
</template>

<script>
export default {
  data () {
    return {
      blocks: [
        { padding: '20px' },
        {
          padding: '20px',
          imgs: [{
            src: require('../examples/img/temp.png'),
            width: '100%',
            rotate: true
          }]
        }
      ],
      prizes: [
        { name: '0' },
        { name: '1' },
        { name: '2' },
        { name: '3' },
        { name: '4' },
        { name: '5' },
        { name: '6' },
        { name: '7' },
      ],
      buttons: [{
        fonts: [{ text: 'Go', top: -12 }],
        radius: '22%',
        background: '#2da3e0',
        pointer: true
      }],
    }
  },
  methods: {
    startCallBack () {
      this.$refs.LuckyWheel.play()
      setTimeout(() => {
        this.$refs.LuckyWheel.stop(Math.random() * 8 >> 0)
      }, 1000)
    },
  }
}
</script>

奖品 - prizes

  • prizes?: Array<object> 奖品列表
    • background?: string 扇形背景色 (可继承 defaultStyle 背景色,默认为 ‘rgba(0,0,0,0)’)
    • fonts?: Array<object> 文字列表
      • text: string 字体内容 (可以使用 \n 用来换行)
      • top?: string | number 距离顶部的高度 (格式为:20 | ‘20px’ | ‘20%’,默认为 0)
      • fontColor?: string 字体颜色 (可继承 defaultStyle 字体颜色,默认为 ‘#000’)
      • fontSize?: string 字体大小(px) (可继承 defaultStyle 字体大小,默认为 ‘22px’)
      • fontStyle?: string 字体样式 (可继承 defaultStyle 字体样式,默认为 ‘sans-serif’)
      • fontWeight?: string 字体粗细 (可继承 defaultStyle 字体粗细,默认为 ‘400’)
      • lineHeight?: string 字体行高 (默认等于字体大小)
      • wordWrap?: boolean 文字自动换行 (默认为 true 开启,关闭时可以使用 \n 换行)
      • lengthLimit?: string | number 换行宽度限制 (格式为:90 | ‘90px’ | ‘90%’,默认为 ‘90%’)
    • imgs?: Array<object> 图片列表
      • src: string 图片路径
      • top?: string | number 距离顶部的高度 (可以写 20px 也可以是 20%,默认为 0)
      • width?: string 图片宽度 (关于图片宽高有四种可能,同上)
      • height?: string 图片高度 (关于图片宽高有四种可能,同上)
关于设置奖品

在这里插入图片描述

  • 奖品区域为扇形,会平分整个大转盘并以顺时针方向绘制,建议配置不同的背景色方便区分
  • 文字默认以扇形的中线居中,会自动随着扇形的旋转而旋转
  • 2号扇形的top为100%,所以他的文字超出了原本的区域
<template>
  <LuckyWheel
    width="200px"
    height="200px"
    :blocks="blocks"
    :prizes="prizes"
  />
</template>

<script>
export default {
  data () {
    return {
      blocks: [{ padding: '10px', background: '#d64737' }],
      prizes: [
        { fonts: [{ text: '0' }], background: '#f8d384' },
        { fonts: [{ text: '1', top: '20px' }], background: '#f9e3bb' },
        { fonts: [{ text: '2', top: '100%' }], background: '#fff' }
      ],
    }
  }
}
</script>
关于奖品文字换行

在这里插入图片描述

  • 由于奖品是一个扇形区域,顶部的圆弧宽度计算困难,建议搭配top属性向下挤一部分
  • wordWrap属性用来控制该段文字是否换行,默认为 true,但等于 false 时依然可以使用\n来换行
  • lengthLimit属性用来控制自动换行的最大宽度,默认为’90%’
<template>
  <LuckyWheel
    width="200px"
    height="200px"
    :blocks="blocks"
    :prizes="prizes"
  />
</template>

<script>
export default {
  data () {
    return {
      blocks: [
        { padding: '10px', background: '#d64737' },
      ],
      prizes: [
        {
          fonts: [{ text: '当文字超长之后就会自动进行换行', top: 10, lengthLimit: '80%' }],
          background: '#f8d384'
        },
        {
          background: '#f9e3bb'
        },
        {
          fonts: [{ text: '这段字不会自动换行', top: 20, wordWrap: false }],
          background: '#f8d384'
        },
        {
          background: '#f9e3bb'
        }
      ],
    }
  }
}
</script>
关于配置图片

在这里插入图片描述

  • 图片跟文字一样,会默认以扇形的中线居中
  • 0号扇形的图片因为没有设置宽度或高度限制,所以他显示了图片的原本大小
  • 1号扇形的图片只设置了宽度,那高度就会随着宽度进行等比缩放
  • 2号扇形的图片同时设置了宽度和高度,所以他被拉伸了
<template>
  <LuckyWheel
    width="200px"
    height="200px"
    :blocks="blocks"
    :prizes="prizes"
  />
</template>

<script>
export default {
  data () {
    return {
      blocks: [{ padding: '10px', background: '#d64737' }],
      prizes: [
        { imgs: [{ src: require('../examples/img/1.png') }], background: '#f8d384' },
        { imgs: [{ src: require('../examples/img/1.png'), width: '30%' }], background: '#f9e3bb' },
        { imgs: [{ src: require('../examples/img/1.png'), width: '40%', height: '50%' }] }
      ],
    }
  }
}
</script>

抽奖按钮 - buttons

  • buttons?: Array<object> 抽奖按钮列表
    • radius?: string 按钮半径
    • pointer?: boolean 是否显示指针 (默认为 false)
    • background?: string 按钮背景色 (可继承 defaultStyle 背景色,默认为 ‘#fff’)
    • fonts?: Array<object> 文字列表
      • text: string 字体内容 (可以使用 \n 用来换行)
      • top?: string | number 距离顶部的高度 (格式为:20 | ‘20px’ | ‘20%’,默认为 0)
      • fontColor?: string 字体颜色 (可继承 defaultStyle 字体颜色,默认为 ‘#000’)
      • fontSize?: string 字体大小(px) (可继承 defaultStyle 字体大小,默认为 ‘22px’)
      • fontStyle?: string 字体样式 (可继承 defaultStyle 字体样式,默认为 ‘sans-serif’)
      • fontWeight?: string 字体粗细 (可继承 defaultStyle 字体粗细,默认为 ‘400’)
      • lineHeight?: string 字体行高 (默认等于字体大小)
    • imgs?: Array<object> 图片列表
      • src: string 图片路径
      • top?: string | number 离圆心的距离 (格式为:20 | ‘20px’ | ‘20%’,默认为 0)
      • width?: string 图片宽度 (关于图片宽高有四种可能,同上)
      • height?: string 图片高度 (关于图片宽高有四种可能,同上)
关于配置按钮

在这里插入图片描述

  • buttons的绘制顺序为从上到下,所以要注意半径的大小,以免下面的按钮过大,把后面的按钮覆盖掉
  • pointer属性控制 item 是否显示指针,如果你想要一个炫酷的指针,那你可以通过引入 img 的方式来实现
  • 我通常建议你在最后一个按钮里面绘制文字或图片,来避免被覆盖掉
<template>
  <LuckyWheel
    width="200px"
    height="200px"
    :blocks="blocks"
    :buttons="buttons"
  />
</template>

<script>
export default {
  data () {
    return {
      blocks: [
        { padding: '10px', background: '#d64737' },
        { padding: '0px', background: '#fff' },
      ],
      buttons: [
        { radius: '40px', background: '#d64737' },
        { radius: '35px', background: '#f6c66f', pointer: true },
        {
          radius: '30px',
          background: '#fff',
          fonts: [{ text: '开始', top: '-13px' }]
        }
      ],
    }
  }
}
</script>
关于按钮文字换行

在这里插入图片描述

  • 按钮文字不会自动换行,没有wordWrap和lengthLimit属性
  • 如果文字超出了按钮区域,你可以使用\n进行手动换行
<template>
  <LuckyWheel
    width="200px"
    height="200px"
    :blocks="blocks"
    :buttons="buttons"
  />
</template>

<script>
export default {
  data () {
    return {
      blocks: [
        { padding: '10px', background: '#d64737' },
        { padding: '0px', background: '#fff' },
      ],
      buttons: [
        { radius: '40px', background: '#d64737' },
        { radius: '35px', background: '#f6c66f', pointer: true },
        {
          radius: '30px',
          background: '#fff',
          fonts: [
            { text: '开始\n抽奖', top: '-20px' },
            { text: '这是按钮文字', top: '20px' }
          ]
        }
      ],
    }
  }
}
</script>

默认配置 - defaultConfig

  • defaultConfig?: object 默认配置
    • gutter?: string | number 扇形之间的缝隙 (默认等于 0)
    • stopRange?: number 扇形区域的停止范围 (默认为 0.8, 建议范围 0 ~ 0.9, 如果设置 1 可能会停在奖品边缘!)
    • offsetDegree?: number 转盘的偏移角度 (默认为 0 度)
    • speed?: number 旋转速度峰值 (默认为 20,建议配置范围 10 ~ 30)
    • speedFunction?: string 缓动函数 (当前版本固定为 quadratic 二次方加速,后期会提供更多可选函数)
    • accelerationTime?: number 开始旋转时间 (单位为毫秒,默认等于 2500 毫秒)
    • decelerationTime?: number 缓慢停止时间 (单位为毫秒,默认等于 2500 毫秒)
关于奖品区域的缝隙

在这里插入图片描述

  • gutter属性用来控制奖品扇形区域之间的缝隙,默认等于 0
  • 这个缝隙是等距的,不会随着角度的不同而产生弧度
<template>
  <LuckyWheel
    width="200px"
    height="200px"
    :blocks="blocks"
    :prizes="prizes"
    :buttons="buttons"
    :default-config="defaultConfig"
  />
</template>

<script>
export default {
  data () {
    return {
      blocks: [{ padding: '10px', background: '#d64737' }],
      prizes: [
        { background: '#f8d384' },
        { background: '#f9e3bb' },
        { background: '#f8d384' },
        { background: '#f9e3bb' },
        { background: '#f8d384' },
        { background: '#f9e3bb' },
      ],
      buttons: [{ radius: '30px', background: 'rgba(0, 0, 0, 0.1)' }],
      defaultConfig: { gutter: '5px' }
    }
  }
}
</script>
关于转盘的偏移角度

在这里插入图片描述

  • 建议配置的角度范围:-360 ~ 360
  • 默认情况下,指针会指向扇形的中线,如果你想让其指向扇形的边缘,可以通过计算
  • 比如这个转盘有 6 个奖品,那么每个扇形就等于360 / 6 = 60度,所以我只需要让转盘向前旋转60 / 2 = 30度即可
<template>
  <LuckyWheel
    width="200px"
    height="200px"
    :blocks="blocks"
    :prizes="prizes"
    :buttons="buttons"
    :default-config="defaultConfig"
  />
</template>

<script>
export default {
  data () {
    return {
      blocks: [{ padding: '10px', background: '#d64737' }],
      prizes: [
        { background: '#f8d384', fonts: [{ text: '0', top: 5 }] },
        { background: '#f9e3bb', fonts: [{ text: '1', top: 5 }] },
        { background: '#f8d384', fonts: [{ text: '2', top: 5 }] },
        { background: '#f9e3bb', fonts: [{ text: '3', top: 5 }] },
        { background: '#f8d384', fonts: [{ text: '4', top: 5 }] },
        { background: '#f9e3bb', fonts: [{ text: '5', top: 5 }] },
      ],
      buttons: [
        { radius: '35px', background: '#d64737' },
        { radius: '30px', background: '#f6c66f', pointer: true },
        { radius: '25px', background: '#ffdea0' }
      ],
      defaultConfig: {
        gutter: '5px',
        offsetDegree: 30
      }
    }
  }
}
</script>
关于旋转速度

旋转总共分为三个阶段:

  • 第一阶段进行加速旋转,速度会从 0 加速到speed设置的值(默认为20),加速曲线恒定的情况下,你设置的时间越短,加速度越大
  • 第二阶段为匀速阶段,处于加速到峰值之后 && 调用stop方法之前,此时加速度恒定为speed
  • 第三阶段会缓慢减速到停止,在你调用stop方法之后,速度会从speed逐渐降低到 0

注意:当你接口的请求速度,小于等于accelerationTime设置的毫秒值时,会跳过第二阶段,此时你可以手动加一个定时器延缓调用stop的时机,以此来留出匀速的时间

默认样式 - defaultStyle

  • defaultStyle?: object 格子默认样式
    • fontColor?: string 字体颜色 (默认是 ‘#000’ 黑色)
    • fontSize?: string 字体大小(px) (默认是 ‘18px’)
    • fontStyle?: string 字体样式 (默认是 ‘sans-serif’)
    • fontWeight?: string 字体粗细 (默认为 ‘400’)
    • lineHeight?: string 字体行高 (默认等于字体大小)
    • textAlign?: string 文字和图片的对其方式 (目前只能居中!)
    • background?: string 奖品区域背景颜色 (默认是 ‘#fff’ 白色)
    • wordWrap?: boolean 文字自动换行 (默认为 true 开启,关闭时可以使用 \n 换行)
    • lengthLimit?: string | number 换行宽度限制 (格式为:90 | ‘90px’ | ‘90%’,默认为 ‘90%’)
      在这里插入图片描述
  • textAlign对其方式目前只支持 center
  • background属性只有在奖品区域没有配置背景色时才会生效,但是按钮的背景色不会继承这里,而是显示透明色
<template>
  <LuckyWheel
    width="200px"
    height="200px"
    :blocks="blocks"
    :prizes="prizes"
    :default-style="defaultStyle"
  />
</template>

<script>
export default {
  data () {
    return {
      blocks: [{ padding: '10px', background: '#d64737' }],
      prizes: [
        { fonts: [{ text: '0' }], background: '#f8d384' },
        { fonts: [{ text: '1' }] },
        { fonts: [{ text: '2' }], background: '#f8d384' },
        { fonts: [{ text: '3' }] },
        { fonts: [{ text: '4' }], background: '#f8d384' },
        { fonts: [{ text: '5' }] },
      ],
      defaultStyle: {
        fontColor: 'red',
        fontSize: '30px',
        background: 'pink'
      },
    }
  }
}
</script>

回调 & 方法

  • strat?: Function 开始抽奖前 (当点击抽奖按钮时,触发该回调)
  • end?: Function 抽奖结束后 (当九宫格完全停止时,触发该回调)
  • play() 开始抽奖 (调用该方法时,游戏才会开始, 没有参数)
  • stop(index) 缓慢停止抽奖 (调用该方法时,才会缓慢停止, 参数是中奖的索引;如果stop方法传入-1, 那游戏立即停止, 并且end回调不会触发)
<template>
  <LuckyWheel
    ref="LuckyWheel"
    width="300px"
    height="300px"
    :prizes="prizes"
    :default-style="defaultStyle"
    :blocks="blocks"
    :buttons="buttons"
    @start="startCallBack"
    @end="endCallBack"
  />
</template>

<script>
export default {
  data () {
    return {
      prizes: [],
      defaultStyle: {
        fontColor: '#d64737',
        fontSize: '14px'
      },
      blocks: [
        { padding: '13px', background: '#d64737' }
      ],
      buttons: [
        { radius: '50px', background: '#d64737' },
        { radius: '45px', background: '#fff' },
        { radius: '41px', background: '#f6c66f', pointer: true },
        {
          radius: '35px', background: '#ffdea0',
          imgs: [{ src: require('./img/button.png'), width: '65%', top: '-50%' }]
        }
      ],
    }
  },
  mounted () {
    this.getPrizesList()
  },
  methods: {
    getPrizesList () {
      const prizes = []
      let data = ['1元红包', '100元红包', '0.5元红包', '2元红包', '10元红包', '50元红包', '0.3元红包', '5元红包']
      data.forEach((item, index) => {
        prizes.push({
          title: item,
          background: index % 2 ? '#f9e3bb' : '#f8d384',
          fonts: [{ text: item, top: '10%' }],
          imgs:[{ src: require(`./img/${index}.png`), width: '30%', top: '35%' }],
        })
      })
      this.prizes = prizes
    },
    startCallBack () {
      this.$refs.LuckyWheel.play()
      setTimeout(() => {
        this.$refs.LuckyWheel.stop(Math.random() * 8 >> 0)
      }, 3000)
    },
    endCallBack (prize) {
      alert(`恭喜你获得${prize.title}`)
    },
  }
}
</script>
  • 5
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
1. 首先,需要在HTML中创建一个包含大转盘的容器元素,并在其中添加一个canvas元素。 ```html <div id="lucky-wheel"> <canvas id="wheel-canvas"></canvas> </div> ``` 2. 在CSS中设置容器元素的样式,如宽度、高度、背景颜色等。 ```css #lucky-wheel { width: 500px; height: 500px; background-color: #fff; border-radius: 50%; position: relative; margin: 0 auto; } ``` 3. 在JavaScript中编写抽奖逻辑代码。首先需要定义奖品数组,每个奖品包含名称、图片、颜色和概率等信息。 ```javascript const prizes = [ { name: '奖品1', image: 'image1.png', color: '#FFA07A', probability: 0.1 }, { name: '奖品2', image: 'image2.png', color: '#87CEFA', probability: 0.2 }, { name: '奖品3', image: 'image3.png', color: '#FFD700', probability: 0.3 }, { name: '奖品4', image: 'image4.png', color: '#00FA9A', probability: 0.4 } ]; ``` 4. 接着,需要定义转盘的样式和绘制函数。转盘的样式可以使用CSS中的渐变和阴影等效果来实现。 ```javascript const wheelStyle = { lineWidth: 2, strokeStyle: '#000', fillStyle: '#fff', shadowColor: '#666', shadowBlur: 4, gradient: { startColor: '#fff', endColor: '#ccc', startX: 0, startY: 0, endX: 0, endY: wheelRadius } }; function drawWheel() { ctx.save(); ctx.translate(wheelCenterX, wheelCenterY); ctx.rotate((Math.PI / 180) * wheelAngle); ctx.beginPath(); ctx.arc(0, 0, wheelRadius, 0, Math.PI * 2); ctx.lineWidth = wheelStyle.lineWidth; ctx.strokeStyle = wheelStyle.strokeStyle; ctx.fillStyle = wheelStyle.fillStyle; ctx.shadowColor = wheelStyle.shadowColor; ctx.shadowBlur = wheelStyle.shadowBlur; ctx.shadowOffsetX = 0; ctx.shadowOffsetY = 0; ctx.stroke(); ctx.fill(); ctx.restore(); drawWheelText(); } ``` 5. 然后,需要定义每个奖品的位置和角度,以及根据概率计算每个奖品在转盘上的占比。 ```javascript const prizeCount = prizes.length; const prizeAngle = 360 / prizeCount; let prizePositions = []; let prizeProbabilities = []; for (let i = 0; i < prizeCount; i++) { const angle = i * prizeAngle; const position = { x: wheelCenterX + Math.sin(degToRad(angle)) * (wheelRadius - wheelTextMargin), y: wheelCenterY - Math.cos(degToRad(angle)) * (wheelRadius - wheelTextMargin) }; prizePositions.push(position); prizeProbabilities.push(prizes[i].probability); } const totalProbability = prizeProbabilities.reduce((a, b) => a + b, 0); const prizeRatios = prizeProbabilities.map(p => p / totalProbability); ``` 6. 接下来,需要编写抽奖函数。该函数首先根据每个奖品的概率计算出随机的中奖结果,然后根据中奖结果的位置和角度旋转转盘,并触发抽奖结束的回调函数。 ```javascript function startLottery() { const random = Math.random(); let sum = 0; for (let i = 0; i < prizeCount; i++) { sum += prizeRatios[i]; if (random <= sum) { const prizeIndex = i; const prizeAngle = 360 - (prizeIndex * prizeAngle) - (prizeAngle / 2); const targetAngle = prizeAngle + 360 * 5; const animate = () => { if (wheelAngle < targetAngle) { wheelAngle += 5; drawWheel(); requestAnimationFrame(animate); } else { onLotteryEnd(prizes[prizeIndex]); } }; requestAnimationFrame(animate); break; } } } ``` 7. 最后,在初始化函数中调用绘制转盘和绑定抽奖按钮的事件处理函数,即可完成大转盘抽奖的实现。 ```javascript function init() { const canvas = document.getElementById('wheel-canvas'); canvas.width = wheelWidth; canvas.height = wheelHeight; ctx = canvas.getContext('2d'); drawWheel(); const button = document.getElementById('lottery-button'); button.addEventListener('click', startLottery); } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值