头图

image.png

Original origin position
image.png

After translation, translate(300, 300), the position of the origin is the center of the circle
image.png

It should be noted that whether it is the hour hand, minute hand or second hand, this position is used as the starting point for drawing. The hour hand needs to make two turns to calculate the angle of rotation of the hour hand in 24 hours. The minute hand and second hand can only make one turn. The rotation of the three hour, minute, and second hands is calculated based on this principle

image.png

<!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>

    <script>
        window.onload = function () {
            //获取画布
            var canvas = document.querySelector('canvas')
            //获取画笔
            var context = canvas.getContext('2d')
            
            function clock() {
                //绘制圆盘
                context.beginPath()
                context.arc(300, 300, 200, 0, Math.PI * 2)
               
                context.fillStyle = 'yellow'
                context.fill()
                //结束路径
                context.closePath()

                //绘制时刻度
                for (i = 1; i <= 12; i++) {
                    // save():将当前的绘画状态进行保存并存入状态栈
                    //简而言之就是保存画刻度之前的状态 和restore()一起用
                    context.save()
                    context.lineWidth = 4
                    context.beginPath()
                    //将原点平移 圆心位置
                    context.translate(300, 300)
                    //旋转30度  小时的刻度
                    // angle:旋转角度,旋转的中心点就是坐标轴的原点
                    context.rotate(i * (Math.PI / 6))
                    //绘制时刻度  从外向里画(反过来则要负数)
                    context.moveTo(0, 200)
                    context.lineTo(0, 180)
                    context.stroke()
                    context.fillStyle = 'black'
                    // 调整数字的大小
                    context.font = '20px bold'
                    //数半径
                    context.fillText(i, -10, -150)
                    context.closePath()
                    // restore():该方法每次调用只会回滚到上一次save的状态
                    //回退到画刻度之前的save()状态,不影响后面的时针,分针等等的绘制
                    context.restore()

                }

                //绘制分刻度  分针要转60次
                for (i = 1; i <= 60; i++) {
                    context.save()
                    //平移原点    新的原点就是圆心
                    context.translate(300, 300)
                    // 分针要转60次的6度     Math.PI相当于180度
                    context.rotate(i * (Math.PI / 30))
                    context.beginPath()
                    // 绘制分刻度  从里往外画
                    context.moveTo(0, -190)
                    context.lineTo(0, -200)
                    context.stroke()
                    context.closePath()
                    //重复分刻度
                    context.restore()
                }

                //利用内置函数Date() 获取当前时间
                var date = new Date()
                //打印看一下
                console.log(date);
                //获取当前的小时
                var hours = date.getHours()
                //获取当前分钟
                var minutes = date.getMinutes()
                //获取当前秒数
                var seconds = date.getSeconds()
                //打印看一下
                console.log(hours, minutes, seconds);


                //当前的小时数
                hours = hours + minutes / 60;

                //绘制时针  依旧要保存绘画时针前的状态然后画完后回退
                context.save()
                //平移原点
                context.translate(300, 300)
                //小时乘以30度
                // rotate(angle):旋转角度,旋转的中心点就是坐标轴的原点
                context.rotate(hours * (Math.PI / 6))
                context.beginPath()
                context.lineWidth = 5
                context.moveTo(0, 10)
                context.lineTo(0, -90)
                context.stroke()
                context.closePath()
                context.restore()



                //绘制分针
                context.save()
                //平移原点   新原点就是圆心
                context.translate(300, 300)
                //先根据当前分钟旋转到那个位置  找到坐标 
                context.rotate(minutes * (Math.PI / 30))
                //再绘制分针
                context.beginPath()
                //调整时针线宽
                context.lineWidth = 3
                //开始绘制  moveTo() 是移动到分针的起始位置
                context.moveTo(0, 10)
                //lineTo() 是画直线  (0, -120)是结束坐标点 这个坐标点是相对圆心来说的,因为前面translate(300, 300)已经把原点平移到圆心的位置了
                context.lineTo(0, -120)
                context.strokeStyle = 'blue'
                context.stroke()
                context.closePath()
                context.restore()


                //绘制秒针
                context.save()
                context.translate(300, 300)
                //小时乘以30度
                // angle:旋转角度,旋转的中心点就是坐标轴的原点
                context.rotate(seconds * (Math.PI / 30))
                context.beginPath()
                //调整线宽 也就是秒针的宽度
                context.lineWidth = 2
                //绘制秒针
                context.moveTo(0, 10)
                context.lineTo(0, -170)
                //改变秒针样式
                context.strokeStyle = 'red'
                //画的是轮廓图形
                context.stroke()
                //结束路径
                context.closePath()
                //回退状态
                context.restore()



                //绘制交叉处
                //  save():将当前的绘画状态进行保存并存入状态栈
                context.save()
                context.translate(300, 300)
                // 开始路径
                context.beginPath()
                //绘制时钟中间的小圆  xy轴开始位置  小圆半径 开始弧度  结束弧度360度
                context.arc(0, 0, 5, 0, Math.PI * 2)
                //填充圆设置为白色
                context.fillStyle = 'white'
                //轮廓圆设置红色
                context.strokeStyle = 'red'
                //绘制填充圆
                context.fill()
                //绘制轮廓圆
                context.stroke()
                //结束路径
                context.closePath()
                context.restore()

                //超时模拟间歇  避免载入时 时钟先消失一小会儿再出现
                setTimeout(clock, 1000)
            }

            clock()
        }


    </script>
</head>

<body>
    <canvas width="600px" height="600px" style="background-color: rgb(154, 233, 243);"></canvas>
</body>

</html>

Drawing an image, that is, adding a background

image.png

<!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>

    <script>
        window.onload = function () {
            var canvas = document.querySelector('canvas')
            var context = canvas.getContext('2d')

            var img = new Image();
            img.src = 'https://img0.baidu.com/it/u=3743817916,1501906955&fm=26&fmt=auto';
            img.onload = function () {
                // 绘制图片到画布中  从0,0点开始绘制图片,绘制一个200*200的图片
                context.drawImage(img, 0, 0, 600, 600);
            }

            function clock() {
                //绘制圆盘
                context.beginPath()
                context.arc(300, 300, 200, 0, Math.PI * 2)

                context.fillStyle = '#ddd'
                context.fill()
                //结束路径
                context.closePath()

                //绘制时刻度
                for (i = 1; i <= 12; i++) {
                    // save():将当前的绘画状态进行保存并存入状态栈
                    //简而言之就是保存画刻度之前的状态 和restore()一起用
                    context.save()
                    context.lineWidth = 4
                    context.beginPath()
                    //将原点平移 圆心位置
                    context.translate(300, 300)
                    //旋转30度  小时的刻度
                    // angle:旋转角度,旋转的中心点就是坐标轴的原点
                    context.rotate(i * (Math.PI / 6))
                    //绘制时刻度  从外向里画(反过来则要负数)
                    context.moveTo(0, 200)
                    context.lineTo(0, 180)
                    context.stroke()
                    context.fillStyle = 'black'
                    // 调整数字的大小
                    context.font = '20px bold'
                    //数半径
                    context.fillText(i, -10, -150)
                    context.closePath()
                    // restore():该方法每次调用只会回滚到上一次save的状态
                    //回退到画刻度之前的save()状态,不影响后面的时针,分针等等的绘制
                    context.restore()

                }

                //绘制分刻度  分针要转60次
                for (i = 1; i <= 60; i++) {
                    context.save()
                    //平移原点    新的原点就是圆心
                    context.translate(300, 300)
                    // 分针要转60次的6度     Math.PI相当于180度
                    context.rotate(i * (Math.PI / 30))
                    context.beginPath()
                    // 绘制分刻度  从里往外画
                    context.moveTo(0, -190)
                    context.lineTo(0, -200)
                    context.stroke()
                    context.closePath()
                    //重复分刻度
                    context.restore()
                }

                //利用内置函数Date() 获取当前时间
                var date = new Date()
                //打印看一下
                console.log(date);
                //获取当前的小时
                var hours = date.getHours()
                //获取当前分钟
                var minutes = date.getMinutes()
                //获取当前秒数
                var seconds = date.getSeconds()
                //打印看一下
                console.log(hours, minutes, seconds);


                //当前的小时数
                hours = hours + minutes / 60;

                //绘制时针  依旧要保存绘画时针前的状态然后画完后回退
                context.save()
                //平移原点
                context.translate(300, 300)
                //小时乘以30度
                // rotate(angle):旋转角度,旋转的中心点就是坐标轴的原点
                context.rotate(hours * (Math.PI / 6))
                context.beginPath()
                context.lineWidth = 5
                context.moveTo(0, 10)
                context.lineTo(0, -90)
                context.stroke()
                context.closePath()
                context.restore()



                //绘制分针
                context.save()
                //平移原点   新原点就是圆心
                context.translate(300, 300)
                //先根据当前分钟旋转到那个位置  找到坐标 
                context.rotate(minutes * (Math.PI / 30))
                //再绘制分针
                context.beginPath()
                //调整时针线宽
                context.lineWidth = 3
                //开始绘制  moveTo() 是移动到分针的起始位置
                context.moveTo(0, 10)
                //lineTo() 是画直线  (0, -120)是结束坐标点 这个坐标点是相对圆心来说的,因为前面translate(300, 300)已经把原点平移到圆心的位置了
                context.lineTo(0, -120)
                context.strokeStyle = 'blue'
                context.stroke()
                context.closePath()
                context.restore()


                //绘制秒针
                context.save()
                context.translate(300, 300)
                //小时乘以30度
                // angle:旋转角度,旋转的中心点就是坐标轴的原点
                context.rotate(seconds * (Math.PI / 30))
                context.beginPath()
                //调整线宽 也就是秒针的宽度
                context.lineWidth = 2
                //绘制秒针
                context.moveTo(0, 10)
                context.lineTo(0, -170)
                //改变秒针样式
                context.strokeStyle = 'red'
                //画的是轮廓图形
                context.stroke()
                //结束路径
                context.closePath()
                //回退状态
                context.restore()



                //绘制交叉处
                //  save():将当前的绘画状态进行保存并存入状态栈
                context.save()
                context.translate(300, 300)
                // 开始路径
                context.beginPath()
                //绘制时钟中间的小圆  xy轴开始位置  小圆半径 开始弧度  结束弧度360度
                context.arc(0, 0, 5, 0, Math.PI * 2)
                //填充圆设置为白色
                context.fillStyle = 'white'
                //轮廓圆设置红色
                context.strokeStyle = 'red'
                //绘制填充圆
                context.fill()
                //绘制轮廓圆
                context.stroke()
                //结束路径
                context.closePath()
                context.restore()

                //超时模拟间歇  避免载入时 时钟先消失一小会儿再出现
                setTimeout(clock, 1000)
            }

            clock()
        }


    </script>
</head>

<body>
    <canvas width="600px" height="600px" style="margin-left: 600px;"></canvas>
</body>

</html>

云绮棠兮
48 声望10 粉丝

当野心追赶不上才华,便静下心来努力