arc():在当前子路经添加一条弧线;
语法:context.arc(x,y,r,sAngle,eAngle,counterclockwise);
挂钟:
代码思路:
第一步:
绘制一个圆,然后我们去绘制里面的刻度,使用for去循环去绘制刻度,如果i是5的倍数就增加刻度的长度,使用if和取余的判断,怎么去绘制呢?从圆心出发,到圆上一点的位置(x+r*cos,y+r*sin)秒钟一圈是60个刻度,所以默认角度是6,for循环遍历60次,这是起点,终点是(x+(r-刻度长度)*cos,y+(r-刻度长度)*sin)。
第二步:
获取当前的时间,定义时针分针秒针的长度,根据秒针来计算时针和分针的角度。
第三步:
把前面两步,包装进函数里面,因为我们要在定时器里写这个功能让他不断执行,所以需要清空画布,在定时器里先清空画布,然后分别,调用步骤一,步骤二就写出来了
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<style>
#box {
border: 1px black solid;
}
</style>
<body>
<canvas id="box" height="700" width="700"> </canvas>
<script>
/** @type {HTMLCanvasElement} */
var canvas = document.querySelector("#box")
var ctx = canvas.getContext("2d")
var deg = Math.PI / 180
var angle = 6
var kedu = 20
function biao(){
ctx.arc(300, 300, 200, 0, 360 * deg)
for (i = 0; i < 60; i++) {
var res
if (i % 5) {
res = kedu
}
else {
res = kedu * 2
}
x1 = 300 + 200 * Math.cos(i * deg * angle)
x2 = 300 + (200 - res) * Math.cos(i * deg * angle)
y1 = 300 + 200 * Math.sin(i * deg * angle)
y2 = 300 + (200 - res) * Math.sin(i * deg * angle)
ctx.moveTo(x1, y1)
ctx.lineTo(x2, y2)
}
ctx.stroke()
}
function zhen() {
var shizhen = 50
var fenzhen = 100
var miaozhen = 150
var time = new Date().getSeconds()
console.log(time)
ctx.beginPath()
ctx.moveTo(300, 300)
var x3 = 300 + miaozhen * Math.cos(time * angle * deg-90*deg)
var y3 = 300 + miaozhen * Math.sin(time * angle * deg-90*deg)
ctx.lineTo(x3, y3)
ctx.moveTo(300, 300)
var x4 = 300 + fenzhen * Math.cos(time * angle / 60 * deg-90*deg)
var y4 = 300 + fenzhen * Math.sin(time * angle / 60 * deg-90*deg)
ctx.lineTo(x4, y4)
ctx.moveTo(300, 300)
var x5 = 300 + shizhen * Math.cos(time * angle / 60 / 12 * deg)
var y5 = 300 + shizhen * Math.sin(time * angle / 60 / 12 * deg)
ctx.lineTo(x5, y5)
ctx.stroke()
}
setInterval(()=>{
canvas.width=canvas.width
biao()
zhen()
},1000)
</script>
</body>
</html>
饼图:
代码思路:
第一步:获取到我们的数据,这里的数据全为我们自己的假数据,目前只作为我们的案例来使用,之后需要我们自己从后端获取到数据,求和把做饼图的部分进行求和,得到总值,总值也就代表了一整个圆。
第二步:使用foreach去遍历数组中的每个数字部分,算出他们占总值的比例,根据canvas的曲线绘制的函数可以知道,每次循环只画出了那一段的曲线所以要回到圆心,最后再把下次循环的起始角度改为这次循环的终止角度就行,填充会自动闭合,前面的设置会随机颜色
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<style>
#box {
border: 1px black solid;
}
</style>
<body>
<canvas id="box" height="700" width="700"> </canvas>
<script>
/** @type {HTMLCanvasElement} */
var canvas = document.querySelector("#box")
var ctx = canvas.getContext("2d")
var deg = Math.PI / 180
var arr = [{
name: "小面",
money: 10
}, {
name: "火锅",
money: 200
}, {
name: "串串",
money: 100
}, {
name: "冒菜",
money: 80
},{
name: "涮羊肉",
money: 300
},{
name: "牛杂煲",
money: 168
}]
total=0;
for(var i=0;i<arr.length;i++){
total=total+arr[i].money
}
console.log(total)
var start=60
arr.forEach(element => {
ctx.beginPath()
var r=parseInt(Math.random()*255)
var g=parseInt(Math.random()*255)
var b=parseInt(Math.random()*255)
ctx.fillStyle=`rgb(${r},${g},${b})`
var bili=(element.money/total)*360
ctx.arc(300,300,200,start*deg,(start+bili)*deg)
ctx.lineTo(300,300)
start=start+bili
ctx.fill()
ctx.stroke()
});
</script>
</body>
</html>
五角星:
代码思路:其实五角星的设计更加简单,就是画出一个圆,然后再圆上找出距离相等的五个点然后把这五个点连线连起来
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<style>
#box {
border: 1px black solid;
}
</style>
<body>
<canvas id="box" height="700" width="700"> </canvas>
<script>
/** @type {HTMLCanvasElement} */
var canvas = document.querySelector("#box")
var ctx = canvas.getContext("2d")
var deg = Math.PI / 180
ctx.arc(300,300,200,0,360*deg)
arr=[]
for(i=0;i<5;i++){
var dian={
x:300 + 200*Math.cos((i*72)*deg),
y:300 + 200*Math.sin((i*72)*deg)
}
arr.push(dian)
}
console.log(arr)
ctx.moveTo(arr[0].x,arr[0].y)
ctx.lineTo(arr[2].x,arr[2].y)
ctx.lineTo(arr[4].x,arr[4].y)
ctx.lineTo(arr[1].x,arr[1].y)
ctx.lineTo(arr[3].x,arr[3].y)
ctx.lineTo(arr[0].x,arr[0].y)
ctx.stroke()
</script>
</body>
</html>
这里解释一下为什么连线的顺序是使用的024130的顺序
因为五角星的连线就是隔开一个点,然后相连,如果顺着连那么就是五边形了