canvas案例一时钟

199 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第1天,点击查看活动详情

基础知识

  • 矩形
// 从坐标(0, 0) 到坐标(600, 400)的
// 矩形是以'#f00'为填充色的填充矩形
 ctx.fillStyle = '#f00'
 ctx.fillRect(0, 0, 600, 400)
 
 // 只有边框的矩形,无填充。
 ctx.strokeStyle = '#f00'
 ctx.strokeRect(0, 0, 600, 400)
 
 
  • 画圆

// 设置圆心的中心点
 ctx.translate(250, 150)// translate 设置中心点
 
 // CanvasPath.arc(x: number, y: number, radius: number, startAngle: number, endAngle: number, counterclockwise?: boolean): void
// 以(0,0)为圆心,10px为半径,从0度开始到2π画圆 
 ctx.arc(0, 0, 10, 0, 2 * Math.PI)

  • 画线
// 从(10, 0)到坐标(60, 0)画一条红色的线
ctx.moveTo(10, 0)
ctx.lineTo(60, 0)
ctx.lineWidth = 5
ctx.strokeStyle = '#f00'
ctx.stroke()

  • 三角形怎么画
// 其实就是三角形的三个点画线
ctx.moveTo(10, 0)
ctx.lineTo(60, 0)
ctx.lineTo(50, 30)


  • ctx.beginPath()ctx.closePath()

开始一个新的路径 目的是保证当前的绘制与其他绘制不相互影响。

  • ctx.restore()成对存在 ctx.save()

如下例子,画了水平画了三个填充的矩形。第一个画了一个红色矩形后后调用了save()保存状态,紧接着画了一个蓝色的,最后恢复调用save()之前状态,所以最后一个矩形也是红色的。

ctx.fillStyle = "#f00";
ctx.fillRect(0, 0, 100, 100); 
ctx.save(); // 保存状态 
ctx.fillStyle = "#00f"; 
ctx.fillRect(0, 150, 100, 100);
ctx.restore(); // 还原到上次保存的状态 
ctx.fillRect(0, 300, 100, 100);

完整的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">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <title>canvas</title>
    <style>
        canvas {
            box-shadow: 0px 0px 5px #ccc;
            border-radius: 8px;
        }
    </style>
</head>

<body>

    <div id="app">
        <canvas id="canvas_clock" width="500" height="300">
            当前浏览器不支持canvas元素,请升级或更换浏览器!
        </canvas>
    </div>

    <script>
        const canvasClock = document.getElementById('canvas_clock')
        if (canvasClock.getContext) {
            const ctx = canvasClock.getContext('2d')

            setInterval(() => {
                ctx.save()
                ctx.clearRect(0, 0, 600, 600)

                ctx.fillStyle = '#1e80ff'
                ctx.fillRect(0, 0, 600, 400)
                ctx.translate(250, 150)// translate 设置中心点
                ctx.save()


                // ctx.beginPath()
                // ctx.arc(0, 0, 100, 0, 2 * Math.PI);
                // ctx.stroke()
                // ctx.closePath()

                ctx.beginPath()
                ctx.arc(0, 0, 1, 0, 2 * Math.PI)
                ctx.stroke()
                ctx.closePath()


                let time = new Date()
                let hour = time.getHours() % 12
                let min = time.getMinutes()
                let sec = time.getSeconds()







                ctx.rotate(2 * Math.PI / 12 * hour + 2 * Math.PI / 12 * (min / 60) - Math.PI / 2)
                ctx.beginPath()
                ctx.moveTo(-10, 0)
                ctx.lineTo(60, 0)
                ctx.lineWidth = 5
                ctx.strokeStyle = '#fff'
                ctx.stroke()
                ctx.closePath()
                ctx.restore()
                ctx.save()





                // 分    60分 = 360度   1分钟 = 60度    

                ctx.rotate(min * 2 * Math.PI / 60 + 2 * Math.PI / 60 * sec / 60 - Math.PI / 2)
                ctx.beginPath()
                ctx.moveTo(-10, 0)
                ctx.lineTo(80, 0)
                ctx.lineWidth = 3
                ctx.strokeStyle = '#fff'
                ctx.stroke()
                ctx.closePath()
                ctx.restore()
                ctx.save()

                ctx.rotate(2 * Math.PI / 60 * sec - Math.PI / 2)
                ctx.beginPath()
                ctx.moveTo(-10, 0)
                ctx.lineTo(80, 0)
                ctx.lineWidth = 2
                ctx.strokeStyle = '#f00'
                ctx.stroke()
                ctx.closePath()
                ctx.restore()
                ctx.save()


                for (let i = 0; i < 60; i++) {
                    ctx.rotate(2 * Math.PI / 60)
                    ctx.beginPath()
                    ctx.moveTo(90, 0)
                    ctx.lineTo(100, 0)
                    ctx.strokeStyle = '#fff'
                    ctx.stroke()
                    ctx.closePath()
                }
                ctx.restore()
                ctx.save()
                ctx.lineWidth = 5

                for (let i = 0; i < 12; i++) {
                    ctx.rotate(2 * Math.PI / 12)
                    ctx.beginPath()
                    ctx.moveTo(85, 0)
                    ctx.lineTo(100, 0)
                    ctx.strokeStyle = '#fff'
                    ctx.stroke()
                    ctx.closePath()
                }


                ctx.restore()
                ctx.restore()
            }, 1000)

        } else {
            console.log('===============')
        }

    </script>

    <!-- built files will be auto injected -->
</body>

</html>