当前位置: 首页 > 文档资料 > HTML5 Canvas 实战 >

5.8 动画时钟

优质
小牛编辑
134浏览
2023-12-01

有一些人,在超酷项目的开发中,常常精神恍惚,好像时间消失得无影无踪。如果你也是这样,这道菜就是为你而做。本节,我们将创建一个漂亮的动画时钟,来提醒人们走出虚拟世界,回到现实世界。

创建走到的时钟
图5-8 创建走到的时钟

操作步骤

按照以下步骤,创建一个带有时针、分针、秒针的动画时钟:

1. 链接到Animation类:

<head>
<script src="animation.js"> </script>

2. 实例化Animation对象,得到画布上下文,并定义时钟的半径:

<script>
window.onload = function(){
  var anim  = new Animation("myCanvas");
  var canvas  = anim.getCanvas(); 
  var context = anim.getContext(); 
  var clockRadius  =  75;

3. 设置stage()函数,用于获取当前时间,计算时针、分针、秒针的角度,清除画布,再绘制时钟:

  anim.setStage(function(){
  // update
  var date  = new Date();
  var hours  = date.getHours();
  var minutes  = date.getMinutes();
  var seconds  = date.getSeconds();
  hours  = hours  >  12  ? hours  -  12  : hours;
  var hour  = hours  + minutes  /  60;
  var minute  = minutes  + seconds  /  60;
  // clear
  this.clear();
  // draw
  var context  = anim.getContext(); 
  context.save();
  context.translate(canvas.width  /  2, canvas.height  /  2);
  // 绘制时钟体
  context.beginPath();
  context.arc(0,  0, clockRadius,  0, Math.PI  *  2,  true);
  var grd  = context.createLinearGradient(-clockRadius,  -clockRadius, clockRadius, clockRadius);
  grd.addColorStop(0, "#F8FCFF");  // light blue 
  grd.addColorStop(1, "#A1CCEE");  // dark blue 
  context.fillStyle  = grd;
  context.fill();
  //绘制数字
  context.font  = "16pt Calibri";
  context.fillStyle  = "#024F8C";
  context.textAlign  = "center";
  context.textBaseline  = "middle";
  for  (var n  =  1; n  <=  12; n++)  {
    var theta  =  (n  -  3)  *  (Math.PI  *  2)  /  12;
    var x  = clockRadius  *  0.8  * Math.cos(theta);
    var y  = clockRadius  *  0.8  * Math.sin(theta); 
    context.fillText(n, x, y);
  }
  context.save();
  // 应用阴影
  context.shadowColor  = "#bbbbbb"; 
  context.shadowBlur  =  5;
  context.shadowOffsetX  =  1;
  context.shadowOffsetY  =  1;
  // 绘制时钟边框
  context.lineWidth  =  3;
  context.strokeStyle  = "#005EA8"; 
  context.stroke();
  context.restore();
  // 绘制时针
  context.save();
  var theta  =  (hour  -  3)  *  2  * Math.PI  /  12; 
  context.rotate(theta);
  context.beginPath();
  context.moveTo(-10,  -4);
  context.lineTo(-10,  4);
  context.lineTo(clockRadius  *  0.6,  1); 
  context.lineTo(clockRadius  *  0.6,  -1); 
  context.fill();
  context.restore();
  //绘制分针
  context.save();
  var theta  =  (minute  -  15)  *  2  * Math.PI  /  60;
  context.rotate(theta);
  context.beginPath(); 
  context.moveTo(-10,  -3);
  context.lineTo(-10,  3);
  context.lineTo(clockRadius  *  0.9,  1); 
  context.lineTo(clockRadius  *  0.9,  -1);
  context.fill();
  context.restore();
  //绘制秒针
  context.save();
  var theta  =  (seconds  -  15)  *  2  * Math.PI  /  60; 
  context.rotate(theta);
  context.beginPath();
  context.moveTo(-10,  -2);
  context.lineTo(-10,  2);
  context.lineTo(clockRadius  *  0.8,  1); 
  context.lineTo(clockRadius  *  0.8,  -1); 
  context.fillStyle  = "red";
  context.fill();
  context.restore();
  context.restore();
  });

4. 启动动画:

  anim.start();
};
</script>
</head>

5. 在HTML文档的body部分嵌入canvas标签:

<body>
<canvas id="myCanvas" width="600" height="250" style="border:1px solid black;">
</canvas>
</body>

工作原理

页面加载完成后,我们可以实例化一个Animation对象,并得到画布及其上下文对象。接下来,我们定义stage()函数,该函数负责更新时钟,清除画布,然后,为每个动画循环绘制时钟。

在代码的更新部分,我们实例化一个Date对象,并获取时、分、秒。接下来,调整时和分来表示一个12小时制(AM和PM)的时间。

清除画布后,我们开始绘制时钟:

  • 调用translate()方法把画布上下文平移的到画布的中央
  • 调用arc()方法绘制时钟体
  • 创建一个循环,并调用fillText()方法绘制时钟边缘的数字
  • 使用shadowOffsetX和shadowOffsetY属性为时钟应用下拉背景
  • 调用stroke()方法绘制时钟边框
  • 绘制时钟的每一个针。绘制时,先旋转画布上下文,再绘制一个窄梯形,其粗的一端位于时钟的中心

最后,stage()被设置完成后,我们就可以调用start()方法启动动画了。

相关参考

  • 第1章 处理文本
  • 第2章 绘制圆
  • 第2章 使用自定义图形和填充样式