IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 新手入门Canvas从120行代码实现圆形时钟开始。 -> 正文阅读

[JavaScript知识库]新手入门Canvas从120行代码实现圆形时钟开始。

一、简介:Canvas简介

? ? ??Canvas 自 HTML5 发布以来就受到了广泛的关注,但却很少在项目中使用,所以大部分前端攻城狮都只是知道,很少实践。canvas所具有的强大功能足以令人震撼。用canvas做了个简单的页面时钟,时钟可以实现动态展示时间的效果。

图1:时钟静态效果

? ? 很遗憾的是暂时无法上传视频到博客中,不过相信各位同学一步步做出来也可以看到动态的效果。

二、Canvas简单创建

? ? ? ? 作为HTML5的一个标签,直接在<body></body>中创建canvas标签即可。同其他标签一样,canvas标签中有三个核心的属性,分别是id,width,height。id作为标签的标志,当然是用于js获取dom元素啦,此处可不能使用class哦。而width,height是圈定画布的区域大小,正如插入的代码中的注释一样,此处的长宽设定值不同于style样式中的长宽,具体区别见注释中。当然自己实际进行操作后会将两者的不同区分的更清楚的。

<!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">
    <title>Document</title>
</head>

<body>
    <!-- 此处需要特别注意的是,canvas中的width和height不同于style中的。canvas中表示的是画布中的内容的分辨率,就是如果其长宽设置成小于图片大小,则只展示圈定的部分。而style中是调节的整个内容尺寸的大小,不影响内容的完整性 -->
    <canvas id="canvas1" width="800px" height="600px" style="width: 600px;height:900px;">
    </canvas>
    <script type="text/javascript">
        let canvas1 = document.getElementById("canvas1");
        //此处用于创建画笔,也就是我们绘制图形的工具
        let ctx1 = canvas1.getContext("2d");
    </script>
</body>
</html>

三、时钟表盘、小时分钟刻度的绘制

? ? ? ? 在完成创建canvas标签并给定相关的属性,js获取到dom元素,创建好画笔三步后。接下来就是进行相关的图形绘制了。由于默认的坐标位于页面的右上角,为了便于操作,我们需要将坐标原点进行移动,移动到我们表盘的圆心。以下就是本小节相关的代码,所有的代码如果需要内置到<script>标签中哦。

//移动原点到画布的中心
ctx.translate(400, 300);
//绘制表盘圆,每次进行绘制的时候,都要进行路径的开始和结束。
            ctx.beginPath();
            ctx.arc(0, 0, 200, 0, 2 * Math.PI);
            ctx.strokeStyle = "pink";
            ctx.lineWidth = 10;
            ctx.stroke();
//本次绘制路径结束标志
            ctx.closePath();
            //绘制完成后对画笔进行重置和储存。
            ctx.restore();
            ctx.save();
 //分针刻度绘制;使用for循环对绘制的分针刻度绕圆心进行旋转复制
            for (let j = 0; j < 60; j++) {
                ctx.rotate(Math.PI / 30);
                ctx.beginPath();
                //线段的起点
                ctx.moveTo(175, 0);
                //线段经过的点
                ctx.lineTo(190, 0);
                ctx.strokeStyle = "dark";
                ctx.lineWidth = 4;
                ctx.stroke();
                ctx.closePath();
            }
 ctx.restore();
            ctx.save();
            //绘制时针刻度,按照计算的刻度完成固定的旋转次数。
            for (let i = 0; i < 12; i++) {
                ctx.rotate(Math.PI / 6);
                ctx.beginPath();
                ctx.moveTo(175, 0);
                ctx.lineTo(200, 0);
                ctx.lineWidth = 8;
                ctx.strokeStyle = "Pink";
                ctx.stroke();
                ctx.closePath();
            }
            ctx.restore();
            ctx.save();

? ? ? ?经过上述代码的运行,可以得到下面的效果;是不是感觉初具规模呢?当然,表盘和刻度的的颜色样式可以根据需要自行进行修改。结束了这一小节,下面就要进行时钟的三个指针的绘制啦。

图2:时钟过程效果1

四、时,分,秒指针的绘制和时间的获取

? ? ? 此部分直接上代码啦,具体的说明尽量在代码的注释。

           //创建获取时间
            let time = new Date();
            let hour = time.getHours();
            let min = time.getMinutes();
            let sec = time.getSeconds();
            //表盘只有12个小时的刻度,但是一天有24小时,用三目运算符进行修改。
            hour = hour > 12 ? hour - 12 : hour;
            //此处通过控制台检查获取时间是否正确。
            console.log(hour, '时', min, "分", sec, "秒");

? ? ? ? ? ? ? ? ? ?时、分、秒指针的绘制。

            //绘制秒针
            ctx.beginPath();
            //此处的旋转需要带上sec变量,即获取的秒钟,每次刷新后既可以实现动态走动。
            ctx.rotate(2 * Math.PI / 60 * sec);
            ctx.beginPath();
            ctx.moveTo(-30, 0);
            ctx.lineTo(160, 0);
            ctx.strokeStyle = "grey";
            ctx.lineWidth = 6;
            ctx.lineCap = "round";
            ctx.stroke();
            ctx.closePath();
            ctx.restore();
            ctx.save();
            //绘制分针
            ctx.beginPath();
            //好好思考一下,此处的运算表达式为么这样写呢?下面的时针表达式又是如何来的呢?
            ctx.rotate(2 * Math.PI / 60 * min + 2 * Math.PI / 3600 * sec);
            ctx.beginPath();
            ctx.moveTo(-20, 0);
            ctx.lineTo(135, 0);
            ctx.strokeStyle = "";
            ctx.lineCap = "round";
            ctx.lineWidth = 8;
            ctx.stroke();
            ctx.closePath();
            ctx.restore();
            ctx.save();
             //绘制时针
            ctx.beginPath();
            ctx.rotate(2 * Math.PI / 12 * hour + 2 * Math.PI / 720 * min + 2 * Math.PI / 3600 * sec);
            ctx.beginPath();
            ctx.moveTo(-10, 0);
            ctx.lineTo(100, 0);
            ctx.strokeStyle = "deepskyBlue"
            ctx.lineWidth = 9;
            ctx.lineCap = "round";
            ctx.stroke();
            ctx.closePath();
            ctx.restore();
            ctx.save();

? ? ? ?写到此处,时钟的整体轮廓就已经基本完成了,一边写一边查看效果是前端应该有的良好习惯哦。那我们来看看写到此处应该有什么效果吧。写到此处,每次刷新后可以看到时钟的秒针发生了转动,但是通过控制台打印的本地时间发现并不符合。怎么解决这个问题呢?

? ? 可以通过在开始的坐标原点平移处将表盘的绘制路径旋转45度,代码如下,当然具体的旋转度数要以实际的相差为准。

            //移动原点到画布的中心
            ctx.translate(400, 300);
            //校正秒针,将圆盘进行适当的旋转。
            ctx.rotate(-2 * Math.PI / 4);

? ? 最后在画布的圆心为时钟加上一个圆形小盖子,直接绘制一个半径为10的圆形就好了。至此,时钟的所有画布上的静态组件全部绘制完成了。可是,目前只有通过每次刷新才能实现时钟的运动,有没有什么方式来实现时钟的自动转动呢?先自己思考一下哦。

            //给圆的中心加个圈
            ctx.beginPath();
            ctx.arc(0, 0, 12, 0, 2 * Math.PI)
            ctx.fillStyle = "yellow";
            ctx.fill();
            ctx.closePath();
            ctx.restore();
            ctx.restore();

五、时钟动态效果的创建?

? ? ? ? ? 通过创建一个函数将上述所有代码囊括,在对本函数使用setInterval()方法设定1000ms的周期就可以实现时钟的运转了。先自己动手操作一下吧,本文的结束附上时钟的全部源代码。

六、总结

? ? ? ? 坦诚的说,这个时钟的画布元素比较少,只有简单的表盘、刻度、指针以及小盖子。后续还可以创建一些文字和阴影效果进行丰富,比如可以给指针创建渐变色,阴影等效果。所有的动态效果均是由javascript创建,后续也可以增添更多的新功能。关于canvas的学习,大可不必记住所有的属性方法,需要时直接去查询相关的中文文档会更好。

源码:

<!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">
    <title>Document</title>
</head>

<body>
    <canvas id="canvas1" width="800px" height="600px">

    </canvas>
    <script type="text/javascript">
        let canvas1 = document.querySelector("#canvas1");
        let ctx = canvas1.getContext("2d");
        //保留画笔的设置

        function renderClock() {
            //此指令的目的就是清除划定区域内的所有像素元素。
            ctx.clearRect(0, 0, 600, 800);
            ctx.save();
            //移动原点到画布的中心
            ctx.translate(400, 300);
            //校正秒针,将圆盘进行适当的旋转。
            ctx.rotate(-2 * Math.PI / 4);
            ctx.save();
            //绘制表盘圆,每次进行绘制的时候,都要进行路径的开始和结束。
            ctx.beginPath();
            ctx.arc(0, 0, 200, 0, 2 * Math.PI);
            ctx.strokeStyle = "pink";
            ctx.lineWidth = 10;
            ctx.stroke();
            ctx.closePath();
            //绘制完成后对画笔进行重置和储存。
            ctx.restore();
            ctx.save();
            //分针刻度绘制;
            for (let j = 0; j < 60; j++) {
                ctx.rotate(Math.PI / 30);
                ctx.beginPath();
                //线段的起点
                ctx.moveTo(175, 0);
                //线段经过的点
                ctx.lineTo(190, 0);
                ctx.strokeStyle = "dark";
                ctx.lineWidth = 4;
                ctx.stroke();
                ctx.closePath();
            }
            ctx.restore();
            ctx.save();
            //绘制时针刻度,按照计算的刻度完成固定的旋转次数。
            for (let i = 0; i < 12; i++) {
                ctx.rotate(Math.PI / 6);
                ctx.beginPath();
                ctx.moveTo(175, 0);
                ctx.lineTo(200, 0);
                ctx.lineWidth = 8;
                ctx.strokeStyle = "Pink";
                ctx.stroke();
                ctx.closePath();
            }
            ctx.restore();
            ctx.save();
            //创建获取时间
            let time = new Date();
            let hour = time.getHours();
            let min = time.getMinutes();
            let sec = time.getSeconds();
            //表盘只有12个小时的刻度,但是一天有24小时,用三目运算符进行修改。
            hour = hour > 12 ? hour - 12 : hour;
            //此处通过控制台检查获取时间是否正确。
            console.log(hour, '时', min, "分", sec, "秒");
            //绘制秒针
            ctx.beginPath();
            //此处的旋转需要带上sec变量,即获取的秒钟。
            ctx.rotate(2 * Math.PI / 60 * sec);
            ctx.beginPath();
            ctx.moveTo(-30, 0);
            ctx.lineTo(160, 0);
            ctx.strokeStyle = "grey";
            ctx.lineWidth = 6;
            ctx.lineCap = "round";
            ctx.stroke();
            ctx.closePath();
            ctx.restore();
            ctx.save();
            //绘制分针
            ctx.beginPath();
            ctx.rotate(2 * Math.PI / 60 * min + 2 * Math.PI / 3600 * sec);
            ctx.beginPath();
            ctx.moveTo(-20, 0);
            ctx.lineTo(135, 0);
            ctx.strokeStyle = "";
            ctx.lineCap = "round";
            ctx.lineWidth = 8;
            ctx.stroke();
            ctx.closePath();
            ctx.restore();
            ctx.save();

            //绘制时针
            ctx.beginPath();
            ctx.rotate(2 * Math.PI / 12 * hour + 2 * Math.PI / 720 * min + 2 * Math.PI / 3600 * sec);
            ctx.beginPath();
            ctx.moveTo(-10, 0);
            ctx.lineTo(100, 0);
            ctx.strokeStyle = "deepskyBlue"
            ctx.lineWidth = 9;
            ctx.lineCap = "round";
            ctx.stroke();
            ctx.closePath();
            ctx.restore();
            ctx.save();

            //给圆的中心加个圈
            ctx.beginPath();
            ctx.arc(0, 0, 12, 0, 2 * Math.PI)
            ctx.fillStyle = "yellow";
            ctx.fill();
            ctx.closePath();
            ctx.restore();
            ctx.restore();
        }
        setInterval(function() {
            renderClock()
        }, 1000);
    </script>
</body>

</html>

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-12-23 15:40:27  更:2021-12-23 15:42:46 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 10:44:28-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码