canvas时钟可随着画布变大而比例变大

  1. HTML

没有添加任何图片的canvas时钟,内涵详细注释,放大canvas画布时,时针会随着比例进行变大缩小

<canvas id="clock" width="200px" height="200px"></canvas>

        2.

* {
    margin:0;
    padding:0;
}
canvas {
    display:block;
    margin:200px auto;
}

           3.JS 

var dom = document.getElementById('clock');
var ctx = dom.getContext('2d');
var width = ctx.canvas.width;
var height = ctx.canvas.height;
var r = width / 2;
var rem = width / 200;
//无论canvas画布多大 时钟都会随着比例变化

function drawBackground() {

    ctx.save();
    //保存当前画布 以便使用clearRect()

    /*****************绘制背景圆****************************/

    ctx.translate(r, r);
    //把绘图的中心移动到坐标为(r,r)的位置

    ctx.beginPath();
    //开始绘图

    ctx.lineWidth = 10 * rem;
    //线条宽度


    ctx.arc(0, 0, r - ctx.lineWidth / 2, 0, 2 * Math.PI, false);
    //绘制一个圆坐标为刚刚移动到的位置  因为半径为canvas正方形的一半所以半径要减去线条宽度的一半

    ctx.stroke();
    //绘制

    /****************绘制小时点********************************/
    var hourNumber = [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2];
    //定义一个小时点数组  因为圆的起点是90度那个位置开始的

    ctx.font = 18 * rem + 'px Arial';
    //设置字体大小

    ctx.textAlign = 'center';
    ctx.textBaseline = 'middle';
    //设置文本的对齐方式 文本对齐居中 文本基线居中对齐

    hourNumber.forEach(function(number, i) { //遍历并获取该数组 传入参数 一个为数字 一个是索引

        var rad = 2 * Math.PI / 12 * i;
        //定义弧度 12个数字 相差就是 2*Math.PI / 12 这就是每个小时数的弧度  再乘以索引以对应弧度的计算

        var x = Math.cos(rad) * (r - 30 * rem);
        //求x坐标 用cos方法 在乘以半径 因为小时点的半径肯定会小一些所以就半径也要小一点

        var y = Math.sin(rad) * (r - 30 * rem);
        //求y坐标 方法同上

        ctx.fillText(number, x, y);
        //填充文本 第一个参数是 文本 第二,三个为坐标
    });

    /************绘制分钟点**********************/
    for (var i = 0; i < 60; i++) {
        //利用for循环遍历60个点

        var rad = 2 * Math.PI / 60 * i;
        //定义弧度60个点 

        var x = Math.cos(rad) * (r - 18 * rem);
        //定义x坐标的位置 方法同上

        var y = Math.sin(rad) * (r - 18 * rem);
        //定义y坐标的位置 方法同上

        ctx.beginPath();
        //因为上面有过beginPath所以需要重新绘制

        if (i % 5 === 0) {
            //因为小时点是每隔5个就有一个所以 如果i取余等于0 就是小时数 小时点的样式带啊如下
            ctx.fillStyle = "black"
            ctx.arc(x, y, 2 * rem, 0, 2 * Math.PI, false);
            //绘制圆 半径为2像素
        } else {
            //反过来就是这样
            ctx.fillStyle = "#ccc";
            ctx.arc(x, y, 2 * rem, 0, 2 * Math.PI, false);
            //绘制圆 半径为2像素
        }
        ctx.fill();
        //因为需要实心圆 所以需要填充

    }

}
/****************绘制时针*************/

function drawHour(hour, minute) {
    //绘制时针

    ctx.save();
    //save()和restore连用 表示先将其绘图环境保存起来 restore返回之前保存的状态

    ctx.beginPath();

    var rad = 2 * Math.PI / 12 * hour;
    //设置时针的位置 定义弧度 

    var mrad = 2 * Math.PI / 12 / 60 * minute;
    //因为时间在4:30的时候时针应该会在4-5之间 所以我们需要计算其当时的弧度

    ctx.rotate(rad + mrad);
    //旋转至该弧度  加上分针中间的弧度 所以时针的弧度等于 时针的弧度加上分针的弧度

    ctx.lineCap = 'round';
    //绘制线条为圆头

    ctx.lineWidth = 5 * rem;

    ctx.moveTo(0, 10 * rem);
    //移动圆点 因为时针需要多点尾巴出来所以定义到10;

    ctx.lineTo(0, -r / 2);
    //添一个点,将其链接到这个位置

    ctx.stroke();

    ctx.restore();


}

/*************绘制分针******************/
function drawMinute(minute) {
    //绘制分针方法与时针方法类似

    ctx.save();

    ctx.beginPath();

    var rad = 2 * Math.PI / 60 * minute;

    ctx.rotate(rad);

    ctx.lineWidth = 3 * rem;

    ctx.lineCap = 'round';

    ctx.moveTo(0, 10 * rem);

    ctx.lineTo(0, -r + 30 * rem);

    ctx.stroke();

    ctx.restore();

}

/*******绘制秒针****************/
function drawSecond(second) {

    ctx.save();

    ctx.beginPath();

    ctx.fillStyle = '#f00';

    var rad = 2 * Math.PI / 60 * second;

    ctx.rotate(rad);

    ctx.moveTo(-2 * rem, 20 * rem);
    //绘制秒针的线条 一头大 一头小
    ctx.lineTo(2 * rem, 20 * rem);

    ctx.lineTo(1, -r + 18 * rem);

    ctx.lineTo(-1, -r + 18 * rem);

    ctx.fill();
    //绘制线条颜色

    ctx.restore();
}

/************绘制中心圆点*************/
function drawDot() {

    ctx.beginPath();

    ctx.fillStyle = "#fff";

    ctx.arc(0, 0, 3 * rem, 0, 2 * Math.PI, false);

    ctx.fill();
}




function draw() {

    ctx.clearRect(0, 0, width, height);
    //设置计时器每秒调用一次 但是因为调用后 之前的还会存在所以需要每秒清除画布

    var now = new Date();

    var hour = now.getHours();

    var minute = now.getMinutes();

    var second = now.getSeconds();


    drawBackground();
    drawHour(hour, minute);
    drawMinute(minute);
    drawSecond(second);
    drawDot();
    ctx.restore();
}

setInterval(draw, 1000);

效果图:canvas时钟可随着画布变大而比例变大