JS在Canvas元素内绘制钟表

 更新时间:2022年01月19日 11:03:57   作者:老马-Max  
这篇文章介绍了JS在Canvas元素内绘制钟表的方法,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

首先,canvas语法基础薄弱的小伙伴请点这里,剩下的小伙伴们可以接着往下看了。

一个表,需要画什么出来呢:3条线(时分秒针),1个圆(表盘),以及60条短线/点(刻度)。

嗯,没毛病。

那接下来让我们考虑点细节:一个圆,自然是360°,分成60个刻度,两个刻度之间相隔6°,然后分针和秒针刻度偏移是相同的,时针的刻度偏移应该是它们的5倍(只有12个小时刻度)=30°,然而你见过时分秒针一样长的表么?(我反正没有)所以我们还需要控制它们的长度是不一样的才对。

咳,有了上面的思考作为基础了,开搞。

先定个点画个圆:

var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.arc(X坐标, Y坐标, 半径, 0, 2 * Math.PI, false);
ctx.strokeStyle = 随便填颜色;
ctx.stroke();
ctx.closePath();

接下来我们要打上时间刻度,可是问题来了:你是可以画出来一个圆,也知道每个刻度6°角,可如何在画出来的圆上找到对应的坐标呢?

don't worry(数学知识过关的小伙伴们表示毫无压力)~我们只需要去算出正余弦就拿到了对应的XY坐标啦(是的,脚本内正余弦算法不是算角度),具体做法如下:

//计算圆上每个点的坐标
///[a]角度[i]刻度[ox]圆心X坐标[oy]圆心Y坐标[or]圆半径
function angle(a, i, ox, oy, or) {
    var hudu = (2 * Math.PI / 360) * a * i;//求出弧度
    var x = ox + Math.sin(hudu) * or;//计算出x轴坐标for正弦
    var y = oy - Math.cos(hudu) * or;//计算出y轴坐标for余弦
    return x + '_' + y;
}

到了这里,我们就可以愉快的画刻度了:

//打上文字(仅小时)
for (var i = 0; i < 12; i++) {
    var textXY = angle(30, i + 1, ox, oy, or - 10);//小时刻度坐标
    ctx.fillText(i + 1, textXY.split('_')[0], textXY.split('_')[1]);
    ctx.textAlign = 'center';//水平居中
    ctx.textBaseline = 'middle';//垂直居中
}
 
//打上分秒钟刻度
for (var i = 0; i < 60; i++) {
    var oXY = angle(6, i + 1, ox, oy, or);//分、秒刻度坐标
    ctx.beginPath();
    ctx.arc(oXY.split('_')[0], oXY.split('_')[1], (i + 1) % 5 == 0 ? 2 : 1, 0, 2 * Math.PI);
    ctx.fillStyle = 'blue';
    ctx.fill();
    ctx.closePath();
}

为了逼真,我还加入了秒针影响分针,分针影响秒针的计算。(见最后代码)

然后就是考虑三根针不一样长的问题,这个问题试过很多遍,最后我发现最简单的解决办法就是多画3个圆,因为偏移的角度计算方式是一样的。

最后的结果是这样的:

因为不支持上传html文件,所以我就把所有代码贴在这里了:

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>小马的canvas练手作品-时钟</title>
    <meta charset="utf-8" />
</head>
<body>
    <canvas id="myCanvas" width="1000" height="1000">您的浏览器不支持此标签</canvas>
    <script type="text/javascript">
 
        setInterval('drawClock(150, 150, 100, 50, 70, 90,"pink","black","red","green")', 1000);
 
        //画钟表
        //[ox]圆心X坐标[oy]圆心Y坐标[or]钟表半径[hr]时针半径[mr]分针半径[sr]秒针半径[oc]钟表外环颜色[hc]时针颜色[mc]分针颜色[sc]秒针颜色
        function drawClock(ox, oy, or, hr, mr, sr, oc, hc, mc, sc) {
 
            //时钟底盘
            var canvas = document.getElementById('myCanvas');
            var ctx = canvas.getContext('2d');
            ctx.clearRect(ox - or, oy - or, or * 2, or * 2);//清空上一次绘制
            ctx.beginPath();
            ctx.arc(ox, oy, or, 0, 2 * Math.PI, false);
            ctx.strokeStyle = oc;
            ctx.stroke();
            ctx.closePath();
 
            //获取当前时间
            var NowTime = new Date();
            var h = NowTime.getHours();
            var m = NowTime.getMinutes();
            var s = NowTime.getSeconds();
            var y = NowTime.getFullYear();
            var mo = NowTime.getMonth() + 1;
            var d = NowTime.getDate();
            ctx.fillText(mo + '月' + d + '日', ox, oy - or / 2, 50);//显示月日
 
            //打上时间刻度
            for (var i = 0; i < 12; i++) {
                var textXY = angle(30, i + 1, ox, oy, or - 10);//小时刻度坐标
                ctx.fillText(i + 1, textXY.split('_')[0], textXY.split('_')[1]);
                ctx.textAlign = 'center';//水平居中
                ctx.textBaseline = 'middle';//垂直居中
            }
 
            //打上分钟刻度
            for (var i = 0; i < 60; i++) {
                var oXY = angle(6, i + 1, ox, oy, or);//分、秒刻度坐标
                ctx.beginPath();
                ctx.arc(oXY.split('_')[0], oXY.split('_')[1], (i + 1) % 5 == 0 ? 2 : 1, 0, 2 * Math.PI);
                ctx.fillStyle = 'blue';
                ctx.fill();
                ctx.closePath();
            }
 
            h = h + m / 60;//分钟影响时针偏移
 
            var hoursXY = angle(30, h > 12 ? h - 12 : h, ox, oy, hr);//时针终点XY坐标
            drawLine(ctx, hc, ox, oy, hoursXY.split('_')[0], hoursXY.split('_')[1]);
 
            m = m + s / 60;//秒钟影响分针偏移
 
            var minuteXY = angle(6, m, ox, oy, mr);//分针终点XY坐标
            drawLine(ctx, mc, ox, oy, minuteXY.split('_')[0], minuteXY.split('_')[1]);
 
            var secondXY = angle(6, s, ox, oy, sr);//秒针终点XY坐标
            drawLine(ctx, sc, ox, oy, secondXY.split('_')[0], secondXY.split('_')[1]);
 
        }
 
        //计算圆上每个点的坐标
        ///[a]角度[i]刻度[ox]圆心X坐标[oy]圆心Y坐标[or]圆半径
        function angle(a, i, ox, oy, or) {
            var hudu = (2 * Math.PI / 360) * a * i;//求出弧度
            var x = ox + Math.sin(hudu) * or;//计算出x轴坐标for正弦
            var y = oy - Math.cos(hudu) * or;//计算出y轴坐标for余弦
            return x + '_' + y;
        }
 
        //画线方法
        ///[ob]绘画对象[ox]圆心X坐标[oy]圆心Y坐标[px]目标X坐标[py]目标Y坐标
        function drawLine(ob, color, ox, oy, px, py) {
            ob.beginPath();
            ob.strokeStyle = color;
            ob.moveTo(ox, oy);
            ob.lineTo(px, py);
            ob.stroke();
            ob.closePath();
        }<br data-filtered="filtered">
    </script>
</body>
</html>

到此这篇关于JS在Canvas元素内绘制钟表的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • layui实现登陆界面验证码

    layui实现登陆界面验证码

    这篇文章主要为大家详细介绍了layui实现登陆界面验证码,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-11-11
  • 完美实现bootstrap分页查询

    完美实现bootstrap分页查询

    这篇文章主要介绍了一个完美的bootstrap分页查询,如何利用bootstrap实现分页查询,本文将为大家进行揭晓
    2015-12-12
  • js基于myFocus实现轮播图效果

    js基于myFocus实现轮播图效果

    这篇文章主要为大家详细介绍了js基于myFocus实现轮播图效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-02-02
  • 用js判断输入是否为中文的函数

    用js判断输入是否为中文的函数

    本篇文章主要是对js判断输入是否为中文的函数进行了介绍,需要的朋友可以过来参考下,希望对大家有所帮助
    2014-03-03
  • js判断变量是否空值的代码

    js判断变量是否空值的代码

    判断变量是否空值undefined, null, '', false, 0, [], {} 均返回true,否则返回false
    2008-10-10
  • 详解ES6 CLASS在微信小程序中的应用实例

    详解ES6 CLASS在微信小程序中的应用实例

    这篇文章主要介绍了详解ES6 CLASS在微信小程序中的应用实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-04-04
  • JavaScript获取短信验证码(周期性)

    JavaScript获取短信验证码(周期性)

    这篇文章主要为大家详细介绍了JavaScript周期性获取短信验证码的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-12-12
  • 触屏中的JavaScript事件分析

    触屏中的JavaScript事件分析

    这篇文章主要介绍了触屏中的JavaScript事件,实例分析了触屏事件的种类、原理与相关使用技巧,需要的朋友可以参考下
    2015-02-02
  • JS中循环遍历数组的四种方式总结

    JS中循环遍历数组的四种方式总结

    这篇文章主要给大家总结介绍了关于JS中循环遍历数组的四种方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-01-01
  • 谈谈IntersectionObserver懒加载的具体使用

    谈谈IntersectionObserver懒加载的具体使用

    这篇文章主要介绍了谈谈IntersectionObserver懒加载的具体使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-10-10

最新评论