canvas之转盘抽奖(所有问题总结)

转盘抽奖所遇问题总结

 

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)在回调函数执行后让这个层消失

 

3.github地址  https://github.com/a578024797/lucky   finally文件(老版本)

                       https://github.com/a578024797/qlcs_wechat_h5       magpieFestivalExtract.html(新版本)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值