前言
出差旅行相信大家一定会住酒店,大家在酒店的前台进行预订的时候,是不是都会留意。通常在大堂的前方会有一面时钟,大概是下面这种样子:
这里只是一个截图,其实不太完整。上面详细的罗列了巴黎、北京、纽约、伦敦、莫斯科、东京等城市的时间。 通常来说,之所以要展示这么多的时钟,一般是对外的酒店,所面向的客人很多都是外国人,他们来自于四面八方,需要将时间和自己国家的时间一致,也是对时间同步的一种保障,这是一种服务力的体现。
当然,上面这种是实体的钟,需要实体钟表的采购成本。现在电子屏已经很常见也很普及,那么有没有可能将web界面投放到电子屏中,实现电子钟的web化展示,加上前端的样式控制,应该也是可以满足酒店等场所的显示需求。也因此有了本文和相关的程序设计。
本文即以canvas为基础,以支持多时区的多时钟的动态web展示为例。实现一种在html5上的电子钟展示方法,首先介绍canvas是什么,然后具体介绍如何进行时钟的绘制,其次介绍时钟的多时区支持,最后给出运行的实际效果。通过本文可以了解canvas的详细用法,掌握基本的文本绘制、样式控制、属性管理的基本知识,通过多时钟的展示场景,将各个知识点融会贯通。如果您想了解canvas的使用方法,可以来这里看看,有什么疑问的也可以在评论区留言交流。
一、关于canvas技术
虽然canvas不是最新的技术,相信很多朋友也不是很熟悉,因此本节还是花一点时间简单的将canvas的知识做个介绍,让大家有个基本的了解,为下一节内容的讲解打下基础。主要包含三个部分,首先介绍canvas是什么,然后介绍它的语法。更详细的内容,大家可以去看html的教程,上面有详细的描述。
1、canvas是什么
canvas api(画布)是在html5中新增的标签用于在网页实时生成图像,并且可以操作图像内容,基本上它是一个可以用javascript操作的位图(bitmap)。canvas 对象表示一个 html 画布元素 -<canvas>。<canvas> 标记由 apple 在 safari 1.3 web 浏览器中引入。对 html 的这一根本扩展的原因在于,html 在 safari 中的绘图能力也为 mac os x 桌面的 dashboard 组件所使用,并且 apple 希望有一种方式在 dashboard 中支持脚本化的图形。firefox 1.5 和 opera 9 都跟随了 safari 的引领。这两个浏览器都支持 <canvas> 标记。我们甚至可以在 ie 中使用 <canvas> 标记,并在 ie 的 vml 支持的基础上用开源的 javascript 代码(由 google 发起)来构建兼容性的画布。<canvas> 的标准化的努力由一个 web 浏览器厂商的非正式协会在推进, <canvas> 已经成为 html 5 草案中一个正式的标签。
在现代 web 开发中,开发者们更多的会借助 canvas 提供的api去绘制上下文,可以自由绘制各种2d和3d图形,创建富有视觉冲击力的游戏场景和角色。canvas的使用可以使得游戏能够实现流畅的动态效果和用户交互。无论是简单的小游戏还是复杂的游戏引擎,canvas 都被广泛应用。
在webgis开发当中,canvas也是一个非常重要的展示场景,比如我们之前用过的动态标绘组件,也是基于canvas来实现的,它的性能是非常高的。不管是面向2d还是3d的场景,canvas都有用武之地。
2、canvas的属性及渲染特性
canvas的属性比较简单,而且它的属性比较简单,跟普通的html标签的属性是一致的,也可以使用如id、高度和宽度这几个属性。其作用就不再赘述,比较简单。canvas的强大还是取决于它的渲染特性,因此这里简单介绍一下canvas的渲染特性。
说高性能渲染时得说说dom驻留模式和canvas快速模式。
dom驻留模式:一种基于文档对象模型(dom)的渲染技术。在dom驻留模式下,页面的布局和样式是由dom树来掌管的。当页面需要更新时,浏览器会重新计算布局和样式并重新渲染。此模式非常灵活,特别适用于处理动态页面交互和多样化的样式控制。
canvas快速模式:利用html5的canvas元素进行图形渲染。开发者可以使用canvas提供的2d或3d绘图api直接在画布上绘制图形。相比于dom驻留模式,canvas快速模式更加高效。它不关心页面的布局和样式,而是在需要时只重绘受影响的部分。
分层提高canvas性能:可以进一步提升canvas性能的策略,即对变化较少和变化较多的内容进行分开渲染。它能够显著降低完全没有必要的渲染性能开销。分层渲染的思想被广泛应用于各种图形相关的领域,从古老的皮影戏、套色印刷术,到现代电影/游戏工业以及虚拟现实领域等等。
上面简单的对canvas的相关知识进行简单介绍,有了上述的基本知识,下面结合实例讲解canvas的多时区时钟动态展示。
二、canvas动态多时区展示
在了解canvas的基本知识以后,我们来介绍canvas的基本使用。在这个实例中,我们需要在html5页面中,使用canvas绘制6个不同城市的时钟,并且要在时钟上标注是属于哪个城市,其对应的24小时制时间是多少,同时时钟要可以动态转动。本节即以详细代码的形式进行讲解。
1、新建html页面
canvas也是建立在html页面上的组件,因此想要把canvas渲染出来,就一定要创建展示的基础。新建一个html文件,关键代码如下所示:
<!doctype html> <html> <head> <meta charset="utf-8"> <title>canvas 多时区时钟可视化</title> <style> body { background-color: #f5f5f5; } canvas { border: 1px dashed #444; } </style> </head> <body> <table style="width:99%;margin: auto;align:center;"> <tbody> <tr> <td > <canvas id="clock0" width="300" height="300"></canvas> </td> <td> <canvas id="clock1" width="300" height="300"></canvas> </td> <td> <canvas id="clock2" width="300" height="300"></canvas> </td> </tr> <tr> <td> <canvas id="clock3" width="300" height="300"></canvas> </td> <td> <canvas id="clock4" width="300" height="300"></canvas> </td> <td> <canvas id="clock5" width="300" height="300"></canvas> </td> </tr> </tbody> </table> </body> </html>
这里仅展示canvas的功能api,对于页面的特效样式没有做过多的设置,如果是真实项目,建议在这个基础上狠狠地记性样式的修改,改造成符合项目需要的美观的。上面采用table布局,为了展示6个不同城市的时钟,我们使用两行三列的布局模式,每个单元格展示一个时钟。为了实现动态的控制这些时钟,比如第一个时钟用来显示纽约的时间,因此有必要使用id对每个canvas进行分别定义。
2、创建canvas对象
在创建了html页面展示元素之后,我们还需要使用canvas来绘制时钟的效果,为了能实现时钟的动态效果,我们将canvas的id属性从0-5分别设置为clock0-clock5,分别用来代表"纽约","伦敦","巴黎","莫斯科","北京","东京"这五个不同时区的城市。为了在后面的时间绘制中能精准控制,我们将所有的canvas创建出来之后,设置到对应的数组当中。
//创建时钟数组 var clockarray = new array(); var timezonearray = ["纽约","伦敦","巴黎","莫斯科","北京","东京"]; for(var i = 0;i < 6; i++){ const canvas = document.getelementbyid("clock" + i); const ctx = canvas.getcontext("2d"); const centerx = canvas.width / 2; const centery = canvas.height / 2; // 将坐标系移动到中心点 ctx.translate(centerx, centery); clockarray.push(canvas); }
3、绘制所有的时钟
将canvas创建出来后,就可以进行时钟的绘制了。下面将结合源码来详细介绍如何进行时钟的绘制。
function drawclock() { const now = new date(); for(var j = 0;j < 6;j++){ var _canvas = clockarray[j]; var _ctx = _canvas.getcontext("2d"); const radius = _canvas.width / 2 - 5; const centerx = _canvas.width / 2; const centery = _canvas.height / 2; _ctx.clearrect(-centerx, -centery, _canvas.width, _canvas.height); // 每次绘制前清空整个画布 _ctx.beginpath(); _ctx.arc(0, 0, radius, 0, 2 * math.pi); _ctx.stroke(); // 绘制钟表数字 _ctx.textalign = "center"; _ctx.textbaseline = "middle"; _ctx.font = "20px sans-serif"; var text = timezonearray[j]; _ctx.stroketext(text + "时间", 2, - 80); _ctx.font = "bold 14px arial"; drawclocknumber(_ctx,radius);//绘制数字 // 绘制时针 var bjhour = now.gethours(); //获取小时 var hour = gethour(j,bjhour); var minute = now.getminutes(); var second = now.getseconds(); drawshowtime(_ctx,hour,minute,second);//绘制当前时间 var hourangle = (hour % 12 + minute / 60 + second / 3600) * math.pi / 6; var hourlength = 0.6 * radius; var hourx = math.sin(hourangle) * hourlength; var houry = -math.cos(hourangle) * hourlength; _ctx.beginpath(); _ctx.moveto(0, 0); _ctx.lineto(hourx, houry); _ctx.linewidth = 4; _ctx.linecap = "round"; _ctx.stroke(); // 绘制分针 const minuteangle = (minute + second / 60) * math.pi / 30; const minutelength = 0.8 * radius; const minutex = math.sin(minuteangle) * minutelength; const minutey = -math.cos(minuteangle) * minutelength; _ctx.beginpath(); _ctx.moveto(0, 0); _ctx.lineto(minutex, minutey); _ctx.linewidth = 2; _ctx.stroke(); // 绘制秒针 const secondangle = second * math.pi / 30; const secondlength = 0.9 * radius; const secondx = math.sin(secondangle) * secondlength; const secondy = -math.cos(secondangle) * secondlength; drawscale(_ctx,radius);//绘制刻度 _ctx.beginpath(); _ctx.moveto(0, 0); _ctx.lineto(secondx, secondy); _ctx.linewidth = 1; _ctx.strokestyle = "red"; // 设置颜色 _ctx.stroke(); // 绘制中央圆点 _ctx.beginpath(); _ctx.arc(0, 0, 5, 0, 2 * math.pi); _ctx.fillstyle = "#333"; // 设置颜色 _ctx.fill(); } // 循环绘制 settimeout(drawclock, 1000); }
上面的代码非常详细的给出了时钟的展示过程,下面将绘制的步骤进行了简单的介绍。
首先获取canvas对象,并且清空画布,因为时钟每隔一秒即变化,同时分针秒针都要发生不断地变化,这些就像橡皮擦一样,要不断擦除和不断重新绘制。
然后在表盘中绘制具体是什么时间,比如北京时间,绘制后如下图所示:
接下来就是绘制时钟的数字刻度,比如1到12这几个数字,如下图所示:
//绘制刻度 function drawclocknumber(_ctx,radius){ for (let i = 1; i <= 12; i++) { var angle = i * math.pi / 6; _ctx.rotate(angle); _ctx.translate(0, -radius + 15); _ctx.rotate(-angle); _ctx.filltext(i.tostring(), 0, 0); _ctx.rotate(angle); _ctx.translate(0, radius - 15); _ctx.rotate(-angle) } }
绘制刻度的具体代码:
// 绘制刻度 function drawscale(_ctx,radius){ // 假设最大刻度线长度是半径的5% const maxmajorticklength = radius * 0.05; // 较大刻度线长度 const maxminorticklength = radius * 0.025; // 较小刻度线长度 for (let m = 0; m < 60; m++) { // 计算每个刻度的角度 const minuteangle = m * math.pi / 30; // 根据分钟数决定刻度线的长度 let ticklength; if (m % 5 === 0) { // 如果是每5分钟的刻度,使用较大刻度线长度 ticklength = maxmajorticklength; } else { // 否则使用较小刻度线长度 ticklength = maxminorticklength; } // 计算刻度线端点的坐标 var x1 = math.sin(minuteangle) * radius; // 圆边缘的x坐标 var y1 = -math.cos(minuteangle) * radius; // 圆边缘的y坐标 var x2 = math.sin(minuteangle) * (radius - ticklength); // 刻度线端点的x坐标 var y2 = -math.cos(minuteangle) * (radius - ticklength); // 刻度线端点的y坐标 // 绘制刻度线 _ctx.beginpath(); _ctx.moveto(x1, y1); // 从圆边缘开始 _ctx.lineto(x2, y2); // 向内延伸到刻度线端点 _ctx.stroke(); } }
在绘制刻度的这里,我刚开始一直没成功,主要原因是没掌握方法,刻度的两个起始点没绘制准确,因此导致了刻度绘制一直不准确,请记得一定计算好位置,尤其是使用moveto和lineto两个方法类调整,主要刻度从圆边缘开始,而不要movoto(0,0),这样从圆心开始,绘制出来的效果就不对了。
由于这6个城市分别属于6个不同的时区,因此也就造成了这6个城市的时间是不一样的,也就是我们常说的时差,通过查找资料可以知道,这里每个城市的时差大约是如下代码表示的。
function gethour(index,bjhour){ var hour = bjhour; // bjhour是北京时间的小时数 var offset; // 定义时区偏移量 // 根据时区索引计算偏移量 switch(index) { case 0: // 纽约 (北京时间比纽约快13小时) offset = -13; break; case 1: // 伦敦 (北京时间比伦敦快8小时) offset = -8; break; case 2: // 巴黎 (北京时间比巴黎快7小时) offset = -7; break; case 3: // 莫斯科 (北京时间比莫斯科快5小时) offset = -5; break; case 4: // 北京 (默认为北京时间) offset = 0; break; case 5: // 东京 (假设北京时间比东京慢1小时) offset = 1; break; default: // 如果索引不在预期范围内,返回原始小时数 return hour; } // 应用时区偏移量,并确保小时数在0到23之间 hour += offset; hour = (hour + 24) % 24; // 循环处理,确保结果在24小时制内 return hour; }
这里通过计算偏移量的方式来计算城市的时间,刚开始没有注意,这样计算出来的结果,会有不准确,因此才采用了时区偏移的处理方式,这样出来能保证每个时钟都是24小时之内。当然,为了计算方便,您也可以直接使用我上面的转换逻,是可以直接使用的。
经过上面的代码,就可以实现时钟的动态展示。效果如下所示:
总结
以上就是本文的主要内容,本文以canvas为基础,支持多时区的多时钟的动态web展示为例实现一种在html5上的电子钟展示方法,首先介绍canvas是什么,然后具体介绍如何进行时钟的绘制,其次介绍时钟的多时区支持,最后给出运行的实际效果。通过本文可以了解canvas的详细用法,掌握基本的文本绘制、样式控制、属性管理的基本知识,通过多时钟的展示场景,将各个知识点融会贯通。如果您想了解canvas的使用方法,可以来这里看看。行文仓促,定有诸多不足之处,欢迎各位专家朋友有什么疑问的也可以在评论区留言交流。
为方便朋友们学习,源码已经上传至资源,大家可以下载:。
到此这篇关于基于canvas的html5多时区动态时钟实战的文章就介绍到这了,更多相关html5 canvas时钟内容请搜索代码网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持代码网!
发表评论