|
@@ -0,0 +1,676 @@
|
|
|
+<template>
|
|
|
+ <view class="main" >
|
|
|
+ <!-- <view class="title-container">
|
|
|
+ {{name}}
|
|
|
+ </view> -->
|
|
|
+ <view v-if="options.length>0" class="canvas-container">
|
|
|
+ <canvas canvas-id="canvas" id="canvas" :style="canvasStyle" />
|
|
|
+
|
|
|
+ </view>
|
|
|
+ <image src="./national-2024-7.png"
|
|
|
+ style="width: 330px; height: 320px;z-index: 999; margin-top: -300px;"
|
|
|
+ ></image>
|
|
|
+ <image src="./national-2024-6.png" @click="end"
|
|
|
+ style="width: 330px; height: 250px; margin-top: -80px;"
|
|
|
+ ></image>
|
|
|
+ <view class="show1" style=" position: relative;
|
|
|
+ top: -140px;
|
|
|
+ color: rgba(157, 58, 15, 1);
|
|
|
+ font-size: 28px;" >
|
|
|
+ {{name}}
|
|
|
+ </view>
|
|
|
+ <!-- <view v-if="showBtn" btn-container>
|
|
|
+ <button type="primary" :disabled="isLottery" @click="playReward">{{btnTitle}}</button>
|
|
|
+ </view> -->
|
|
|
+ </view>
|
|
|
+</template>
|
|
|
+<script>
|
|
|
+ var img2=require('./national-2024-2.png')
|
|
|
+ var img3=require('./national-2024-3.png')
|
|
|
+ var ctx = null;
|
|
|
+ export default {
|
|
|
+
|
|
|
+ props: {
|
|
|
+ // 弹窗内容 ,当 turnModalContent=【】时,默认弹窗内容为抽奖结果,并且不展示标题
|
|
|
+ turnModalContent: {
|
|
|
+ type: Array,
|
|
|
+
|
|
|
+ default () {
|
|
|
+ return []
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 减速,值越小,减速效果越明显 turnReduceSpeed
|
|
|
+ turnReduceSpeed: {
|
|
|
+ type: Number,
|
|
|
+ default: 50
|
|
|
+ },
|
|
|
+ // 表示转速:表示再转多少圈再进行抽奖
|
|
|
+ turnCircle: {
|
|
|
+ type: Number,
|
|
|
+ default: 0
|
|
|
+ },
|
|
|
+ // 转盘名称
|
|
|
+ name: {
|
|
|
+ type: String,
|
|
|
+ default: "摇奖中..."
|
|
|
+ },
|
|
|
+ // 画布宽度
|
|
|
+ width: {
|
|
|
+ type: Number,
|
|
|
+ default: 100,
|
|
|
+
|
|
|
+ },
|
|
|
+ // 画布高度
|
|
|
+ height: {
|
|
|
+ type: Number,
|
|
|
+ default: 100
|
|
|
+ },
|
|
|
+ // 画布内字体大小
|
|
|
+ fontSize: {
|
|
|
+ type: Number,
|
|
|
+ default: 18
|
|
|
+ },
|
|
|
+ // 钩子函数,抽奖开始前执行,返回值为选项列表下标,若返回值为-1,则进行随机抽奖
|
|
|
+ setWinnerFn: {
|
|
|
+ type: Function,
|
|
|
+ default: null,
|
|
|
+ },
|
|
|
+ // // 钩子函数,抽奖开始前执行
|
|
|
+ // beforePlay: {
|
|
|
+ // type: Function,
|
|
|
+ // default: null,
|
|
|
+ // },
|
|
|
+ // // 钩子函数,抽奖结束后执行
|
|
|
+ // afterPlay: {
|
|
|
+ // type: Function,
|
|
|
+ // default: null,
|
|
|
+ // },
|
|
|
+ // 如果 true,则 使用组件默认的选项数据
|
|
|
+ isUseDefaultOptions: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false
|
|
|
+ },
|
|
|
+ // 选项列表
|
|
|
+ data: {
|
|
|
+ type: Array,
|
|
|
+ default: []
|
|
|
+ },
|
|
|
+ // 是否要展示开始按钮
|
|
|
+ showBtn: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false,
|
|
|
+ },
|
|
|
+ // 按钮文本
|
|
|
+ btnTitle: {
|
|
|
+ type: String,
|
|
|
+ default: "开始"
|
|
|
+ }
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ img2:img2,
|
|
|
+ img3:img3,
|
|
|
+ options: [{
|
|
|
+ id: 0, // 唯一id
|
|
|
+ name: '水饺', // 名称
|
|
|
+ // "weight": 50, // 中奖权重,0-100
|
|
|
+ img: '', // 展示图片
|
|
|
+ color: "#f6e174" // 轮盘区域底色
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: 2,
|
|
|
+ name: '火锅',
|
|
|
+ img: '',
|
|
|
+ color: "#94494d"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: 3,
|
|
|
+ name: '川菜',
|
|
|
+ img: '',
|
|
|
+ color: "#ffaa7f"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: 4,
|
|
|
+ name: '麻辣烫',
|
|
|
+ img: '',
|
|
|
+ color: "#a48342"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: 5,
|
|
|
+ name: '炸鸡汉堡',
|
|
|
+ img: '',
|
|
|
+ color: "#a25f81"
|
|
|
+ }
|
|
|
+
|
|
|
+ ],
|
|
|
+ isLottery: false, // 是否正在抽奖
|
|
|
+ };
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ canvasStyle() {
|
|
|
+ return "width:" + this.width + "px;; height:" + this.height + "px;";
|
|
|
+ },
|
|
|
+
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ end(){
|
|
|
+ if (this.isLottery) {
|
|
|
+
|
|
|
+ uni.showToast({
|
|
|
+ title: "摇奖中...",
|
|
|
+ icon: "none"
|
|
|
+ })
|
|
|
+ }else{
|
|
|
+ this.$emit("end")
|
|
|
+ }
|
|
|
+ },
|
|
|
+ async playReward() {
|
|
|
+ if (this.isLottery) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.isLottery = true
|
|
|
+ let len = this.options.length
|
|
|
+ if (len == 0) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ //console.log("playReward")
|
|
|
+ // if (this.beforePlay) {
|
|
|
+ // () => this.beforePlay()
|
|
|
+ // this.beforePlay()
|
|
|
+ this.$emit("beforePlay")
|
|
|
+ // }
|
|
|
+
|
|
|
+ let num = -1;
|
|
|
+ if (this.setWinnerFn) {
|
|
|
+ // 自定义抽奖结果
|
|
|
+ let res = () => this.setWinnerFn(this.options)
|
|
|
+ if (res != undefined && res >= 0) {
|
|
|
+ num = res
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ if (num < 0) {
|
|
|
+ // 进行权重抽奖
|
|
|
+ let optionIndex = this.lotteryWeight(this.options)
|
|
|
+ if (optionIndex != undefined || optionIndex >= 0) {
|
|
|
+ num = optionIndex
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (num < 0) {
|
|
|
+ // 没有自动抽奖结果 && 没有定义选项权重,则进行随机数抽奖
|
|
|
+ num = Math.floor(Math.random() * len)
|
|
|
+ }
|
|
|
+
|
|
|
+ const result = await this.roateCanvas(num)
|
|
|
+ //console.log("抽奖结果:", result.name)
|
|
|
+ this.name=result.name
|
|
|
+ this.isLottery = false
|
|
|
+ let title = ""
|
|
|
+ let content = result.name
|
|
|
+ if (this.turnModalContent.length > 0) {
|
|
|
+ // 若设置了 content ,则随机取一个 content 内容,并且 title 将展示为抽奖结果
|
|
|
+ title = result.name
|
|
|
+ content = this.turnModalContent[Math.floor(Math.random() * this.turnModalContent.length)]
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ },
|
|
|
+
|
|
|
+ initBtnCanvas() {
|
|
|
+ let angleTo = 0
|
|
|
+ let ctx = uni.createCanvasContext("canvasBtn", this);
|
|
|
+ // 6. 画中心点圆
|
|
|
+ // 圆中心点的坐标 x: 宽度的一半
|
|
|
+ let center_x = this.width / 2;
|
|
|
+ // 圆中心点的坐标 y: 高度的一半
|
|
|
+ let center_y = this.height / 2;
|
|
|
+
|
|
|
+ // 1. 先清除画布上在该矩形区域内的内容
|
|
|
+ ctx.clearRect(0, 0, this.width, this.height);
|
|
|
+
|
|
|
+ ctx.translate(center_x, center_y);
|
|
|
+
|
|
|
+ // 6. 画中心点圆
|
|
|
+ ctx.beginPath();
|
|
|
+ // ctx.arc(0, 0, 15, 0, Math.PI * 2); // 15 为中心点圆的半径
|
|
|
+ ctx.moveTo(0, -50); // 三角形顶点坐标
|
|
|
+ ctx.lineTo(-20, 10); // 左下角坐标
|
|
|
+ ctx.lineTo(20, 10); // 右下角坐标
|
|
|
+ ctx.setFillStyle("#ff0000");
|
|
|
+ ctx.fill();
|
|
|
+ ctx.draw();
|
|
|
+ },
|
|
|
+ initCanvas: function(ctx, angleTo) {
|
|
|
+
|
|
|
+ const len = this.options.length; //数组长度
|
|
|
+ if (len == 0) {
|
|
|
+ //console.log("options len == 0")
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (!angleTo) {
|
|
|
+ angleTo = 0
|
|
|
+ }
|
|
|
+ // 圆中心点的坐标 x: 宽度的一半
|
|
|
+ let center_x = this.width / 2;
|
|
|
+ // 圆中心点的坐标 y: 高度的一半
|
|
|
+ let center_y = this.height / 2;
|
|
|
+ // 圆的弧度的总度数,2π表示画圆
|
|
|
+ let totalAngle = 2 * Math.PI;
|
|
|
+ // 平均一个选项占用的孤度数
|
|
|
+ let avgAngle = totalAngle / len;
|
|
|
+
|
|
|
+ let radius = center_x - 14;
|
|
|
+ let fontSize = this.getFontSize()
|
|
|
+
|
|
|
+ // 1. 先清除画布上在该矩形区域内的内容
|
|
|
+ ctx.clearRect(0, 0, this.width, this.height);
|
|
|
+
|
|
|
+ ctx.translate(center_x, center_y);
|
|
|
+ // 2. 设置画布内字体大小
|
|
|
+ ctx.setFontSize(fontSize);
|
|
|
+ ctx.setLineWidth(14);
|
|
|
+ ctx.save();
|
|
|
+
|
|
|
+ // 3. 画外圆
|
|
|
+ ctx.rotate(angleTo * Math.PI / 180);
|
|
|
+ var beginAngle = 2 * Math.PI / 360 * (-90);
|
|
|
+ // ctx.setStrokeStyle("#ffaa00");
|
|
|
+ ctx.setStrokeStyle("#ffffff");
|
|
|
+ ctx.arc(0, 0, radius - 3, 0, Math.PI * 2);
|
|
|
+ ctx.stroke();
|
|
|
+
|
|
|
+ // 4. 划分区域,并且填充颜色
|
|
|
+ ctx.setLineWidth(0.1);
|
|
|
+ beginAngle = 2 * Math.PI / 360 * (-90);
|
|
|
+ //绘制填充形状
|
|
|
+ for (var i = 0; i < len; i++) {
|
|
|
+ ctx.save();
|
|
|
+ ctx.beginPath();
|
|
|
+ ctx.moveTo(0, 0);
|
|
|
+ ctx.setStrokeStyle(this.options[i].color);
|
|
|
+ ctx.setFillStyle(this.options[i].color);
|
|
|
+
|
|
|
+ ctx.arc(0, 0, radius, beginAngle, beginAngle + avgAngle, false);
|
|
|
+ //ctx.stroke();
|
|
|
+
|
|
|
+ beginAngle = beginAngle + avgAngle;
|
|
|
+ ctx.fill();
|
|
|
+ ctx.save();
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ // 5. 绘制选项文字
|
|
|
+ beginAngle = 0; //avgAngle / 2;
|
|
|
+ for (var i = 0; i < len; i++) {
|
|
|
+ var ry = -(center_x / 2) - 25;
|
|
|
+ //绘制旋转文字
|
|
|
+ ctx.rotate((beginAngle + (avgAngle * 0.5))); //顺时针旋转
|
|
|
+ ctx.setTextAlign("center");
|
|
|
+ ctx.setFillStyle("#9D3A0F");
|
|
|
+ ctx.fillText(this.options[i].name, 0, ry);
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ ctx.restore();
|
|
|
+ beginAngle = beginAngle + avgAngle;
|
|
|
+ }
|
|
|
+
|
|
|
+ var img = new Image();
|
|
|
+ // img.onload = function() {
|
|
|
+
|
|
|
+
|
|
|
+ beginAngle = 0; //avgAngle / 2;
|
|
|
+ for (var i = 0; i < len; i++) {
|
|
|
+
|
|
|
+ ctx.save();
|
|
|
+ var ry = -(center_x / 2) - 25;
|
|
|
+ //绘制旋转文字
|
|
|
+ ctx.rotate((beginAngle + (avgAngle * 0.5))); //顺时针旋转
|
|
|
+
|
|
|
+
|
|
|
+ if(this.options[i].id==1){
|
|
|
+ ctx.drawImage(this.img2, -17, -90,32,32);
|
|
|
+ }else{
|
|
|
+ ctx.drawImage(this.img3, -17, -90,32,32);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ // ctx.draw(true)
|
|
|
+
|
|
|
+ ctx.restore();
|
|
|
+ beginAngle = beginAngle + avgAngle;
|
|
|
+ }
|
|
|
+ //ctx.draw();
|
|
|
+
|
|
|
+ // }
|
|
|
+
|
|
|
+ // img.src=this.img3
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ ctx.save();
|
|
|
+ // 6. 画中心点圆
|
|
|
+ ctx.beginPath();
|
|
|
+ ctx.arc(0, 0, 15, 0, Math.PI * 2); // 15 为中心点圆的半径
|
|
|
+ ctx.setFillStyle("#FFFFFF");
|
|
|
+ ctx.fill();
|
|
|
+ ctx.draw();
|
|
|
+ },
|
|
|
+ // 根据设置的权重进行抽奖
|
|
|
+ lotteryWeight(prizes) {
|
|
|
+ if (!prizes || prizes.length == 0) {
|
|
|
+ //console.log("奖品列表为空")
|
|
|
+ return -1
|
|
|
+ }
|
|
|
+ let winPrizesIndex = [] // 抽中的奖品下标,多个是因为如果存在多个奖品的权重一致的情况,则再进行随机抽奖
|
|
|
+ let winPrizeWeight = 0; // 抽中的奖品的权重
|
|
|
+
|
|
|
+ let round = Math.random() * 100; // 生成一个 0-100的随机数
|
|
|
+ //console.log("lotteryWeight 生成的 round:", round)
|
|
|
+ for (let index = 0; index < prizes.length; index++) {
|
|
|
+ let prize = prizes[index];
|
|
|
+ let weight = prize['weight']
|
|
|
+ if (!weight) {
|
|
|
+ // 没有设置权重,则跳过
|
|
|
+ //console.log("奖品 ", prize.name, " 未设置权重,则不参与抽奖")
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ if (weight <= 0) {
|
|
|
+ // 如果奖品的权重设置<0,则表示不参与抽奖
|
|
|
+ //console.log("奖品 ", prize.name, " 不参与抽奖")
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ if (round > weight) {
|
|
|
+ // 随机数超过了权重,则未抽中
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ if (weight < winPrizeWeight) {
|
|
|
+ // 权重比之前抽中的还小,则跳过
|
|
|
+ //console.log("奖品 ", prize.name, "小于已经抽中的奖品", winPrizeWeight, " 不参与抽奖")
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ if (weight == winPrizeWeight) {
|
|
|
+ // 本次抽中的奖品和已经抽中的奖品权重一致,则加入抽中列表
|
|
|
+ //console.log("再抽中奖品 ", prize.name, " 中奖")
|
|
|
+ winPrizesIndex.push(index)
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ if (weight > winPrizeWeight) {
|
|
|
+ // 权重比之前抽中的还大,则重置抽中奖品
|
|
|
+ winPrizesIndex = [index]
|
|
|
+ winPrizeWeight = weight
|
|
|
+ //console.log("奖品 ", prize.name, " 中奖")
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (winPrizesIndex.length <= 0) {
|
|
|
+ // 本次没有抽中奖品
|
|
|
+ //console.log("本次没有抽中奖品")
|
|
|
+ return -1
|
|
|
+ }
|
|
|
+ if (winPrizesIndex.length == 1) {
|
|
|
+ // 只抽中了一个奖品,这直接返回
|
|
|
+ let index = winPrizesIndex[0];
|
|
|
+ //console.log("奖品 ", prizes[index], " 抽中");
|
|
|
+ return index
|
|
|
+ }
|
|
|
+ if (winPrizesIndex.length > 1) {
|
|
|
+ // 抽中多个,则再进行随机抽奖
|
|
|
+ //console.log(" 抽中多个,则再进行随机抽奖");
|
|
|
+ let index = round % winPrizesIndex.length
|
|
|
+ index = Math.floor(index)
|
|
|
+ //console.log("再次抽中结果:", winPrizesIndex[index])
|
|
|
+ return winPrizesIndex[index]
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ //console.log("其他抽奖情况")
|
|
|
+ return -1
|
|
|
+
|
|
|
+ },
|
|
|
+ // 旋转画布,num 表示选项 options 的下标
|
|
|
+ roateCanvas(num) {
|
|
|
+ let len = this.options.length
|
|
|
+ let angle = 360 / len;
|
|
|
+ angle = num * angle + angle / 2;
|
|
|
+ angle = angle || 0;
|
|
|
+ angle = 360 - angle;
|
|
|
+ angle += 360 * 5;
|
|
|
+ if (this.turnCircle > 0) {
|
|
|
+ let turnCircle = this.turnCircle
|
|
|
+ // 最多只能转 10 圈
|
|
|
+ if (turnCircle > 10) {
|
|
|
+ turnCircle = 10
|
|
|
+ }
|
|
|
+ angle += 360 * turnCircle;
|
|
|
+ }
|
|
|
+ let that = this;
|
|
|
+ let count = 1;
|
|
|
+ // 减速,值越小,减速效果越明显
|
|
|
+ let turnReduceSpeed = this.turnReduceSpeed
|
|
|
+ if (turnReduceSpeed == 0) {
|
|
|
+ turnReduceSpeed = 1
|
|
|
+ }
|
|
|
+ let baseStep = turnReduceSpeed;
|
|
|
+ // 起始滚动速度
|
|
|
+ let baseSpeed = 1;
|
|
|
+ let result = {}
|
|
|
+ return new Promise((resolve, reject) => {
|
|
|
+ let timer = setInterval(function() {
|
|
|
+
|
|
|
+ that.initCanvas(that.ctx, count);
|
|
|
+ if (count == angle) {
|
|
|
+ clearInterval(timer);
|
|
|
+ result = that.options[num];
|
|
|
+ resolve(result)
|
|
|
+ }
|
|
|
+ count = count + baseStep * (((angle - count) / angle) > baseSpeed ? baseSpeed :
|
|
|
+ ((angle -
|
|
|
+ count) / angle)) + 0.1;
|
|
|
+
|
|
|
+ if (angle - count < 0.5) {
|
|
|
+ count = angle;
|
|
|
+ }
|
|
|
+ }, 25);
|
|
|
+ });
|
|
|
+ },
|
|
|
+ getFontSize() {
|
|
|
+ let fontSize = this.fontSize
|
|
|
+ if (this.options.length > 10) {
|
|
|
+ if (this.fontSize >= 18) {
|
|
|
+ fontSize = this.fontSize - (this.options.length - 10)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return fontSize
|
|
|
+ },
|
|
|
+ // 生成随机颜色
|
|
|
+ genRandColor() {
|
|
|
+ // 生成随机的 RGB 值
|
|
|
+ var r = Math.floor(Math.random() * 256); // 0 到 255 之间的随机数
|
|
|
+ var g = Math.floor(Math.random() * 256);
|
|
|
+ var b = Math.floor(Math.random() * 256);
|
|
|
+
|
|
|
+ // 将 RGB 值转换为 Hex 颜色表示
|
|
|
+ var hexColor = "#" + this.componentToHex(r) + this.componentToHex(g) + this.componentToHex(b);
|
|
|
+
|
|
|
+ return hexColor;
|
|
|
+ },
|
|
|
+ componentToHex(c) {
|
|
|
+ var hex = c.toString(16);
|
|
|
+ return hex.length === 1 ? "0" + hex : hex;
|
|
|
+ },
|
|
|
+ initOptions: function() {
|
|
|
+ let defaultOptions = this.options
|
|
|
+ if (this.isUseDefaultOptions) {
|
|
|
+ // 使用默认数据
|
|
|
+ } else {
|
|
|
+ this.options = this.data
|
|
|
+ }
|
|
|
+ // 所有默认的颜色
|
|
|
+ let allDefColorArr = defaultOptions.map(item => item.color);
|
|
|
+
|
|
|
+ // 找到最大的 id
|
|
|
+ let maxId = -Infinity;
|
|
|
+
|
|
|
+ this.options.forEach(item => {
|
|
|
+ if (!item.id) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (item.id > maxId) {
|
|
|
+ maxId = item.id;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ // 填充 id,确保 id 唯一
|
|
|
+ var existIds = []
|
|
|
+ for (var i = 0; i < this.options.length; i++) {
|
|
|
+ let item = this.options[i]
|
|
|
+ if (item['id'] == undefined || item.id == 0 || existIds.includes(item.id)) {
|
|
|
+ // id 不存在,或者 id 重复了
|
|
|
+ this.options[i]['id'] = maxId + 1
|
|
|
+ }
|
|
|
+ existIds.push(this.options[i].id)
|
|
|
+ if (item['color'] == undefined || item.color == "") {
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 填充颜色,确保颜色唯一
|
|
|
+ let availableColor = JSON.parse(JSON.stringify(allDefColorArr)) // 可用颜色
|
|
|
+ let existColor = [] // 存在颜色
|
|
|
+ for (var i = 0; i < this.options.length; i++) {
|
|
|
+ let item = this.options[i]
|
|
|
+ if (item['color'] == undefined || item.color == "") {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ let color = item.color
|
|
|
+ existColor.push(color)
|
|
|
+ // 过滤掉已经用了的 color
|
|
|
+ availableColor = availableColor.filter(item => item !== color);
|
|
|
+
|
|
|
+ }
|
|
|
+ // 剩下的 allDefColorArr 都是可用的颜色
|
|
|
+ for (var i = 0; i < this.options.length; i++) {
|
|
|
+ let item = this.options[i]
|
|
|
+
|
|
|
+ if (item['color'] == undefined || item.color == "") {
|
|
|
+ if (availableColor.length == 0) {
|
|
|
+ // 没有可用颜色了,则随机生成一个
|
|
|
+ let color = ''
|
|
|
+ for (var j = 0; j < 100; j++) {
|
|
|
+ if (color != '') {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ let genColor = this.genRandColor()
|
|
|
+ if (!existColor.includes(genColor)) {
|
|
|
+ existColor.push(color)
|
|
|
+ color = genColor
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.options[i]['color'] = color
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ const color = availableColor.shift();
|
|
|
+ existColor.push(color)
|
|
|
+ this.options[i].color = color
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
+ },
|
|
|
+ init() {
|
|
|
+ this.initOptions();
|
|
|
+ this.ctx = uni.createCanvasContext("canvas", this);
|
|
|
+ this.initCanvas(this.ctx, 0);
|
|
|
+ this.initBtnCanvas();
|
|
|
+ this.playReward()
|
|
|
+ }
|
|
|
+ },
|
|
|
+ // 初始化画布
|
|
|
+ mounted: function() {
|
|
|
+ //console.log("lottery mounted init......")
|
|
|
+ this.init()
|
|
|
+ }
|
|
|
+ }
|
|
|
+</script>
|
|
|
+<style scoped>
|
|
|
+ .main {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ .title-container {
|
|
|
+ font-size: 25px;
|
|
|
+ margin-top: 120rpx;
|
|
|
+ margin-bottom: 40rpx;
|
|
|
+ z-index: 100;
|
|
|
+ }
|
|
|
+
|
|
|
+ .canvas-container {
|
|
|
+ position: relative;
|
|
|
+ width: fit-content;
|
|
|
+ height: fit-content;
|
|
|
+ z-index: 99;
|
|
|
+ }
|
|
|
+
|
|
|
+ .canvasBtn {
|
|
|
+ position: absolute;
|
|
|
+ top: 0%;
|
|
|
+ }
|
|
|
+
|
|
|
+ .canvas-btn {
|
|
|
+ position: absolute;
|
|
|
+ top: 50%;
|
|
|
+ left: 50%;
|
|
|
+ background-color: #ffffff;
|
|
|
+ transform: translate(-50%, -50%);
|
|
|
+ width: 110rpx;
|
|
|
+ height: 110rpx;
|
|
|
+ border-radius: 50%;
|
|
|
+ line-height: 110rpx;
|
|
|
+ text-align: center;
|
|
|
+ font-size: 45rpx;
|
|
|
+ text-shadow: 0 -1px 1px rgba(0, 0, 0, 0.6);
|
|
|
+ box-shadow: 0 3px 5px rgba(0, 0, 0, 0.6);
|
|
|
+ text-decoration: none;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /* .canvas-btn::before {
|
|
|
+ content: "";
|
|
|
+ position: absolute;
|
|
|
+ top: -15px;
|
|
|
+ left: 50%;
|
|
|
+ transform: translateX(-50%);
|
|
|
+ width: 0;
|
|
|
+ height: 0;
|
|
|
+ border-left: 10px solid transparent;
|
|
|
+ border-right: 10px solid transparent;
|
|
|
+ border-bottom: 20px solid #ffffff;
|
|
|
+ } */
|
|
|
+
|
|
|
+ .canvas-btn.isLottery {
|
|
|
+ background-color: #CCCCCC;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* .canvas-btn.isLottery {
|
|
|
+ pointer-events: none;
|
|
|
+ background: #CCCCCC;
|
|
|
+ color: #ccc;
|
|
|
+ } */
|
|
|
+
|
|
|
+ /* .canvas-btn.isLottery::before {
|
|
|
+ border-bottom-color: #CCCCCC;
|
|
|
+ }
|
|
|
+
|
|
|
+ .canvas-btn.isLottery::after {
|
|
|
+ border-bottom-color: #CCCCCC;
|
|
|
+ } */
|
|
|
+</style>
|