转盘抽奖所遇问题总结
1.在我画圆形得时候遍历 为何逆时针与顺时针效果不同
<script>
function draw() {
let obj = document.getElementById("canvas");
let context = obj.getContext('2d');
var length = 6;
for (let i = 0; i < 6; i++) {
let startAngle = Math.PI / 180 * (360 / 6) * i;
let endAngle = Math.PI / 180 * (360 / 6) * (i + 1);
context.save();
console.log(endAngle);
// true false
drawRound(context, obj.width / 2, obj.height / 2, 200, -startAngle, -endAngle, true, i, "#5f59ff",
"#7575ff");
// drawRound(context, obj.width / 2, obj.height / 2, 200, endAngle, startAngle, true, i, "#5f59ff",
// "#7575ff");
//逆时针
// drawRound(context, obj.width / 2, obj.height / 2, 80, startAngle, endAngle, true, i, "#5f59ff");
context.restore();
// console.log(startAngle);
// console.log(endAngle);
}
}
function drawRound(_context, _x, _y, _r, _startAngle, _endAngle, _isFalse, _index, color1, color2) {
_context.beginPath();
// _context.moveTo(_x, _y);
if (_index % 2 === 0) {
_context.fillStyle = color1;
} else {
_context.fillStyle = color2 ? color2 : color1;
}
console.log(_context.fillStyle);
_context.lineWidth = 2;
//顺时针
_context.arc(_x, _y, _r, _startAngle, _endAngle, _isFalse);
_context.closePath();
_context.stroke();
_context.fill();
}
draw();
</script>
效果图
第一个图为ni时针 第二个图为顺时针 弧度
let startAngle = Math.PI / 180 * (360 / 6) * i; //开始
let endAngle = Math.PI / 180 * (360 / 6) * (i + 1); //结束
为什么逆时针会出现这种情况那??
个人理解,逆时针得角度必须都是负得,如果在逆时针得情况下,结束角度(或开始角度)传入了正数, 那么他的弧度是是按照顺时针顺序来的,所以 既然要用逆时针那么弧度都是负得,顺时针就都是正得;
第一个图
drawRound(context, obj.width / 2, obj.height / 2, 200, -startAngle, -endAngle, true, i, "#5f59ff",
"#7575ff");
第二个图
drawRound(context, obj.width / 2, obj.height / 2, 200, startAngle, endAngle, true, i, "#5f59ff",
"#7575ff");
2. 关于非零环绕的问题
简单来说就是如果 交线不为零就填充, 否则就反之
//绘制大圆
context.arc(0, 0, 200, sAngle, eAngle, false);
//绘制小圆
context.arc(0, 0, 80, eAngle, sAngle, true);
context.arc(0, 0, 200, sAngle, eAngle, false);
//绘制小圆
context.arc(0, 0, 80, eAngle, sAngle, false);
false false 都是顺时针方向 里面就有颜色了 不过 我代码 明明写的是
//判断颜色
if (index % 2 === 0) {
context.fillStyle = '#7575ff';
} else {
context.fillStyle = '#5f59ff';
}
但是不知道为什么 第二个小圆 只显示第一个颜色, 由于时间得关系 并没有弄懂此问题
3 对圆盘绑定click时间 出现 冒泡得问题
第二次点击后 动的很慢 看log 发现 应该是setinterval执行了两次 方法用得 addEventListener 绑定的 改用 onclick之后 冒泡没有了.
4 转盘点击抽奖后 会出现点击按钮闪烁得情况,
使用canvas缓存下图片 然后用每次绘制得时候 绘制这个 canvas就可以了
//由于图片闪烁 尝试下网上说的双缓存
function createCache(_option) {
if (!_option.cacheImg) {
let cacheCanvas = document.createElement("canvas");
let cacheContext = cacheCanvas.getContext("2d");
let img = new Image();
img.onload = function () {
cacheCanvas.width = _option.canvasH / 3.2 * (img.width / img.height);
cacheCanvas.height = _option.canvasH / 3.2;
cacheContext.drawImage(img, 0, 0,
_option.canvasH / 3.2 * (img.width / img.height),
_option.canvasH / 3.2);
// _option.cacheImg = cacheCanvas; //如果等图片加载完在赋值会报错
}
img.src = _option.clickImg;
_option.cacheImg = cacheCanvas; //这样不会报错,但是点击得图片会消失 目前只出现在火狐
}
} //end
5 第一次页面加载 火狐浏览器下可能会造成点击按钮消失,:
img.onload = function () {
if (_option.cacheImg) {
//由于给的图形是长方形,所以我绝对已高为单位做半径
context.drawImage(img, -_option.canvasH / 2, -_option.canvasH / 2, _option.canvasH,
_option
.canvasH);
//ps 由于第一次加载 可能会出现图片记载不出来得情况
//这么做感觉有点愚蠢 谁有更好办法清联系我 578024797
let img2 = new Image();
img2.onload = function () {
//本来想写在外面的 但是由于层级顺序只能写在里面了
drawProducts(_option);
//点击事件
registeClick(_option);
}
img2.src = _option.clickImg;
}
}
img.src = _option.backgroundImg;
这样做问题虽然会解决 但是 img2却 onload两次..
6 谷歌浏览器下 一直点击旋转按钮 会造成卡顿得情况(未解决) 有时候没有 有时候有...
_option.canvas.onclick = function (e) {
//判断鼠标点击是否在范围点击抽奖范围内,
if ((e.offsetX >= position_minX && e.offsetX <= position_maxX) && (e.offsetY >= position_minH &&
e.offsetY <= position_maxH)) {
//判断当前旋转是否结束
if (_option.onlyone === 0) {
_option.onlyone = 1;
//执行接口 每次点击需要获取得数据 判断domain地址是否为空 为空(测试)给个假得
if (_option.domain !== undefined && _option !== "" && _option !== null) {
$.ajax({
type: 'POST',
url: _option.domain,
data: {},
dataType: 'json',
// jsonpCallback: "showData",
// crossDomain: true,
success: function (result) {
cosnole.log(1111111111111111111111);
if (result.error == 1) {
alert(result.msg);
} else if (result.error == 0) {
//设置成功方法所需要的数据
let lucy = result.name;
let position = _option.productsList.indexOf(lucy);
_option.luckPosition = position; //获奖位置
_option.result = result; //保存result结果
_option.frequency = result.frequency //更新总抽奖次数
console.log(result);
// console.log(11);
}
},
error: function () {
console.log("不OK");
}
});
console.log("ajax之后")
} else {
_option.luckPosition = 2;
}
//判断总次数 如果大于抽奖次数则不旋转(抽奖总次数每次掉ajax都会更新)
if (_option.flagTimes < _option.frequency) {
_option.flagTimes++;
_option.timer = setInterval(function () {
//判断公式 ra角度 * 弧度 >= 360 弧度 * 圈数 (由于指针向上 转盘开始角度从 顺时针90度开始)
//- 90度 - 默认角度得一半 - 产品位置
//位置准确性并没有校验.. 不过貌似差不多
// 这个变速写的很烂 有时间更新
if (_option.roateRadian * Math.PI / 180 <= Math.PI * 2 * 2 - Math.PI /
2 -
_option.baseRadian /
2 - _option.baseRadian * _option.luckPosition) {
_option.roateRadian += 5;
} else if (_option.roateRadian * Math.PI / 180 <= Math.PI * 2 * 2.5 -
Math.PI /
2 -
_option.baseRadian / 2 -
_option.baseRadian *
_option.luckPosition) {
_option.roateRadian += 3;
} else if (_option.roateRadian * Math.PI / 180 >= Math.PI * 2 * 3 -
Math.PI / 2 -
_option.baseRadian / 2 - _option.baseRadian *
_option.luckPosition) {
clearPromise(_option).then(function (result) {
//回复角度
_option.roateRadian = 0;
//延迟0.8秒 执行获奖方法
setTimeout(() => {
_option.onlyone = 0;
console.log(result);
if (_option.success) {
// _option.result = {
// "error": 0,
// "msg": null,
// "type": "2",
// "name": "5元优惠券",
// "score": "100",
// "hc_id": "00000007499328"
// }
_option.success(_option.result);
} else {
console.log("如果需要回调,清添加success");
}
}, 800);
}).catch(function () {
console.log("错误了")
});
return; //如果不加return 清除完之后还会执行几次!!!
} else {
_option.roateRadian += 1;
}
drawProducts(_option);
}, 1) //setinterval end
} else {
return false;
}// 旋转 end
} //onlyone end
} //判断点击范围
} //onclick end
先判断鼠标范围 再判断旋转是否结束 然后执行ajax ajax没执行就弄个假的 然后旋转 旋转结束后 执行success, 请大佬指点..
7 火狐浏览器下 一直单击click 在回调函数效果执行后我让 onlyone=0 但是火狐下 在回调效果执行前 就onlyone=0了, 谷歌点一直点击会咔 所以用一个统一得解决办法 执行的时候创建一个层 position:fixed(position:aboulute);覆盖整个页面(然后覆盖canvas)在回调函数执行后让这个层消失