使用canvas制作一个圆环倒计时

最近项目中使用到了圆环倒计时,由于我自己不是很喜欢canvas总觉得这个不适合我,但是我还是边看api边看别人的写法,还是写出来了。放张效果图,如下:

大概的效果就是这样子,文字数字都是外部文本,本来想写到canvas里面,但是觉得麻烦就还是直接放外面了。

先贴上主要代码,里面有几个我觉得是需要一开始注意下的。

// 倒计时
    countdown () {
        $('.game_start').hide()
        $('.countdown').show().addClass('rotateIn')

        var canvas = document.getElementById("cvs")
        var ctx = canvas.getContext("2d")
        var width = canvas.width
        var height = canvas.height
        var r = Math.floor((width - 50) / 2)

        var total_times = 20                          // 游戏总时间
        var cntd = total_times
        // 运行的线段
        var startAngle = -0.5 * Math.PI               // 开始角度   
        var endAngle = -2.5 * Math.PI                 // 结束角度
        runCvs()
        let circle
        clearInterval(circle)
        circle = setInterval(() => {
            runCvs()
            //  逆时针运行,角度不断增加
            endAngle += 2 * Math.PI / total_times
            cntd --

            // 刚好一个圆,停止canvas
            if (endAngle > startAngle ) {
                $('.countdown').removeClass('rotateIn').addClass('rotateOut').on('webkitAnimationEnd animationEnd', function () {
                    $('.countdown').hide().removeClass('rotateOut')
                    $('.game_end').fadeIn(300)
                })
                
                clearInterval(circle)
            }
        }, 1000)
        function runCvs() {
            // 画边框
            $('.seconds').text(cntd)
            ctx.clearRect(0,0,580,580) // 清除
            ctx.beginPath()
            ctx.arc(width / 2, height / 2, r, 0, 2 * Math.PI)   // x, y, 半径, 开始角度, 结束角度
            ctx.strokeStyle = "#03D0FF"
            ctx.stroke()
            ctx.closePath()
            // end
            
            ctx.save()  // 保存之前状态,也就是保存外部细边框
            // 开始画粗圆弧
            ctx.beginPath()
            ctx.lineWidth = 18
            ctx.arc(width / 2, height / 2, r - 9, startAngle, endAngle, true)       // true = 逆时针,所以endAngle的值肯定是比startAngle的值要小 
            ctx.strokeStyle = "#03D0FF"
            ctx.stroke()
            ctx.closePath()
            // end

            // 画跟随的圆圈 内圆
            ctx.beginPath()
            let x , y, r1 = 21
            x = (r - 9) * Math.cos(endAngle) + width / 2        // 通过三角函数计算x y 坐标
            y = (r - 9) * Math.sin(endAngle) + width / 2
            ctx.arc(x, y, r1, 0, 2 * Math.PI)
            ctx.fillStyle = '#87E9FF'
            ctx.fill()
            ctx.closePath()
            // 外圆
            ctx.beginPath()
            let r2 = 35
            ctx.arc(x, y, r2, 0, 2 * Math.PI)
            ctx.fillStyle = 'rgba(190,243,255,0.30)'
            ctx.fill()
            ctx.closePath()
            ctx.restore()
        }
    }

 我们来看看canvas中画圆的方法,画圆是使用arc(x, y, r, startAngle, endAngle, true)这个方法的,具体参数可前往w3cschool了解。

首先一开始进来是粗圆环,是一个完整的圆,那么一开始就需要先把整个圆环画好,因为我们是从圆的最顶端开始变化,故我们应该从-0.5 * Math.PI开始,画到-2.5 * Math.PI,这样一开始就是先画了一个完整的圆了。

然后我们要将圆环不断变少,那么我们就应该不断的将endAngle的角度变大,这样子每次画圆环的时候,就会不断变小。因为我们是逆时针画了一个完整的圆,所以,我们应该角度慢慢变大。(若是不是很了解这里的意思,建议w3cschool看下使用方法)所以才会有我们看到的,圆环顺时针慢慢变小。

然后我们在圆环那边,还有两个小圆跟随在圆环终点处,跟随着跑动。这里的圆环位置的计算,需要用到高中的数学知识, 也就是三角函数,我直接贴一张三角函数图出来吧,方便理解。

有了三角函数的关系,我们就能够根据当前圆环的endAngle,圆环的圆心坐标,计算出当前圆环终点处的x,y坐标,然后将坐标赋值给两个小圆的坐标,小圆也是使用arc()方法来画的。然后运行起来后两个小圆就会跟随着圆环终点而运动。但还没有结束,我们运行起来后,会有留下小圆的踪迹在圆环的轨道上,原因是我们没有清除掉画布上一刻小圆的位置状态,保存好圆环的当前状态,清除掉上帧的状态,然后画好圆环和当前小圆的位置即可。

匆匆忙忙写的小心得,可能写得不是很清晰明了。若不清楚,可评论留言,看到的话会尽快回复的。也希望大神能指导我这个小白。(虽然我很不喜欢canvas)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值