pt-lottery.vue 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. <template>
  2. <view class="pt-lottery">
  3. <view class="pt-lottery-box">
  4. <view :animation="animationData" class="pt-lottery-bg">
  5. <image :src="lotteryBg" class='pt-lottery-bg-img'></image>
  6. <view class="prize-list">
  7. <view class="prize-item" v-for="(data,index) in showPrizeList" :key="index">
  8. <view class="prize-item-info" :style="{'transform': 'rotate('+data.turn+')'}">
  9. <view class="prize-name">{{data.prizeName}}</view>
  10. <view v-if="data.prizeIcon" class="prize-icon">
  11. <image :src="data.prizeIcon" mode="aspectFit"></image>
  12. </view>
  13. </view>
  14. </view>
  15. </view>
  16. </view>
  17. <view @click="throttle(getLottery,gapTimes)" class="pt-lottery-btn">
  18. <image :src="lotteryBtn"></image>
  19. </view>
  20. </view>
  21. </view>
  22. </template>
  23. <script>
  24. /** 参数
  25. * lotteryBg 大转盘背景,不用纯色块,界面不好看
  26. * lotteryBtn 点击抽奖按钮
  27. * prizeList 奖品列表 [{prizeName,prizeIcon}]
  28. * times 抽奖次数
  29. * gapTimes 几秒钟内触发1次
  30. * runTimes 转盘旋转时间与转动的速度
  31. */
  32. let timer, flag;
  33. export default {
  34. props: {
  35. lotteryBg: {
  36. type: String,
  37. default: ''
  38. },
  39. lotteryBtn: {
  40. type: String,
  41. default: ''
  42. },
  43. prizeList: {
  44. type: Array,
  45. default () {
  46. return []
  47. }
  48. },
  49. gapTimes: {
  50. type: Number,
  51. default: 2000
  52. },
  53. runTimes: {
  54. type: Number,
  55. default: 5000
  56. }
  57. },
  58. data() {
  59. return {
  60. animationData: {},
  61. runDegs: '',
  62. is_lottery: false,
  63. showPrizeList: [],
  64. showTimes: ''
  65. }
  66. },
  67. created() {
  68. this.showTimes = this.times
  69. var awardsConfig = this.prizeList,
  70. len = awardsConfig.length,
  71. awardsList = [],
  72. turnNum = 1 / len
  73. for (var i = 0; i < len; i++) {
  74. awardsList.push({
  75. turn: i * turnNum + 'turn',
  76. prizeName: awardsConfig[i].prizeName,
  77. prizeIcon: awardsConfig[i].prizeIcon,
  78. });
  79. }
  80. this.showPrizeList = awardsList
  81. },
  82. methods: {
  83. // 节流,防止多次点击,目前设定的是2秒中内只触发一次,按需修改
  84. throttle(func, wait = 500, immediate = true) {
  85. if (immediate) {
  86. if (!flag) {
  87. flag = true;
  88. typeof func === 'function' && func();
  89. timer = setTimeout(() => {
  90. flag = false;
  91. }, wait);
  92. }
  93. } else {
  94. if (!flag) {
  95. flag = true
  96. timer = setTimeout(() => {
  97. flag = false
  98. typeof func === 'function' && func();
  99. }, wait);
  100. }
  101. }
  102. },
  103. // 点击抽奖按钮
  104. getLottery() {
  105. this.$emit('start')
  106. },
  107. // 开始旋转
  108. init(index) {
  109. let _this = this
  110. if (this.is_lottery) {
  111. console.log('正在抽奖中,请等待本轮抽奖结束再进行下次抽奖')
  112. return
  113. }
  114. this.is_lottery = true
  115. if (this.showTimes) {
  116. if (this.showTimes > 0) {
  117. this.showTimes--
  118. } else {
  119. return uni.showToast({
  120. icon: 'none',
  121. title: '您未获得抽奖机会!'
  122. })
  123. }
  124. }
  125. var awardIndex = 0;
  126. if (index) {
  127. awardIndex = index
  128. } else {
  129. awardIndex = Math.ceil(Math.random() * this.showPrizeList.length - 1)
  130. }
  131. console.log(awardIndex, '123456');
  132. this.runDegs = this.runDegs || 0
  133. this.runDegs = this.runDegs + (360 - this.runDegs % 360) + (360 * this.showPrizeList.length - awardIndex *
  134. (360 / this.showPrizeList.length))
  135. var animationRun = uni.createAnimation({
  136. duration: _this.runTimes,
  137. timingFunction: 'ease'
  138. })
  139. animationRun.rotate(this.runDegs).step()
  140. this.animationData = animationRun.export()
  141. setTimeout(() => {
  142. this.is_lottery = false
  143. this.$emit('end')
  144. }, _this.runTimes)
  145. }
  146. }
  147. }
  148. </script>
  149. <style>
  150. .pt-lottery-times {
  151. text-align: center;
  152. padding: 40rpx 0;
  153. }
  154. .pt-lottery-box {
  155. position: relative;
  156. width: 650rpx;
  157. height: 650rpx;
  158. margin: 0 auto;
  159. border-radius: 50%;
  160. overflow: hidden;
  161. }
  162. .pt-lottery-bg {
  163. position: absolute;
  164. width: 650rpx;
  165. height: 650rpx;
  166. left: 0;
  167. top: 0;
  168. z-index: 1;
  169. background-clip: padding-box;
  170. }
  171. .pt-lottery-bg-img {
  172. width: 650rpx;
  173. height: 650rpx;
  174. }
  175. .prize-list {
  176. position: absolute;
  177. left: 0;
  178. top: 0;
  179. width: 650rpx;
  180. height: 650rpx;
  181. z-index: 9999;
  182. }
  183. .prize-item {
  184. position: absolute;
  185. left: 0;
  186. top: 0;
  187. width: 100%;
  188. height: 100%;
  189. font-weight: 600;
  190. text-shadow: 0 1px 1px rgba(255, 255, 255, 0.6);
  191. overflow: hidden;
  192. }
  193. .prize-item-info {
  194. position: relative;
  195. display: block;
  196. margin: 0 auto;
  197. text-align: center;
  198. transform-origin: 50% 325rpx;
  199. font-size: 24rpx;
  200. padding-top: 95rpx;
  201. color: #947600;
  202. }
  203. .prize-icon image {
  204. width: 80rpx;
  205. height: 80rpx;
  206. margin-top: 10rpx;
  207. }
  208. .pt-lottery-btn {
  209. position: absolute;
  210. top: 50%;
  211. left: 50%;
  212. transform: translate(-50%, -50%);
  213. z-index: 10;
  214. width: 212rpx;
  215. height: 228rpx;
  216. }
  217. .pt-lottery-btn image {
  218. width: 212rpx;
  219. height: 228rpx;
  220. }
  221. </style>