在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
自定义组件 新建文件夹component 在这个文件夹下面设置自定义的组件(抽奖组件) 组件截图如下: cj.json文件 { "component": true, "usingComponents": {} } cj.wxml文件 <view class="draw_num">您还有<text>{{num}}</text>次抽奖机会</view> <view class="canvas-container"> <view animation="{{animationData}}" class="gb-wheel-content" style='width:{{size-2}}rpx;height:{{size}}rpx;'> <!-- 扇形颜色背景 当选项长度等于2或者3时做了特殊处理 --> <view class="canvas-list"> <view class="canvas-item2" wx:for="{{awardsConfig.awards}}" wx:key="key" style="transform: rotate({{item.item2Deg}});background-color:{{awardsConfig.awards.length==2?item.color:''}};opacity:{{awardsConfig.awards.length==2?item.opacity:awardsConfig.awards.length==3?item.opacity:''}};width:{{size}}rpx;height:{{size/2-2}}rpx;transform-origin:{{size/2}}rpx {{size/2}}rpx"> <view class="canvas-item2-after" style="transform: rotate({{item.afterDeg}});background-color:{{item.color}};opacity:{{awardsConfig.awards.length==3?'':item.opacity}};width:{{size/2}}rpx;height:{{size/2}}rpx;transform-origin: {{size/2}}rpx {{size/2}}rpx"></view> <view wx:if='{{awardsConfig.awards.length==3}}' class="canvas-item2-after" style="background-color:{{item.color}};width:{{size/2}}rpx;height:{{size/2}}rpx;transform-origin: {{size/2}}rpx {{size/2}}rpx"></view> </view> </view>
<!-- 选项内容 --> <view class="gb-wheel-list"> <view class="gb-wheel-item" data-index="{{index}}" wx:for="{{awardsConfig.awards}}" wx:key='key'> <view class="gb-wheel-icontent" style="height:262rpx;overflow:hidden;font-size:{{item.name.length>9?'26':'30'}}rpx;line-height:{{item.name.length>9?'26':'30'}}rpx;width:{{awardsConfig.awards.length > 10 ? '140rpx':'200rpx'}};padding-top:25rpx;transform: rotate({{index*turnNum}}turn);transform-origin: 50% {{size/2-2}}rpx"> <text style='word-break:break-all;display:block;'>{{item.name}}</text> <image src="{{item.img}}" style="width:80rpx;height:100rpx;margin-top:10rpx"></image> </view> </view> </view> </view>
<view class="img-container" style='width:100%;height:{{size}}rpx;'> <!-- 转盘中间的按钮 --> <image bindtap="_zhuan" src='../images/canvas_button_go_unclick.png' style='width:{{size/4.4}}rpx;display:{{block1}};margin-top:-49rpx;left:15rpx;' mode='widthFix'></image> <image src='../images/canvas_button_go_click.png' style='width:{{size/4.4}}rpx;display:{{block2}};margin-top:-49rpx;left:15rpx;' mode='widthFix'></image> <image bindtap="reset" src='../images/canvas_button_reset_unclick.png' style='width:{{size/4.4}}rpx;display:{{block3}};margin-top:-49rpx;left:15rpx;' mode='widthFix'></image> <!-- <image src='../../images/canvas_button_reset_click.png' style='width:{{size/4.4}}rpx;display:{{block4}};margin-top:16rpx' mode='widthFix'></image> --> </view> </view> cj.wxss文件 .draw_num{ text-align:center; padding-top:-21rpx; padding-bottom:21rpx; font-size:30rpx; font-weight:600; } .draw_num text{ color:#f00; padding:0 7rpx; } .canvas-container { margin: 0 auto; position: relative; display: flex; align-items: center; justify-content: center; }
.img-container { margin: 0 auto; position: absolute; display: flex; align-items: center; justify-content: center; left: 0; top: 0; z-index:10; }
.gb-wheel-run { box-shadow: 0 0 5rpx 0rpx rgba(0, 0, 0, 0.98); width: 700rpx; height: 700rpx; border-radius: 50%; border: 30rpx solid #f1ecec; box-sizing: border-box; position: absolute; left: 27rpx; top: -19rpx; opacity: 0.7; }
.gb-wheel-content { position: relative; margin: 0 auto; z-index: 2; width: 660rpx; height: 660rpx; border-radius: 50%; border: 20rpx solid #f1ecec; box-shadow: 0 0 5rpx 0rpx rgba(0, 0, 0, 0.98); opacity: 0.7; overflow: hidden; }
.canvas-list { position: absolute; left: 0; top: 0; width: inherit; height: inherit; z-index: 8; }
.canvas-item2 { position: absolute; left: 0px; top: 0; width: 660rpx; height: 328rpx; color: #e4370e; font-weight: bold; transform-origin: 330rpx 330rpx; overflow: hidden; }
.canvas-item2-after { position: absolute; top: 0; left: 0; width: 330rpx; height: 330rpx; transform-origin: 330rpx 330rpx; opacity: 1; }
.gb-wheel-list { position: absolute; left: 0; top: 0; width: 100%; height: 100%; z-index: 9; }
.gb-wheel-item { position: absolute; left: 0; top: 0; width: 100%; height: 100%; color: #fff; text-shadow: 0 1px 1px rgba(255, 255, 255, 0.6); }
.gb-wheel-icontent { position: relative; display: block; padding-top: 50rpx; margin: 0 auto; text-align: center; transform-origin: 50% 328rpx; } cj.js文件 // pages/cj/cj.js //创建并返回内部 audio 上下文 innerAudioContext 对象 const start = wx.createInnerAudioContext(); const mid = wx.createInnerAudioContext(); const stop = wx.createInnerAudioContext();
Component({ options: { multipleSlots: true // 在组件定义时的选项中启用多slot支持 },
/** * 组件的属性列表 * 用于组件自定义设置 组件的对外属性 */ properties: { myProperty: { // 属性名 myProperty2: String, 简化的定义方式 type: String, // 类型(必填),目前接受的类型包括:String, Number, Boolean, Object, Array, null(表示任意类型) value: '', // 属性默认 初始值(可选),如果未指定则会根据类型选择一个 observer: function (newVal, oldVal, changedPath) { // 属性被改变时执行的函数(可选),也可以写成在methods段中定义的方法名字符串, 如:'_propertyChange' // 通常 newVal 就是新设置的数据, oldVal 是旧数据 } }, num:{ type: Number, value:0, observer: function (newVal, oldVal, changedPath) { this.setData({ num:newVal }) } }, probability: { type: Boolean, // 概率开关,默认false 随机 value: true },
musicflg: { type: Boolean, // 转盘声音开关,默认true value: true },
fastJuedin: { type: Boolean, // 快速转动转盘的开关,默认false value: false },
repeat: { type: Boolean, // 重复抽取开关,默认false value: false },
size: { type: Number, // 转盘大小,传入宽度即可 value: 600 },
zhuanpanArr: { // 可以切换的转盘选项, 支持多个 type: Array, value: [ { id: 0, option: '转盘的标题名称', awards: [ { id: 0, name: "1", // 选项名 color: 'red', // 选项的背景颜色 probability: 10 // 概率 0代表永远也转不到这个选项,数字越大概率也就越大 }, { id: 1, name: "2", // 超过9个字时字体会变小点 color: 'green', probability: 10 }, { id: 2, name: "3", // 超过9个字时字体会变小点 color: 'blue', probability: 10 }, { id: 3, name: "4", // 超过9个字时字体会变小点 color: 'pink', probability: 10 }, { id: 4, name: "5", // 超过9个字时字体会变小点 color: 'orange', probability: 10 } ] } ], observer: function (newVal, oldVal, changedPath) { // 属性被改变时执行的函数(可选),也可以写成在methods段中定义的方法名字符串, 如:'_propertyChange' // 通常 newVal 就是新设置的数据, oldVal 是旧数据 // console.log(oldVal); this.setData({ zhuanpanArr:newVal }) console.log(this.data.zhuanpanArr); } },
// 限制:最多17个选项, 单个选项最多填10-13个字,多余部分会隐藏 awardsConfig: { // 默认的当前转盘选项 type: Object, value: { option: '我的小决定?', awards: [ { id: 0, name: "奖项一", color: 'red', probability: 0 }, { id: 1, name: "选项二", color: 'green', probability: 0 }, { id: 2, name: "选项三", color: 'blue', probability: 10 } ], }, observer: function (newVal, oldVal, changedPath) { console.log(newVal); if (newVal) { this.switchZhuanpan(newVal, true); } } }
},
/** * 私有数据,组件的初始数据 * 可用于模版渲染 */ data: { animationData: {}, // 转盘动画 zhuanflg: false, // 转盘是否可以点击切换的标志位 fastTime: 7600, // 转盘快速转动的时间 slowTime: 3900, // 转盘慢速转动的时间 runDegs: 0, // 转盘旋转了多少圈 timer: null, // 清除转盘的时间clearTimeout(timer) block1: 'block', // 控制显示或隐藏转盘中心的图片 block2: 'none', block3: 'none', block4: 'none' },
//组件生命周期函数,在组件实例进入页面节点树时执行,注意此时不能调用 setData created: function () { },
// 组件生命周期函数,在组件实例进入页面节点树时执行 attached: function () { console.log('===============attached==============='); start.src = 'https://gamesdata.oss-cn-hangzhou.aliyuncs.com/xiaojueding/start.mp3'; // 转盘开始转动的音乐 mid.src = 'https://gamesdata.oss-cn-hangzhou.aliyuncs.com/xiaojueding/mid.mp3'; // 快速决定时,转盘开始转动的音乐 stop.src = 'https://gamesdata.oss-cn-hangzhou.aliyuncs.com/xiaojueding/stop.mp3'; // 转盘停止转动的音乐
this.setData({ awardsConfig: this.data.zhuanpanArr[0] }) // this.initAdards(); },
/** * 组件的方法列表 * 更新属性和数据的方法与更新页面数据的方法类似 */ methods: { /* * 公有方法 */ //判断值是否为空 isNull(str) { if (str == null || str == undefined || str == '') { return true; } else { return false; } },
//初始化数据 initAdards() { var that = this, awardsConfig = this.data.awardsConfig; console.log('lotteryData', awardsConfig) var t = awardsConfig.awards && awardsConfig.awards.length || 0; // 选项长度 var e = 1 / t, i = 360 / t, r = i - 90;
for (var g = 0; g < t; g++) { awardsConfig.awards[g].item2Deg = g * i + 90 - i / 2 + "deg";//当前下标 * 360/长度 + 90 - 360/长度/2 awardsConfig.awards[g].afterDeg = r + "deg"; awardsConfig.awards[g].opacity = '1'; }
that.setData({ turnNum: e, // 页面的单位是turn awardsConfig: awardsConfig, })
that._change();//向父组件传出当前转盘的初始数据 },
//重置转盘 reset() { var that = this, awardsConfig = that.data.awardsConfig; var animation = wx.createAnimation({ duration: 1, timingFunction: "ease" }); that.animation = animation; animation.rotate(0).step(), that.data.runDegs = 0;
that.setData({ animationData: animation.export(), block3: 'none', block4: 'block' })
for (let x in awardsConfig.awards) { awardsConfig.awards[x].opacity = '1'; }
setTimeout(function () { that.setData({ block1: 'block', block4: 'none', awardsConfig: awardsConfig, }) }, 300) },
//父组件需要切换当前转盘的选项 //如果有需要切换不同转盘的选项时,可以调用这方法 //data: 转盘的数据 //flag: 当转盘在转动过程中如果你想停止的话,可以传个true值,默认可不传 switchZhuanpan(data, flag) { this.setData({ awardsConfig: data, block1: 'block', block1: 'none', block3: 'none', block4: 'none', zhuanflg: false, }) this.initAdards();
if (flag) { this.reset(); clearTimeout(this.data.timer); start.stop(); mid.stop(); stop.stop(); wx.removeStorageSync('repeatArr'); } },
/* * 内部私有方法建议以下划线开头 * triggerEvent 用于触发事件,过triggerEvent来给父组件传递信息的 * 写法: this.triggerEvent('cancelEvent', { num: 1 }) // 可以将num通过参数的形式传递给父组件 */
// GO转盘开始转动 _zhuan() { var that = this, awardsConfig = that.data.awardsConfig, runDegs = that.data.runDegs;
var num0 = that.data.num ;
if(num0 > 0){ //>>> 是无符号移位运算符 var r = Math.random() * awardsConfig.awards.length >>> 0, runNum = 8;// 根据尹工的逻辑,这里的r的值从后端获取,不需要我来计算
/*=============不重复抽取=============*/ if (that.data.repeat) { r = that._queryRepeat(r); } else { wx.removeStorageSync('repeatArr');
console.log('是否开启了概率???', that.data.probability); //开启概率 probability这属性必须要传个ture if (that.data.probability) { r = that._openProbability(); } } /*=============不重复抽取=============*/ console.log('当前答案选项的下标=====', r); setTimeout(function () { //转盘开始转动音乐 that.data.musicflg ? that.data.fastJuedin ? mid.play() : start.play() : '';
//要转多少度deg runDegs = runDegs || 0, runDegs = runDegs + (360 - runDegs % 360) + (2160 - r * (360 / awardsConfig.awards.length));
var animation = wx.createAnimation({ duration: that.data.fastJuedin ? that.data.slowTime : that.data.fastTime, timingFunction: "ease" }); that.animation = animation;
//这动画执行的是差值 //如果第一次写rotate(360) 那么第二次再写rotate(360)将不起效果 animation.rotate(runDegs).step(), 0 == r && (runDegs = 0);
that.setData({ animationData: animation.export(), block1: 'none', block2: 'block', zhuanflg: true, })
that._setatZhuan(true); }, 100);
that.setData({ timer: setTimeout(function () { //转盘停止后,答案区域高亮显示,其他区域增加透明度 for (let x in awardsConfig.awards) { if (x != r) { awardsConfig.awards[x].opacity = '0.3'; } else { awardsConfig.awards[x].opacity = '1'; } }
//转盘停止后的音乐 !that.data.musicflg ? '' : stop.play(); let num1 = that.data.num; that.setData({ animationData: {}, s_awards: awardsConfig.awards[r].id,//最终选中的结果 awardsConfig: awardsConfig, block2: 'none', block3: 'block', zhuanflg: false, num: --num1 }) that._myAwards(); that._setatZhuan(false); }, that.data.fastJuedin ? that.data.slowTime : that.data.fastTime) })
}else{ wx.showToast({ title: '您没有抽奖机会', icon: '', image: '/images/tishi.png', duration: 1000 }) }
},
// 开启概率 // 传的数越大概率越大 // 传入0的话就永远摇不到这个选项 _openProbability() { var that = this, awards = that.data.awardsConfig.awards, arr = []; //5, 5, 20, 10 ,30 ,30, 0 for (let i in awards) { if (awards[i].probability != 0) { for (var x = 0; x < awards[i].probability; x++) { //把当前的概率数字 以当前选项下标的形式 都添加都空数组中,然后随机这个数组 arr.push(i); } } } var s = Math.floor(Math.random() * arr.length); return arr[s]; },
//不重复抽取 //r:随机数 当前选项进行随机 _queryRepeat(r) { var that = this, flag = true, repeatArr = wx.getStorageSync('repeatArr'), repeatArr2 = [], awardsConfig = that.data.awardsConfig; if (that.isNull(repeatArr)) { repeatArr2.push(r), wx.setStorageSync('repeatArr', repeatArr2); return r; } else { var len = awardsConfig.awards.length, r = Math.random() * len >>> 0; for (let i in repeatArr) { if (r == repeatArr[i]) { flag = false; if (repeatArr.length == len) { wx.removeStorageSync('repeatArr'); repeatArr2.push(r), wx.setStorageSync('repeatArr', repeatArr2); return r; } else { return that._queryRepeat();//递归调用 } } } if (flag) { repeatArr.push(r), wx.setStorageSync('repeatArr', repeatArr); return r; } } },
//初始化数据时向外传的参 _change() { this.triggerEvent('myData', this.data.awardsConfig);// 向父组件传出当前转盘的数组数据 },
//当前转盘的结果 _myAwards() { this.triggerEvent('myAwards', this.data.s_awards) },
//转盘开始转动或者结速转动后的要传的值 _setatZhuan(e) { this.triggerEvent('startZhuan', e); },
} })
下面来说组件的使用 在使用组件的json文件中设置如下 { "navigationBarTitleText": "抽奖", "usingComponents": { "cj": "../../Component/cj" } } 页面中组件的使用如下 <!-- 自定义组件开始 --> <cj id="cj" zhuanpanArr="{{zhuanpanArr}}" num="{{num}}" wx:if="{{isShow}}" bind:myAwards="onGetCode"></cj> 在JS文件中设置变量 data: { isShow : true, } 目的是在更改组件中的变量以后刷新页面,所以增加如下判断: wx.request({ url: url+'choujiang', data: { uid:app.globalData.uid }, header: { 'content-type': 'application/json' // 默认值 }, success (res) { console.log(res.data.data); that.setData({ isShow:false }) that.data.zhuanpanArr = res.data.data.zhuanpanArr; that.data.num = res.data.data.num; that.setData({ // zhuanpanArr : res.data.data, num : res.data.data.num, zhuanpanArr: res.data.data.zhuanpanArr, jzgz:res.data.data.jzgz, pbgz:res.data.data.pbgz }) console.log(that.data.zhuanpanArr); that.setData({ isShow:true }) } }) 这样就可以实现自定义组件中的值与页面数据的交互了。
|
请发表评论