| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413 | 
							- /**
 
-  * ease:
 
-  * 'linear'  动画从头到尾的速度是相同的
 
-  * 'ease'  动画以低速开始,然后加快,在结束前变慢
 
-  * 'ease-in'  动画以低速开始
 
-  * 
 
-  * 'ease-in-out'  动画以低速开始和结束
 
-  * 'ease-out'  动画以低速结束
 
-  * 'step-start'  动画第一帧就跳至结束状态直到结束
 
-  * 'step-end'  动画一直保持开始状态,最后一帧跳到结束状态
 
-  */
 
- let config = {
 
-     size: {
 
-         width: '560rpx',
 
-         height: '560rpx'
 
-     }, // 转盘宽高
 
-     bgColors: ['#FFC53F', '#FFED97'], // 转盘间隔背景色 支持多种颜色交替
 
-     fontSize: 12, // 文字大小
 
-     fontColor: '#C31A34', // 文字颜色
 
-     nameMarginTop: 12, // 最外文字边距
 
-     nameLength: 6, // 最外文字个数
 
-     iconWidth: 32, // 图标宽度
 
-     iconHeight: 32, // 图标高度
 
-     iconAndTextPadding: 4, // 最内文字与图标的边距
 
-     duration: 3000, // 转盘转动动画时长
 
-     rate: 1.5, // 由时长s / 圈数得到
 
-     border: 'border: 10rpx solid #FEFAE4;', // 转盘边框
 
-     ease: 'ease-out' // 转盘动画
 
- };
 
- let preAngle = 0; // 上一次选择角度
 
- let preAngle360 = 0; // 上一次选择角度和360度之间的差
 
- let retryCount = 10; // 报错重试次数
 
- let retryTimer; // 重试setTimeout
 
- let drawTimer; // 绘制setTimeout
 
- Component({
 
-     properties: {
 
-         // 是否可用
 
-         enable: {
 
-             type: Boolean,
 
-             value: true
 
-         },
 
-         // 数据
 
-         gifts: {
 
-             type: Array,
 
-             value: []
 
-         },
 
-         //  中奖id
 
-         prizeId: {
 
-             type: String,
 
-             value: ''
 
-         },
 
-         // 配置项 传入后和默认的配置进行合并
 
-         config: {
 
-             type: Object,
 
-             value: {}
 
-         },
 
-         // 抽奖次数
 
-         count: {
 
-             type: Number,
 
-             default: ""
 
-         },
 
-     },
 
-     data: {
 
-         lotteryCount: null,
 
-         cost: null,
 
-         turnCanvasInfo: { width: 0, height: 0 },
 
-         size: config.size,
 
-         giftModule: [],
 
-         disable: false,
 
-         canvasImgUrl: '',
 
-         border: config.border,
 
-         infos: []
 
-     },
 
-     methods: {
 
-         async getCanvasContainerInfo(id) {
 
-             return new Promise((resolve) => {
 
-                 const query = wx.createSelectorQuery().in(this);
 
-                 query.select(id).boundingClientRect(function (res) {
 
-                     const { width, height } = res;
 
-                     resolve({ width, height });
 
-                 }).exec();
 
-             });
 
-         },
 
-         async init() {
 
-             try {
 
-                 const info = await this.getCanvasContainerInfo('#turn');
 
-                 if (info.width && info.height) {
 
-                     this.setData({
 
-                         turnCanvasInfo: info
 
-                     });
 
-                     this.drawTurn();
 
-                 } else {
 
-                     wx.showToast({
 
-                         icon: 'nont',
 
-                         title: '获取转盘宽高失败'
 
-                     })
 
-                 }
 
-             } catch (e) {
 
-                 if (retryCount <= 0) {
 
-                     return;
 
-                 }
 
-                 retryCount--;
 
-                 if (retryTimer) {
 
-                     clearTimeout(retryTimer);
 
-                 }
 
-                 retryTimer = setTimeout(async () => {
 
-                     await this.init();
 
-                 }, 100);
 
-             }
 
-         },
 
-         drawTurn() {
 
-             const turnCanvasInfo = this.data.turnCanvasInfo;
 
-             const giftModule = this.properties.gifts;
 
-             const ctx = wx.createCanvasContext('turn', this);
 
-             // 计算没个扇区弧度
 
-             const radian = Number((2 * Math.PI / giftModule.length).toFixed(2));
 
-             // 绘制扇区并记录每个扇区信息
 
-             const infos = this.drawSector(radian, giftModule, ctx, turnCanvasInfo);
 
-             // 记录旋转角度
 
-             this.recordTheRotationAngle(infos);
 
-             // 绘制扇区文本及图片
 
-             this.drawTextAndImage(giftModule, ctx, turnCanvasInfo, radian);
 
-             ctx.draw(false, () => {
 
-                 this.saveToTempPath(turnCanvasInfo);
 
-             });
 
-         },
 
-         saveToTempPath(turnCanvasInfo) {
 
-             if (drawTimer) {
 
-                 clearTimeout(drawTimer);
 
-             }
 
-             drawTimer = setTimeout(() => {
 
-                 wx.canvasToTempFilePath({
 
-                     canvasId: 'turn',
 
-                     quality: 1,
 
-                     x: 0,
 
-                     y: 0,
 
-                     width: turnCanvasInfo.width,
 
-                     height: turnCanvasInfo.height,
 
-                     success: (res) => {
 
-                         this.setData({
 
-                             canvasImgUrl: res.tempFilePath
 
-                         });
 
-                     },
 
-                     fail: (error) => {
 
-                         console.log(error);
 
-                     }
 
-                 }, this);
 
-             }, 500);
 
-         },
 
-         drawSector(radian, giftModule, ctx, turnCanvasInfo) {
 
-             const halfRadian = Number((radian / 2).toFixed(2));
 
-             let startRadian = -Math.PI / 2 - halfRadian;
 
-             const angle = 360 / giftModule.length;
 
-             const halfAngle = angle / 2;
 
-             let startAngle = -90 - halfAngle;
 
-             const infos = [];
 
-             // 绘制扇形
 
-             for (let i = 0; i < giftModule.length; i++) {
 
-                 // 保存当前状态
 
-                 ctx.save();
 
-                 // 开始一条新路径
 
-                 ctx.beginPath();
 
-                 ctx.moveTo(turnCanvasInfo.width / 2, turnCanvasInfo.height / 2);
 
-                 ctx.arc(turnCanvasInfo.width / 2, turnCanvasInfo.height / 2, turnCanvasInfo.width / 2, startRadian, startRadian + radian);
 
-                 if (giftModule[i].bgColor) {
 
-                     ctx.setFillStyle(giftModule[i].bgColor);
 
-                 } else {
 
-                     ctx.setFillStyle(config.bgColors[i % config.bgColors.length]);
 
-                 }
 
-                 ctx.fill();
 
-                 ctx.closePath();
 
-                 ctx.restore();
 
-                 infos.push({
 
-                     id: giftModule[i].objectId,
 
-                     angle: (startAngle + startAngle + angle) / 2
 
-                 });
 
-                 startRadian += radian;
 
-                 startAngle += angle;
 
-             }
 
-             return infos;
 
-         },
 
-         drawTextAndImage(giftModule, ctx, turnCanvasInfo, radian) {
 
-             let startRadian = 0;
 
-             // 绘制扇形文字和logo
 
-             for (let i = 0; i < giftModule.length; i++) {
 
-                 // 保存当前状态
 
-                 ctx.save();
 
-                 // 开始一条新路径
 
-                 ctx.beginPath();
 
-                 ctx.translate(turnCanvasInfo.width / 2, turnCanvasInfo.height / 2);
 
-                 ctx.rotate(startRadian);
 
-                 ctx.translate(-turnCanvasInfo.width / 2, -turnCanvasInfo.height / 2);
 
-                 if (giftModule[i].fontSize) {
 
-                     ctx.setFontSize(giftModule[i].fontSize);
 
-                 } else {
 
-                     ctx.setFontSize(config.fontSize);
 
-                 }
 
-                 ctx.setTextAlign('center');
 
-                 if (giftModule[i].fontColor) {
 
-                     ctx.setFillStyle(giftModule[i].fontColor);
 
-                 } else {
 
-                     ctx.setFillStyle(config.fontColor);
 
-                 }
 
-                 ctx.setTextBaseline('top');
 
-                 if (giftModule[i].name) {
 
-                     ctx.fillText(giftModule[i].name, turnCanvasInfo.width / 2, config.nameMarginTop);
 
-                 }
 
-                 if (giftModule[i].subname) {
 
-                     ctx.fillText(giftModule[i].subname ? giftModule[i].subname : '', turnCanvasInfo.width / 2, config.nameMarginTop + config.fontSize + 2);
 
-                 }
 
-                 if (giftModule[i].imgUrl) {
 
-                     ctx.drawImage(giftModule[i].imgUrl,
 
-                         turnCanvasInfo.width / 2 - config.iconWidth / 2,
 
-                         config.nameMarginTop + config.fontSize * 2 + 2 + config.iconAndTextPadding,
 
-                         config.iconWidth, config.iconHeight);
 
-                 }
 
-                 ctx.closePath();
 
-                 ctx.restore();
 
-                 startRadian += radian;
 
-             }
 
-         },
 
-         recordTheRotationAngle(infos) {
 
-             for (let i = infos.length - 1; i >= 0; i--) {
 
-                 infos[i].angle -= infos[0].angle;
 
-                 infos[i].angle = 360 - infos[i].angle;
 
-             }
 
-             // 记录id及滚动的角度
 
-             this.setData({
 
-                 infos: infos
 
-             });
 
-         },
 
-         luckDrawHandle() {
 
-             if (this.data.disable || !this.data.canvasImgUrl) {
 
-                 return;
 
-             }
 
-             this.setData({
 
-                 disable: true
 
-             });
 
-             console.log('开始抽奖')
 
-             this.triggerEvent('LuckDraw');
 
-         },
 
-         startAnimation(angle) {
 
-             if (this.data.lotteryCount - this.data.cost < 0) {
 
-                 this.setData({
 
-                     disable: false
 
-                 });
 
-                 this.triggerEvent('NotEnough', '积分不足!');
 
-                 return;
 
-             }
 
-             // 抽奖次数减一
 
-             this.setData({
 
-                 lotteryCount: this.data.lotteryCount - this.data.cost
 
-             });
 
-             const currentAngle = preAngle;
 
-             preAngle += Math.floor((config.duration / 1000) / config.rate) * 360 + angle + preAngle360;
 
-             this.animate('#canvas-img', [
 
-                 { rotate: currentAngle, ease: 'linear' },
 
-                 { rotate: preAngle, ease: config.ease },
 
-             ], config.duration, () => {
 
-                 this.setData({
 
-                     disable: false
 
-                 });
 
-                 preAngle360 = 360 - angle;
 
-                 this.triggerEvent('LuckDrawFinish');
 
-             });
 
-         },
 
-         downloadHandle(url) {
 
-             return new Promise((resolve, reject) => {
 
-                 wx.downloadFile({
 
-                     url: url, // 仅为示例,并非真实的资源
 
-                     success: (res) => {
 
-                         // 只要服务器有响应数据,就会把响应内容写入文件并进入 success 回调,业务需要自行判断是否下载到了想要的内容
 
-                         if (res.statusCode === 200) {
 
-                             resolve(res.tempFilePath);
 
-                         } else {
 
-                             reject();
 
-                         }
 
-                     },
 
-                     fail: () => {
 
-                         reject();
 
-                     }
 
-                 });
 
-             });
 
-         },
 
-         async downloadImg(imgs) {
 
-             let result;
 
-             try {
 
-                 const downloadHandles = [];
 
-                 for (const url of imgs) {
 
-                     if (this.isAbsoluteUrl(url)) { // 是网络地址
 
-                         downloadHandles.push(this.downloadHandle(url));
 
-                     } else {
 
-                         downloadHandles.push(Promise.resolve(url));
 
-                     }
 
-                 }
 
-                 result = await Promise.all(downloadHandles);
 
-             } catch (e) {
 
-                 console.log(e);
 
-                 result = [];
 
-             }
 
-             return result;
 
-         },
 
-         clearTimeout() {
 
-             if (retryTimer) {
 
-                 clearTimeout(retryTimer);
 
-             }
 
-             if (drawTimer) {
 
-                 clearTimeout(drawTimer);
 
-             }
 
-         },
 
-         isAbsoluteUrl(url) {
 
-             return /(^[a-z][a-z\d\+\-\.]*:)?\/\//i.test(url);
 
-         },
 
-         async initData(data) {
 
-             let name;
 
-             let subname;
 
-             let imgUrls = [];
 
-             if (this.properties.config) {
 
-                 config = Object.assign(config, this.properties.config);
 
-             }
 
-             for (const d of data) {
 
-                 name = d.name;
 
-                 imgUrls.push(d.imgUrl);
 
-                 d.imgUrl = '';
 
-                 if (name.length > config.nameLength) {
 
-                     d.name = name.slice(0, config.nameLength);
 
-                     subname = name.slice(config.nameLength);
 
-                     if (subname.length > config.nameLength - 2) {
 
-                         d['subname'] = subname.slice(0, config.nameLength - 2) + '...';
 
-                     } else {
 
-                         d['subname'] = subname;
 
-                         /*   console.log('是否开启了概率???', that.data.probability);
 
-                           //开启概率 probability这属性必须要传个ture
 
-                           if (that.data.probability) {
 
-                               r = that._openProbability();
 
-                           } */
 
-                     }
 
-                 }
 
-             }
 
-             imgUrls = await this.downloadImg(imgUrls);
 
-             for (let i = 0; i < imgUrls.length; i++) {
 
-                 data[i].imgUrl = imgUrls[i];
 
-             }
 
-             this.setData({
 
-                 giftModule: data
 
-             });
 
-             await this.init();
 
-         }
 
-     },
 
-     observers: {
 
-         'gifts': async function (gifts) {
 
-             if (!gifts || !gifts.length) {
 
-                 return;
 
-             }
 
-             await this.initData(gifts);
 
-         },
 
-         'enable': function (enable) {
 
-             this.setData({
 
-                 disable: !enable
 
-             });
 
-         },
 
-         'prizeId': function (id) {
 
-             if (!id) {
 
-                 this.setData({
 
-                     disable: false
 
-                 });
 
-                 return;
 
-             }
 
-             try {
 
-                 const infos = this.data.infos;
 
-                 console.log(infos, id)
 
-                 const info = infos.find((item) => item.id == id);
 
-                 console.log(info)
 
-                 this.startAnimation(info.angle);
 
-             } catch (e) {
 
-                 this.setData({
 
-                     disable: false
 
-                 });
 
-             }
 
-         },
 
-         'count': function (lotteryCount) {
 
-             console.log(lotteryCount)
 
-             this.setData({
 
-                 lotteryCount
 
-             });
 
-         },
 
-         // 'cost': function(cost) {
 
-         //     console.log(cost)
 
-         //     this.setData({
 
-         //         cost
 
-         //     });
 
-         // },
 
-     },
 
-     lifetimes: {
 
-         detached() {
 
-             this.clearTimeout();
 
-         }
 
-     },
 
-     pageLifetimes: {
 
-         hide() {
 
-             this.clearTimeout();
 
-         }
 
-     }
 
- });
 
 
  |