yuminge-app/yun-min-program-plugin-master/mycomponent/DTurntable/DTurntable.js

208 lines
6.7 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// mycomponent/DTurntable/DTurntable.js
// let angle = 0;
// let duration = 0;
Component({
/**
* 组件的属性列表
*/
properties: {
prize: {
type: Array,
value: [], //* 奖品,数组类型,格式 [ { text:"aaa",image:"图片地址",color:"随css颜色" },... ] 当数组后面的元素的没有color时会循环 前面的color
},
start: {
type: Boolean,
value: false, //* 是否开始旋转会监听这个变量为true时旋转
},
lottery: {
type: Number,
value: 0, //* 中奖的 索引号 相对于prize
},
minTurns: {
type: Number,
value: 3, //* 旋转最少 多少圈
},
maxTurns: {
type: Number,
value: 5, //* 旋转最多 多少圈
},
minDuration: {
type: Number, //* transition 最小时间 */
value: 7, //* 秒级
},
maxDuration: {
type: Number, //* transition 最大时间 会随机从 minDuration 和maxDuration中选择一个随机数 */
value: -1, //* 秒级
},
debug: {
type: Boolean, //* 调试模式会隐藏canvas和显示奖品index
value: false,
},
angle: {
type: Number, //* 距离中奖区域边距 例如中奖区域是 15-30度 指针落在区域会是 15+angle的度数 至 30-angle的度数之间。传入是-1的话就是正中心
value: -1,
},
infinite: {
type: Boolean, //* 无限滚动。当突然变为false会开始正常滚动
value: false,
},
},
ready() {
if (this.data.debug === false) {
this.drawCircle();
}
let prize = this.data.prize;
for (let index = 0; index < prize.length; index++) {
const prizeItem = prize[index];
prizeItem["angle"] = (360 / prize.length) * index + 180 / prize.length;
}
this.fillLatticeColor();
prize = prize.reverse();
this.setData({
itemAngle: 360 / this.data.prize.length,
prize,
});
},
/**
* 组件的初始数据
*/
data: {
lotteryRotateAngle: 0,
transitionDuration: 0,
transitionFunction: "linear",
spinning: false,
itemAngle: 0,
latticeColors: [],
},
/**
* 组件的方法列表
*/
methods: {
drawCircle() {
const query = this.createSelectorQuery();
query
.select("#lotteryCanvas")
.fields({ node: true, size: true })
.exec((res) => {
let latticeColors = this.data.latticeColors;
if (latticeColors.length == 0) {
latticeColors = this.generateColors(["#fff", "#feb446"], this.data.prize.length);
}
const borderColor = "transparent";
const prizeLength = latticeColors.length;
const canvasNode = res[0].node;
const screenDPR = wx.getSystemInfoSync().pixelRatio;
const canvasContext = canvasNode.getContext("2d");
const canvasW = res[0].width * screenDPR;
const canvasH = res[0].height * screenDPR;
canvasNode.width = canvasW;
canvasNode.height = canvasH;
canvasContext.translate(0, canvasH);
canvasContext.rotate((-90 * Math.PI) / 180);
const outRadius = canvasW / 2;
const innerRadius = 0;
const baseAngle = (Math.PI * 2) / prizeLength;
canvasContext.clearRect(0, 0, canvasW, canvasH);
canvasContext.strokeStyle = borderColor; // 设置画图线的颜色
for (let index = 0; index < prizeLength; index++) {
const angle = index * baseAngle;
canvasContext.fillStyle = latticeColors[index];
canvasContext.beginPath();
canvasContext.arc(canvasW * 0.5, canvasH * 0.5, outRadius, angle, angle + baseAngle, false);
canvasContext.arc(canvasW * 0.5, canvasH * 0.5, innerRadius, angle + baseAngle, angle, true);
canvasContext.stroke(); //开始连线
canvasContext.fill(); //填充颜色
canvasContext.save(); //保存当前环境的状态
}
});
},
startSpinning() {
if (this.data.spinning) {
return;
}
const borderStart = this.data.lottery * this.data.itemAngle; //* 中奖区域开始度数
const borderEnd = borderStart + this.data.itemAngle; //* 中奖区域结束度数
const randomTurns = this.randomRange(this.data.minTurns, this.data.maxTurns); //* 随机圈数
let maxDurationSeconds = randomTurns;
if (this.data.maxDuration !== -1) {
maxDurationSeconds = this.data.maxDuration;
}
const rotateTransitionDurationSeconds = this.randomRange(this.data.minDuration, maxDurationSeconds); //* 随机 过渡时间 每圈时间=randomTurns / rotateTransitionDurationSeconds
let angle = randomTurns * 360;
if (this.data.angle === -1) {
angle += borderStart + this.data.itemAngle / 2; //* 奖品正中心
} else {
angle += this.randomRange(borderStart, borderEnd); //* 随机度数 圈数*360 也就是转多少圈, 加上后面的指定度数 就停在指定礼品区域
}
this.setData(
{
lotteryRotateAngle: 0,
transitionDuration: 0,
spinning: true,
},
() => {
setTimeout(() => {
this.setData({
lotteryRotateAngle: angle,
transitionDuration: rotateTransitionDurationSeconds,
});
setTimeout(() => {
this.setData({
spinning: false,
});
this.triggerEvent("end", {
duration: rotateTransitionDurationSeconds,
angle,
turns: randomTurns,
angleRange: {
start: borderStart,
end: borderEnd,
},
itemAngle: this.data.itemAngle,
});
}, rotateTransitionDurationSeconds * 1000);
}, 500);
}
);
},
randomRange(lowerValue, upperValue) {
return Math.floor(Math.random() * (upperValue - lowerValue + 1) + lowerValue);
},
fillLatticeColor() {
let latticeColors = [];
this.data.prize.forEach((prizeItem) => {
if (prizeItem.color) {
latticeColors.push(prizeItem.color);
}
});
if (latticeColors.length > 0) {
latticeColors = this.generateColors(latticeColors, this.data.prize.length);
}
this.setData({
latticeColors,
});
},
generateColors(initColors = [], needLength) {
let initLength = initColors.length;
for (let index = initColors.length; index < needLength; index++) {
initColors.push(initColors[index - initLength]);
}
return initColors;
},
},
observers: {
start(newV) {
if (newV === true) {
this.startSpinning();
}
},
},
});