zoukankan      html  css  js  c++  java
  • 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);

    效果图:

  • 相关阅读:
    SqlServer实现Oracle的wm_concat()函数功能
    WebApi异常过滤器
    C#DataTable转List<Models>
    C#访问Oracle或SqlServer数据库遍历添加参数
    C#+.netFrameWork4.5.2+WebAPI+Jquery+Ajax跨域请求问题
    VS2015+Windows服务简易教程+文件夹监听
    C# rpt 批量打印写法
    C#model序列化xml
    oracle em无法连接数据库实例
    childNodes与children
  • 原文地址:https://www.cnblogs.com/sharing1986687846/p/10314987.html
Copyright © 2011-2022 走看看