最近项目中使用到了圆环倒计时,由于我自己不是很喜欢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)