Appearance
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
html,
body {
width: 100vw;
height: 100vh;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
background-color: #ddd;
}
</style>
</head>
<body>
<canvas id="canvas"></canvas>
<script>
const canvas = document.querySelector('#canvas')
const context = canvas.getContext('2d')
canvas.width = 650
canvas.height = 450
canvas.style.background = 'white'
context.textAlign = 'center'
context.textBaseline = 'middle'
const drawGrid = (stepX, stepY, lineWidth, color) => {
const { width, height } = canvas
context.lineWidth = lineWidth
context.strokeStyle = color
// horizontal line
for (let i = stepY + lineWidth; i < height; i += stepY) {
context.beginPath()
context.moveTo(0, i)
context.lineTo(width, i)
context.stroke()
}
// vertical line
for (let i = stepX + lineWidth; i < width; i += stepX) {
context.beginPath()
context.moveTo(i, 0)
context.lineTo(i, height)
context.stroke()
}
}
const center = { x: 325, y: 225 }
const { PI, cos, sin } = Math
const drawCircles = () => {
const { x, y } = center
const r1 = 200
const r2 = 180
const startAngle = 0
const endAngle = PI * 2
// 内外两个圆
context.beginPath()
context.arc(x, y, r1, startAngle, endAngle)
context.strokeStyle = 'blue'
context.stroke()
context.arc(x, y, r2, startAngle, endAngle, true)
context.fillStyle = 'rgba(0, 0, 0, .1)'
context.fill()
}
const drawTicks = () => {
const { x, y } = center
const tickWidth = 2
const tickHeight = 10
for (let i = 0; i < 360; i += 10) {
const angle = i / 180 * Math.PI
const _x = x + cos(angle) * 180
const _y = y + sin(angle) * 180
const _tickHeight = i % 30 === 0 ? tickHeight : tickHeight / 2
context.beginPath()
context.moveTo(_x, _y)
context.lineTo(_x - _tickHeight * cos(angle), _y - _tickHeight * sin(angle))
context.lineWidth = i % 30 === 0 ? tickWidth : tickWidth / 2
context.stroke()
}
}
const drawdrawAnnotations = () => {
const { x, y } = center
const tickWidth = 2
const tickHeight = 30
context.font = '16px Arial'
context.fillStyle = 'blue'
for (let i = 0; i < 360; i += 10) {
if (i % 30 === 0) {
const angle = i / 180 * Math.PI
const _x = x + cos(angle) * 180
const _y = y + sin(angle) * 180
context.fillText(i, _x - tickHeight * cos(angle), _y - tickHeight * sin(angle))
}
}
}
const drawCursor = () => {
const { x, y } = center
const r = 10
const startAngle = 0
const endAngle = PI * 2
context.beginPath()
context.arc(x, y, r, startAngle, endAngle)
context.fillStyle = 'green'
context.fill()
context.beginPath()
context.moveTo(x, y)
context.lineTo(x - 200 * sin(30), y - 200 * cos(30))
context.stroke()
}
drawGrid(10, 10, 0.5, '#ddd')
drawCircles()
drawTicks()
drawdrawAnnotations()
drawCursor()
</script>
</body>
</html>