Canvas:实现在线动态时钟效果

想象一下,用几行代码就能创造出如此逼真的图像和动画,仿佛将艺术与科技完美融合,前端开发的Canvas技术正是这个数字化时代中最具魔力的一环,它不仅仅是网页的一部分,更是一个无限创意的画布,一个让你的想象力自由驰骋的平台。

目录

基础页面搭建

设置时分秒针

最终总结


基础页面搭建

接下来借助canvas实现一个简易的动态时钟操作,首先这里我们设置一下画布的一些基础布局样式:

<canvas id="canvas" width="800" height="600"></canvas>
<script>
    // 获取canvas画布绘制上下文对象以及获取2d画笔对象
    let canvas = document.getElementById("canvas");
    let ctx = canvas.getContext("2d");
</script>

接下来我们通过两个for循环,实现小时与分钟的刻度显示,其中ctx.save()和ctx.restore()用于管理绘图状态,确保不同的绘图操作不会相互影响,代价如下:

ctx.save() // 存档
ctx.translate(400, 300) // 平移
ctx.rotate(-Math.PI / 2) // 旋转

ctx.save() // 存档
for (let i = 0; i < 12; i++) {
    // 绘制小时的刻度
    ctx.beginPath()
    ctx.moveTo(170, 0)
    ctx.lineTo(190, 0)
    ctx.strokeStyle = 'gray';
    ctx.lineWidth = 8
    ctx.stroke()
    ctx.closePath()
    ctx.rotate(2 * Math.PI / 12)
}
ctx.restore() // 恢复上一层坐标
ctx.save() // 存档
for (let i = 0; i < 60; i++) {
    // 绘制分钟的刻度
    ctx.beginPath()
    ctx.moveTo(180, 0)
    ctx.lineTo(190, 0)
    ctx.strokeStyle = 'gray';
    ctx.lineWidth = 2
    ctx.stroke()
    ctx.closePath()
    ctx.rotate(2 * Math.PI / 60)
}
ctx.restore() // 恢复上一层坐标
ctx.save() // 存档

最终呈现的效果如下所示:

设置时分秒针

接下来我们借助设计时分秒针的样式,通过date函数获取当前的时分秒的时间,然后通过借助JS的动态渲染函数requestAnimationFrame来动态改变当前的时间,具体的步骤如下所示,整段代码就完成了利用 Canvas 绘制时钟的功能,根据当前时间动态绘制时、分、秒针的效果:

// 获取当前时间
let time = new Date();
let hour = time.getHours();
let min = time.getMinutes();
let sec = time.getSeconds();
hour = hour >= 12 ? hour - 12 : hour; // 12小时制
// 绘制时针
ctx.rotate(2 * Math.PI / 12 * hour + 2 * Math.PI / 12 / 60 * min + 2 * Math.PI / 12 / 60 / 60 * sec)
ctx.beginPath()
ctx.moveTo(-15, 0)
ctx.lineTo(110, 0)
ctx.strokeStyle = '#333';
ctx.lineWidth = 8
ctx.stroke()
ctx.closePath()
ctx.restore() // 恢复上一层坐标
ctx.save() // 存档
// 绘制分针
ctx.rotate(2 * Math.PI / 60 * min + 2 * Math.PI / 60 / 60 * sec)
ctx.beginPath()
ctx.moveTo(-20, 0)
ctx.lineTo(130, 0)
ctx.strokeStyle = '#888';
ctx.lineWidth = 4
ctx.stroke()
ctx.closePath()
ctx.restore() // 恢复上一层坐标
ctx.save() // 存档
// 绘制秒针
ctx.rotate(2 * Math.PI / 60 * sec)
ctx.beginPath()
ctx.moveTo(-30, 0)
ctx.lineTo(190, 0)
ctx.strokeStyle = 'red';
ctx.lineWidth = 2
ctx.stroke()
ctx.closePath()
ctx.restore() // 恢复上一层坐标

ctx.restore() // 恢复上一层坐标

为了让时钟能够动态的进行时间的跳转,这里我们记住requestAnimationFrame函数进行动画帧的渲染,代码如下:

requestAnimationFrame(render)

最终呈现的效果如下所示:

最终总结

接下来对代码实现了一个基于 HTML5 Canvas 的动态时钟效果,让我逐步解释其实现思路:

清除画布:ctx.clearRect(0, 0, 800, 600); 每帧开始时清除整个画布,避免之前的绘制残留。
变换画布原点:ctx.translate(400, 300); 将画布原点移到中心点位置,便于后续绘制钟表。
旋转坐标系:ctx.rotate(-Math.PI / 2); 将坐标系旋转,使得钟表的 12 点方向朝上。
绘制钟表刻度:分别用循环绘制小时和分钟的刻度,每次绘制完成后旋转坐标系到下一个刻度位置。
获取当前时间:使用 new Date() 获取当前时间的小时、分钟和秒数。
绘制时针、分针、秒针:根据当前时间计算旋转角度,分别绘制时针、分针和秒针。
动画效果:使用 requestAnimationFrame(render) 实现每秒钟更新一次画面,形成动态的钟表效果。

按照上面的步骤,这样整个代码就完成了一个基于 Canvas 的动态时钟绘制,实现了钟表的时、分、秒针的动态变化,以及刻度的静态绘制,完整代码如下所示:

<body>
    <canvas id="canvas" width="800" height="600"></canvas>
    <script>
        // 获取canvas画布绘制上下文对象以及获取2d画笔对象
        let canvas = document.getElementById("canvas");
        let ctx = canvas.getContext("2d");

        function render() {
            ctx.clearRect(0, 0, 800, 600);

            ctx.save() // 存档
            ctx.translate(400, 300) // 平移
            ctx.rotate(-Math.PI / 2) // 旋转

            ctx.save() // 存档
            for (let i = 0; i < 12; i++) {
                // 绘制小时的刻度
                ctx.beginPath()
                ctx.moveTo(170, 0)
                ctx.lineTo(190, 0)
                ctx.strokeStyle = 'gray';
                ctx.lineWidth = 8
                ctx.stroke()
                ctx.closePath()
                ctx.rotate(2 * Math.PI / 12)
            }
            ctx.restore() // 恢复上一层坐标
            ctx.save() // 存档
            for (let i = 0; i < 60; i++) {
                // 绘制分钟的刻度
                ctx.beginPath()
                ctx.moveTo(180, 0)
                ctx.lineTo(190, 0)
                ctx.strokeStyle = 'gray';
                ctx.lineWidth = 2
                ctx.stroke()
                ctx.closePath()
                ctx.rotate(2 * Math.PI / 60)
            }
            ctx.restore() // 恢复上一层坐标
            ctx.save() // 存档

            // 获取当前时间
            let time = new Date();
            let hour = time.getHours();
            let min = time.getMinutes();
            let sec = time.getSeconds();
            hour = hour >= 12 ? hour - 12 : hour; // 12小时制
            // 绘制时针
            ctx.rotate(2 * Math.PI / 12 * hour + 2 * Math.PI / 12 / 60 * min + 2 * Math.PI / 12 / 60 / 60 * sec)
            ctx.beginPath()
            ctx.moveTo(-15, 0)
            ctx.lineTo(110, 0)
            ctx.strokeStyle = '#333';
            ctx.lineWidth = 8
            ctx.stroke()
            ctx.closePath()
            ctx.restore() // 恢复上一层坐标
            ctx.save() // 存档
            // 绘制分针
            ctx.rotate(2 * Math.PI / 60 * min + 2 * Math.PI / 60 / 60 * sec)
            ctx.beginPath()
            ctx.moveTo(-20, 0)
            ctx.lineTo(130, 0)
            ctx.strokeStyle = '#888';
            ctx.lineWidth = 4
            ctx.stroke()
            ctx.closePath()
            ctx.restore() // 恢复上一层坐标
            ctx.save() // 存档
            // 绘制秒针
            ctx.rotate(2 * Math.PI / 60 * sec)
            ctx.beginPath()
            ctx.moveTo(-30, 0)
            ctx.lineTo(190, 0)
            ctx.strokeStyle = 'red';
            ctx.lineWidth = 2
            ctx.stroke()
            ctx.closePath()
            ctx.restore() // 恢复上一层坐标

            ctx.restore() // 恢复上一层坐标
            requestAnimationFrame(render)
        }
        render()
    </script>
</body>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/796566.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

万界星空科技MES系统:食品加工安全的实时监控与智能管理

万界星空科技MES系统通过集成多种技术和功能&#xff0c;能够实时监控食品加工过程中各环节的安全风险。以下是对该系统如何实现实时监控的详细分析&#xff1a; 一、集成传感器和数据分析技术 万界星空科技MES系统利用集成的传感器和数据分析技术&#xff0c;实时监控生产过程…

c++ - 多态

文章目录 一、多态的概念二、多态使用三、多态的原理 一、多态的概念 1、概念&#xff1a; 多态就是具有多种形态&#xff0c;可以理解为同一个行为不同对象去完成表现出不同的状态&#xff0c;如&#xff1a; 二、多态使用 1、构成多态的条件 &#xff08;1&#xff09;派…

硬件开发笔记(二十五):AD21导入电解电容原理图库、封装库和3D模型

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/140344547 长沙红胖子Qt&#xff08;长沙创微智科&#xff09;博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV…

[DiT] Scalable Diffusion Models with Transformers

1、目的 用transformer来替代U-Net backbone&#xff0c;提升生成效果 2、方法 Diffusion Transformers (DiTs) 1&#xff09;结构 Latent Diffusion Models (LDMs) -> Transformer (Vision Transformer, ViT) based DDPM -> off-the-shelf convolutional VAE 2&#xf…

Navicat使用教程——连接/新建数据库、SQL实现表的创建/数据插入、解决报错【2059-authentication plugin‘caching_sha2_password’……】

一、连接数据库 以MySQL为例 1、新建连接 &#xff08;1&#xff09;点击“文件”“新建连接”“MySQL” &#xff08;2&#xff09;根据需要&#xff0c;自定义连接名&#xff0c;输入安装MySQL时的密码&#xff0c;点击“连接测试”&#xff0c;确定是否可以连接 &#xf…

【企业级监控】Zabbix实现邮箱报警

Zabbix监控自动化 文章目录 Zabbix监控自动化资源列表基础环境前言四、Zabbix邮件告警4.1、实现报警所需的条件4.1.1、告警媒介4.1.2、触发器&#xff08;trigger&#xff09;4.1.3、动作&#xff08;action&#xff09; 4.2、配置告警媒介4.2.1、设置告警媒介参数4.2.2、启用此…

秋招Java后端开发冲刺——Mybatis使用总结

一、基本知识 1. 介绍 MyBatis 是 Apache 的一个开源项目&#xff0c;它封装了 JDBC&#xff0c;使开发者只需要关注 SQL 语句本身&#xff0c;而不需要再进行繁琐的 JDBC 编码。MyBatis 可以使用简单的 XML 或注解来配置和映射原生类型、接口和 Java POJO&#xff08;Plain …

【提交ACM出版 | EIScopus检索稳定 | 高录用】第五届大数据与社会科学国际学术会议(ICBDSS 2024,8月16-18)

第五届大数据与社会科学国际学术会议&#xff08;ICBDSS 2024&#xff09;将于2024年08月16-18日在中国-上海隆重举行。 ICBDSS会议在各专家教授的支持下&#xff0c;去年已成功举办了四届会议。为了让更多的学者有机会参与会议分享交流经验。本次会议主要围绕“大数据”、“社…

小浣熊素材 - 分析博客文章分布

我上传的 Excel&#xff0c;第一列为文章标题&#xff0c;请你分析这个 Excel 里总共的文章数量&#xff0c;并且根据文章标题&#xff0c;智能地将这些文章进行归类&#xff0c;然后绘制出饼状图&#xff0c;展示每一类的文章&#xff0c;占文章总数的百分比。 自己的 Pytho…

51单片机STC89C52RC——17.1 红外线遥控器

目的/效果 LCD1602显示红外遥控按键值 一&#xff0c;STC单片机模块 二&#xff0c;红外线遥控器 2.1 简介 人的眼睛能看到的可见光按波长从长到短排列&#xff0c;依次为红、橙、黄、绿、青、蓝、紫。 光的波长和频率如下图 红外遥控是利用红外光进行通信的设备&#xff0…

程序的控制结构——switch语句【互三互三】

文章目录 &#x1f341; 引言 &#x1f341;1.语句格式&#xff1a; &#x1f341;2.语句执行过程 &#x1f341;3.语句格式举例 &#x1f341;例题 &#x1f449;【例1】 &#x1f680;示例代码 &#x1f449;【例2】 &#x1f680;【分析】 &#x1f680;示例代码…

【linux】进程间通信(IPC)——匿名管道,命名管道与System V内核方案的共享内存,以及消息队列和信号量的原理概述

目录 ✈必备知识 进程间通信概述 &#x1f525;概述 &#x1f525;必要性 &#x1f525;原理 管道概述 &#x1f525;管道的本质 &#x1f525;管道的相关特性 &#x1f525;管道的同步与互斥机制 匿名管道 &#x1f525;系统调用接口介绍 &#x1f525;内核原理 …

如何搞定美国TikTok直播网络?

在全球范围内&#xff0c;TikTok已经积累了超过30亿次的下载量&#xff0c;月活跃用户达到13亿以上&#xff0c;支持75种语言&#xff0c;覆盖了150多个国家和地区。这一庞大的流量池吸引了众多国内电商人尝试在TikTok上进行业务拓展。本文将探讨如果要在美国运营TikTok直播&am…

Kithara与OpenCV (一)

Kithara使用 OpenCV 库 目录 Kithara使用 OpenCV 库简介需求和支持的环境构建 OpenCV 库使用 CMake 进行配置以与 Kithara 一起工作 使用 OpenCV 库设置项目运行 OpenCV 代码图像采集和 OpenCV自动并行化限制和局限性1.系统建议2.实时限制3.不支持的功能和缺失的功能4.显示 Ope…

彻底搞懂JVM垃圾回收

哈喽&#xff0c;大家好&#x1f389;&#xff0c;我是世杰。 欢迎大家关注我的公众号『程序员世杰』获取更多后端技术干货&#x1f389;&#x1f389;! 本文我为大家介绍「JVM垃圾回收那些事」 面试连环call 如何判断对象是否应被回收?finalize方法的实现机制是什么?如何判…

触摸屏虚拟键盘组件 jQuery Virtual Keyboard使用 自定义键盘

如何在触摸设备上为输入域添加虚拟键盘&#xff1f; 一个插件可以解决这个问题&#xff0c;关键还支持高度自定义&#xff08;git地址&#xff09;&#xff1a; GitHub - Mottie/Keyboard: Virtual Keyboard using jQuery ~ 官网地址&#xff1a;Virtual Keyboard 使用步骤&…

Photoshop

彩色转灰度&#xff1a;ctrlshiftu 背景转黑色&#xff1a; 魔术棒容差10 shift连选 shiftF5&#xff08;填充&#xff09;钢笔选择 路径 工作路径 将路径作为选区载入 点回图层 按ctrlx删除选区 待更新

如何找回误删的文件?4个常用文件恢复方法!

对于许多用户来说&#xff0c;误删文件是一种常见而令人懊恼的情况。恢复误删文件的重要性在于&#xff0c;它可以帮助用户找回宝贵的数据&#xff0c;避免因数据丢失带来的各种不便和损失。 如何找回不小心删除的文件&#xff1f; 误删数据不知道怎么恢复&#xff0c;会给我…

Spring MVC入门3

看完这篇博客你能学到什么 理解JSON的使用理解注解PathVariable理解解注解RequestPart理解cookie和Session的基本概念理解cookie和Session的区别 如果想真正掌握&#xff0c;还需要自己勤加练习。 正文 JSON JSON概念 JSON&#xff1a;JavaScript Object Notation 【JavaS…

传输层协议之UDP

1、端口号 我们在应用层创建的套接字&#xff0c;是需要通过bind()接口绑定我们的IP地址与端口号的&#xff0c;这是因为数据从传输层向上交付到应用层时&#xff0c;需要用端口号来查找特定的服务进程。一般在网络通信时&#xff0c;用IP地址标识一台主机&#xff0c;用端口号…