Html5 canvas 钟表

简介: 原文:Html5 canvas 钟表看到有不少人用canvas写钟表,今天也来加入他们,自己实现个。   效果图:   实现代码如下: Html5 canvas 钟表 canvas{ border:2px solid Gray; ba...
原文: Html5 canvas 钟表

看到有不少人用canvas写钟表,今天也来加入他们,自己实现个。

 

效果图:

 

实现代码如下:

<html>
<head>
    <title>Html5 canvas 钟表</title>
    <style type="text/css">
        canvas{ border:2px solid Gray; background-color:Gray;}
    </style>
</head>
<body>
    <canvas width="250" height="250"  id="canvas"></canvas>
    <script type="text/javascript">

        //时钟对象
        function clock(canvasID) {

            var TT = new Date();
            var HH = TT.getHours();

            //时,分,秒
            this.HH = HH > 12 ? HH - 12 : HH;
            this.MM = TT.getMinutes();
            this.SS = TT.getSeconds();

            var canvas = document.getElementById(canvasID);
            this.context = canvas.getContext("2d");

            //宽,高,半径,表盘外边框宽度,品牌文字
            this.W = canvas.offsetWidth;
            this.H = canvas.offsetHeight;
            this.R = this.W / 2;
            this.B = 12; 
       this.Brand = "SIMILAR"; }
//初始化设置 clock.prototype.cxtInit = function () { var cxt = this.context;
       
cxt.save();  //保存画布原始状态 cxt.lineWidth = 3; //笔刷宽度为3 cxt.strokeStyle = "White"; //笔刷颜色为白色 cxt.translate(this.R, this.R); //定位中心点 cxt.rotate(-Math.PI / 2); //旋转负90度 cxt.save();  //保存初始化设置后的状态 } //画表盘 clock.prototype.drawCCFace = function () { var cxt = this.context; //外框大圆 cxt.lineWidth = this.B; //笔刷宽度 cxt.beginPath(); cxt.arc(0, 0, this.R - this.B, 0, 2 * Math.PI); cxt.stroke(); cxt.closePath(); //填充黑色 cxt.fillStyle = "Black"; cxt.fill(); cxt.restore(); cxt.save(); //中心小圆 cxt.lineWidth = 3; cxt.beginPath(); cxt.arc(0, 0, 3, 0, 2 * Math.PI); cxt.stroke(); cxt.closePath(); //填充白色 cxt.fillStyle = "White"; cxt.fill(); cxt.restore(); cxt.save(); } //画时针刻度 clock.prototype.drawHHScale = function () { var cxt = this.context; cxt.lineWidth = 3; cxt.beginPath(); for (var i = 1; i < 13; i++) { cxt.rotate(Math.PI / 6); cxt.moveTo(this.R - this.B - 15, 0); cxt.lineTo(this.R - this.B, 0); } cxt.stroke(); cxt.closePath(); cxt.restore(); cxt.save(); } //画分针刻度 clock.prototype.drawMMScale = function () { var cxt = this.context; cxt.lineWidth = 1; cxt.beginPath(); for (var i = 0; i < 60; i++) { if (i % 5 != 0) { cxt.moveTo(this.R-this.B-8, 0); cxt.lineTo(this.R-this.B, 0); } cxt.rotate(Math.PI / 30); } cxt.stroke(); cxt.closePath(); cxt.restore(); cxt.save(); } //画数字 clock.prototype.drawCCNumber = function () { var cxt = this.context; cxt.rotate(Math.PI / 2); for (i = 0; i < 12; i++) { var num = (i + 3 > 12) ? i + 3 - 12 : i + 3; var numX = Math.round(Math.cos(i * Math.PI / 6) * (this.R - this.B - 30)); var numY = Math.round(Math.sin(i * Math.PI / 6) * (this.R - this.B - 30)); cxt.font = 'bold 12px 微软雅黑'; cxt.fillStyle = "White"; cxt.fillText(num, numX - 5, numY + 5); } cxt.restore(); cxt.save(); } //画时针 clock.prototype.drawHHHand = function () { var cxt = this.context; cxt.rotate((Math.PI / 6) * this.HH + (Math.PI / 360) * this.MM + (Math.PI / 21600) * this.SS); cxt.lineCap = "round"; cxt.beginPath(); cxt.moveTo(0, 0); cxt.lineTo(this.R / 2, 0); cxt.stroke(); cxt.closePath(); cxt.restore(); cxt.save(); } //画分针 clock.prototype.drawMMHand = function () { var cxt = this.context; cxt.rotate((Math.PI / 30) * this.MM + (Math.PI / 1800) * this.SS); cxt.lineCap = "round"; cxt.beginPath(); cxt.moveTo(0, 0); cxt.lineTo(this.R - this.B - 20, 0); cxt.stroke(); cxt.closePath(); cxt.restore(); cxt.save(); } //画秒针 clock.prototype.drawSSHand = function () { var cxt = this.context; cxt.rotate(this.SS * Math.PI / 30); cxt.lineWidth = 2; cxt.beginPath(); cxt.moveTo(-20, 0); cxt.lineTo(this.R - this.B - 5, 0); cxt.stroke(); cxt.closePath(); cxt.restore(); cxt.save(); } //画品牌 clock.prototype.drawCCBrand = function () { var cxt = this.context; cxt.rotate(Math.PI / 2); cxt.font = "15px Arial" cxt.fillStyle = "White"; cxt.fillText(this.Brand, - 25, -(this.R - 80), 50); cxt.restore(); cxt.save(); } //还原画布到原始状态 clock.prototype.cxtBackOriginal = function () { var cxt = this.context; cxt.restore(); cxt.restore(); } //主函数 function Main() { var c = new clock("canvas"); //初始化 c.cxtInit(); //表盘 c.drawCCFace(); //刻度,数字 c.drawHHScale(); c.drawMMScale(); c.drawCCNumber(); //指针 c.drawHHHand(); c.drawMMHand(); c.drawSSHand(); //品牌 c.drawCCBrand(); //还原画布 c.cxtBackOriginal(); } setInterval(Main, 1000); </script> </body> </html>

 

上面是初始版本,上面这个版本性能是极差的,因为每隔1秒就会创建1个新对象,即:new clock()

刚开始想到的解决方案是用 单例模式 ,但结果行不通,因为时间必须是实时的,如果用 单例模式 则时间就一直是第一次new clock()时的那个时间,因此也就不会走针。

之后修改如下:

<html>
<head>
    <title>Html5 canvas 钟表</title>
    <style type="text/css">
        canvas{ border:2px solid Gray; background-color:Gray;}
    </style>
</head>
<body>
    <canvas width="250" height="250"  id="canvas"></canvas>
    <script type="text/javascript">

        //时钟对象
        function clock(canvasID) {
            
            //取得画布对象
            var canvas = document.getElementById(canvasID);
            this.context = canvas.getContext("2d");

            //宽,高,半径,表盘外边框宽度,品牌文字
            this.W = canvas.offsetWidth;
            this.H = canvas.offsetHeight;
            this.R = this.W / 2;
            this.B = 12;
            this.Brand = "SIMILAR";         
        }

        //初始化设置
        clock.prototype.cxtInit = function () {

            var cxt = this.context;

            cxt.save(); //保存画布原始状态

            cxt.clearRect(0, 0, this.W, this.H);    //清空画布
            cxt.lineWidth = 3;                      //笔刷宽度为3
            cxt.strokeStyle = "White";              //笔刷颜色为白色
            cxt.translate(this.R, this.R);          //定位中心点
            cxt.rotate(-Math.PI / 2);               //旋转负90度

            cxt.save(); //保存初始化设置后的状态
        }

        //画表盘
        clock.prototype.drawCCFace = function () {

            var cxt = this.context;

            //外框大圆
            cxt.lineWidth = this.B; //笔刷宽度

            cxt.beginPath();
            cxt.arc(0, 0, this.R - this.B, 0, 2 * Math.PI);
            cxt.stroke();
            cxt.closePath();

            //填充黑色
            cxt.fillStyle = "Black";
            cxt.fill();

            cxt.restore();
            cxt.save();

            //中心小圆
            cxt.lineWidth = 3;
            cxt.beginPath();
            cxt.arc(0, 0, 3, 0, 2 * Math.PI);
            cxt.stroke();
            cxt.closePath();

            //填充白色
            cxt.fillStyle = "White";
            cxt.fill();

            cxt.restore();
            cxt.save();
        }

        //画时针刻度
        clock.prototype.drawHHScale = function () {

            var cxt = this.context;

            cxt.lineWidth = 3;
            cxt.beginPath();
            for (var i = 1; i < 13; i++) {
                cxt.rotate(Math.PI / 6);
                cxt.moveTo(this.R - this.B - 15, 0);
                cxt.lineTo(this.R - this.B, 0);
            }
            cxt.stroke();
            cxt.closePath();

            cxt.restore();
            cxt.save();
        }

        //画分针刻度
        clock.prototype.drawMMScale = function () {

            var cxt = this.context;

            cxt.lineWidth = 1;
            cxt.beginPath();
            for (var i = 0; i < 60; i++) {
                if (i % 5 != 0) {
                    cxt.moveTo(this.R-this.B-8, 0);
                    cxt.lineTo(this.R-this.B, 0);
                }
                cxt.rotate(Math.PI / 30);
            }
            cxt.stroke();
            cxt.closePath();

            cxt.restore();
            cxt.save();
        }

        //画数字
        clock.prototype.drawCCNumber = function () {

            var cxt = this.context;

            cxt.rotate(Math.PI / 2);

            for (i = 0; i < 12; i++) {
                var num = (i + 3 > 12) ? i + 3 - 12 : i + 3;
                var numX = Math.round(Math.cos(i * Math.PI / 6) * (this.R - this.B - 30));
                var numY = Math.round(Math.sin(i * Math.PI / 6) * (this.R - this.B - 30));
                cxt.font = 'bold 12px 微软雅黑';
                cxt.fillStyle = "White";
                cxt.fillText(num, numX - 5, numY + 5);
            }

            cxt.restore();
            cxt.save();
        }


        //画指针
        clock.prototype.drawCCHand = function () {

            var tt = new Date();

            //时,分,秒
            var hh = tt.getHours() > 12 ? tt.getHours() - 12 : tt.getHours();var mm = tt.getMinutes();
            var ss = tt.getSeconds();

            var cxt = this.context;

            //画时针
            cxt.rotate((Math.PI / 6) * hh + (Math.PI / 360) * mm + (Math.PI / 21600) * ss);

            cxt.lineCap = "round";
            cxt.beginPath();
            cxt.moveTo(0, 0);
            cxt.lineTo(this.R / 2, 0);
            cxt.stroke();
            cxt.closePath();

            cxt.restore();
            cxt.save();

            //画分针
            cxt.rotate((Math.PI / 30) * mm + (Math.PI / 1800) * ss);

            cxt.lineCap = "round";
            cxt.beginPath();
            cxt.moveTo(0, 0);
            cxt.lineTo(this.R - this.B - 20, 0);
            cxt.stroke();
            cxt.closePath();

            cxt.restore();
            cxt.save();

            //画秒针
            cxt.rotate(ss * Math.PI / 30);

            cxt.lineWidth = 2;
            cxt.beginPath();
            cxt.moveTo(-20, 0);
            cxt.lineTo(this.R - this.B - 5, 0);
            cxt.stroke();
            cxt.closePath();

            cxt.restore();
            cxt.save();
        }

        //画品牌
        clock.prototype.drawCCBrand = function () {

            var cxt = this.context;

            cxt.rotate(Math.PI / 2);

            cxt.font = "15px Arial"
            cxt.fillStyle = "White";
            cxt.fillText(this.Brand, - 25, -(this.R - 80), 50);

            cxt.restore();
            cxt.save();
        }

        //还原画布到原始状态
        clock.prototype.cxtBackOriginal = function () {
            var cxt = this.context;
            cxt.restore();
            cxt.restore();
        }

        //主函数
        function Main() {

            var c = new clock("canvas");

            setInterval(function () {
                //初始化
                c.cxtInit();

                //表盘
                c.drawCCFace();

                //刻度,数字
                c.drawHHScale();
                c.drawMMScale();
                c.drawCCNumber();

                //指针
                c.drawCCHand();

                //品牌
                c.drawCCBrand();

                //还原画布到原始状态
                c.cxtBackOriginal();
            }, 1000);
        }

        Main();
    </script>
</body>
</html>

修改的地方:

1.>将画指针的3个方法(即,画时针,分针,秒针)合并成了一个方法( 即,画指针 drawCCHand() )

2.>将时间的获取放到了drawCCHand()方法里面,而不是在构造函数里面。

3.>在初始化方法cxtInit()里面加了一句代码:cxt.clearRect(0, 0, this.W, this.H);    //清空画布。因为不会重新创建clock对象,所以每次画前要清空前一秒的画布内容

 

如果大家还有好的优化方案或建议,就分享下吧。

推广个新建的WEB前端QQ群:142512178

目录
相关文章
|
22天前
|
前端开发 JavaScript API
2024 新年HTML5+Canvas制作3D烟花特效(附源码)
2024 新年HTML5+Canvas制作3D烟花特效(附源码)
72 0
|
9月前
|
移动开发 前端开发 Shell
《HTML5 Canvas核心技术 图形、动画与游戏开发》 读书笔记
《HTML5 Canvas核心技术 图形、动画与游戏开发》 读书笔记
|
22天前
|
存储 移动开发 前端开发
HTML新特性【HTML5内联SVG、SVG_矩形、SVG 与 Canvas两者间的区别 、HTML5_MathML 】(三)-全面详解(学习总结---从入门到深化)
HTML新特性【HTML5内联SVG、SVG_矩形、SVG 与 Canvas两者间的区别 、HTML5_MathML 】(三)-全面详解(学习总结---从入门到深化)
52 0
|
22天前
|
移动开发 前端开发 API
HTML5 Canvas 提供丰富的绘图API,支持绘制图形、文本、渐变和图像,助力游戏开发
【5月更文挑战第13天】HTML5 Canvas 提供丰富的绘图API,支持绘制图形、文本、渐变和图像,助力游戏开发。关键功能包括绘制基本形状、文本渲染、图像处理及渐变图案。在游戏开发中,Canvas用于绘制游戏元素、实现动画效果、精确的物理碰撞检测,并具有跨平台兼容性,为创造多样化视觉体验和互动游戏提供强大工具。随着技术进步,Canvas在游戏领域的应用将持续增长。
22 4
|
22天前
|
移动开发 前端开发 HTML5
HTML5 Canvas发光Loading源码
一款基于HTML5 Canvas的发光Loading加载HTML源码。Loading旋转图标是在canvas画布上绘制的,整个loading动画是发光3D的视觉效果
22 1
HTML5 Canvas发光Loading源码
|
22天前
|
移动开发 前端开发 HTML5
Canvas实现超酷Loading动画HTML代码
之前我们分享过很多基于CSS3的Loading动画效果,相信大家都很喜欢。今天我们要来分享一款基于HTML5 Canvas的发光Loading加载动画特效。Loading旋转图标是在canvas画布上绘制的,整个loading动画是发光3D的视觉效果,HTML5非常强大。
19 1
Canvas实现超酷Loading动画HTML代码
|
22天前
|
移动开发 前端开发 API
简述HTML5 Canvas的基本绘图API及其在游戏开发中的作用。
HTML5 Canvas 提供丰富的绘图API,用于在网页上绘制图形、动画和视觉效果,支持基本形状、文本、渐变、图像及像素操作。在游戏开发中,Canvas API用于绘制游戏元素、实现动画效果、进行物理碰撞检测,并具备跨平台兼容性,为创新游戏体验提供强有力的支持。
14 1
|
22天前
|
前端开发 JavaScript 容器
编程笔记 html5&css&js 032 HTML Canvas
编程笔记 html5&css&js 032 HTML Canvas
|
22天前
|
移动开发 前端开发 JavaScript
html5 Canvas 绘制基本图形 从直线图形到使用路径 - 直线、矩形、路径、多边形、复杂组合图形
html5 Canvas 绘制基本图形 从直线图形到使用路径 - 直线、矩形、路径、多边形、复杂组合图形
139 0
html5 Canvas 绘制基本图形 从直线图形到使用路径 - 直线、矩形、路径、多边形、复杂组合图形
|
22天前
|
存储 移动开发 前端开发
HTML新特性【HTML5内联SVG、SVG_矩形、SVG 与 Canvas两者间的区别 、HTML5_MathML 】(三)-全面详解(学习总结---从入门到深化)(下)
HTML新特性【HTML5内联SVG、SVG_矩形、SVG 与 Canvas两者间的区别 、HTML5_MathML 】(三)-全面详解(学习总结---从入门到深化)
34 0