ant-mini-wheel-draw
Version:
支付宝小程序大转盘抽奖组件
98 lines (96 loc) • 3.91 kB
JavaScript
Component({
data: {
degValue: 0, // 旋转角度
prizeWidth: 0, // 奖项背景图宽度计算值
prizePaddingTop: 0, // 奖项上边距计算值
itemTransformOrigin: '' // 奖项旋转原点计算值
},
props: {
width: 300, // 画布大小,默认单位 px
initDeg: 0, // 初始旋转角度
rotTimes: 1, // 抽奖机会次数
prizeList: [], // 奖品列表
prizeName: '', // 获奖项名字
prizeWidth: NaN, // 奖项宽度
prizePaddingTop: NaN, // 奖项距离圆弧的内边距
bgImg: 'https://gw.alipayobjects.com/zos/rmsportal/YIunNQVWkFRxUTaUNhOZ.png', // 背景图
btnImg: 'https://gw.alipayobjects.com/zos/rmsportal/JHenAywYHZTLbbrnkIFN.png', // 按钮图
onStart: function onStart() {}, // 开始回调
onFinish: function onFinish() {}, // 结束回调
onTimesUp: function onTimesUp() {} // 次数用尽的回调
},
didMount: function didMount() {
var widthNum = this._getNum(this.props.width);
var widthUnit = this._getUnit(this.props.width);
var prizeWidth = this.props.prizeWidth;
var paddingTop = this.props.prizePaddingTop;
this.setData({
degValue: this.props.initDeg,
itemTransformOrigin: 'transform-origin:50% ' + 0.5 * widthNum + widthUnit + ';',
prizeWidth: isNaN(prizeWidth) ? this._calculatePrizeWidth() : prizeWidth,
prizePaddingTop: isNaN(paddingTop) ? this._calculatePrizePaddingTop() : paddingTop
});
this.count = 6; // 奖品个数
this.rotNum = 0; // 当前是第几次抽奖
this.onRunning = false; // 是否正在抽奖
},
methods: {
init: function init() {},
getIndexByName: function getIndexByName(name) {
var list = this.props.prizeList;
for (var i = 0; i < this.count; i++) {
if (list[i] && list[i].name === name) return i;
}
return -1;
},
start: function start(e) {
var _this = this;
if (this.onRunning) return;
if (this.rotNum >= this.props.rotTimes) {
this.props.onTimesUp();
return;
};
if (!this.props.prizeName) {
throw new Error('请传入抽奖结果名称:prizeName');
}
var index = this.getIndexByName(this.props.prizeName);
if (index === -1) {
throw new Error('\u62BD\u5956\u7ED3\u679C\u540D\u79F0\u4E0E\u62BD\u5956\u5217\u8868\u914D\u7F6E\u9879\u4E0D\u5339\u914D\uFF0C\u672A\u627E\u5230\u540D\u79F0\u4E3A' + this.props.prizeName + '\u7684\u5956\u9879');
}
this.rotNum += 1;
this.onRunning = true;
var degree = (index + (index + 1)) * (360 / (this.count * 2));
var degValue = 360 * this.count * this.rotNum - degree;
this.setData({ degValue: degValue });
this.props.onStart(this.props.prizeName, this.rotNum);
setTimeout(function () {
_this.done();
}, 6000);
},
done: function done() {
this.onRunning = false;
this.props.onFinish(this.props.prizeName, this.rotNum);
},
_getNum: function _getNum(s) {
// 获取像素选项数值
return parseFloat(s);
},
_getUnit: function _getUnit(s) {
// 获取像素选项单位
s += '';
return (s.match(/[a-z]+$/) || [])[0] || 'px';
},
_calculatePrizeWidth: function _calculatePrizeWidth() {
// 等边三角形内接正方形边长: (4 - 2 * 根号3) * 边长
var widthNum = this._getNum(this.props.width);
var widthUnit = this._getUnit(this.props.width);
return (4 - 2 * Math.sqrt(3)) * 0.5 * widthNum + widthUnit;
},
_calculatePrizePaddingTop: function _calculatePrizePaddingTop() {
// 等边三角形一边的中点离过该边两点的圆弧的距离: 边长 - 边长 * (根号3 / 2)
var widthNum = this._getNum(this.props.width);
var widthUnit = this._getUnit(this.props.width);
return 0.5 * widthNum - 0.25 * widthNum * Math.sqrt(3) + widthUnit;
}
}
});