HTML Canvas - 画布时钟


画布时钟主要用于为网站添加时钟功能。当今大多数可用的网站都使用 Canvas 元素在其网站上实现基于时间的应用程序,因为它非常容易实现,并且 Canvas 可以制作良好的客户端动画。

我们将在本章中构建一个实时模拟时钟。让我们绘制一个带有圆圈的基本画布,以便我们可以使用 JavaScript 制作一个模拟时钟。代码如下。

<!DOCTYPE html>
<html lang="en">
   <head>
      <title>canvas clock</title>
   </head>
   <body onload="clock();">
      <canvas id="canvas" width="400" height="400" style="border: 10px solid black;background-color: burlywood;"></canvas>
      <script>
         var canvas = document.getElementById("canvas");
         var context = canvas.getContext("2d");
         var radius = canvas.height / 2;
         context.translate(radius, radius);
         radius = radius * 0.90;
         Clock();

         function Clock() {
            context.arc(0, 0, radius, 0, 2 * Math.PI);
            context.lineWidth = 15;
            context.strokeStyle = "black";
            context.stroke();
            context.fillStyle = "#dddddd";
            context.fill();
         }
      </script>
   </body>
</html>

这将画布的主体返回为

帆布时钟

将脸部添加到画布

我们必须先画一个画布,然后在画布内使用圆弧画圆,我们可以在其中实现时钟。为了画圆,我们必须确保画布的中心是圆的中心点,这有助于我们使它看起来更好。以下代码绘制 Canvas 元素并在其中实现钟面。

<!DOCTYPE html>
<html lang="en">
   <head>
      <title>canvas clock</title>
   </head>
   <body onload="clock();">
      <canvas id="canvas" width="400" height="400" style="border: 10px;"></canvas>
      <script>
         var canvas = document.getElementById("canvas");
         var context = canvas.getContext("2d");
         var radius = canvas.height / 2;
         context.translate(radius, radius);
         radius = radius * 0.90
         Clock();

         function Clock() {
            Face(context, radius);
         }

         function Face(context, radius) {
            var gradient;
            context.beginPath();
            context.arc(0, 0, radius, 0, 2 * Math.PI);
            context.fillStyle = 'white';
            context.fill();
            gradient = context.createRadialGradient(0, 0, radius * 0.95, 0, 0, radius * 1.05);
            gradient.addColorStop(0, '#555555');
            gradient.addColorStop(0.5, 'lightblue');
            gradient.addColorStop(1, '#555555');
            context.strokeStyle = gradient;
            context.lineWidth = 25;
            context.stroke();
            context.closePath();
            context.beginPath();
            context.arc(0, 0, radius * 0.1, 0, 2 * Math.PI);
            context.fillStyle = '#555555';
            context.fill();
            context.closePath()
         }
      </script>
   </body>
</html>

代码返回的输出是

将面添加到画布

添加数字和手

每个时钟都需要数字和指针来识别时间。因此,我们将对称地对时钟区域进行编号并绘制指针,就像我们在真正的机械时钟中常见的那样。下面给出实现代码。

<!DOCTYPE html>
<html lang="en">
   <head>
      <title>canvas clock</title>
   </head>
   <body onload="clock();">
      <canvas id="canvas" width="400" height="400" style="border: 10px;"></canvas>
      <script>
         var canvas = document.getElementById("canvas");
         var context = canvas.getContext("2d");
         var radius = canvas.height / 2;
         context.translate(radius, radius);
         radius = radius * 0.90;
         Clock();

         function Clock() {
            Face(context, radius);
            Numbers(context, radius);
            Time(context, radius);
         }

         function Face(context, radius) {
            var gradient;
            context.beginPath();
            context.arc(0, 0, radius, 0, 2 * Math.PI);
            context.fillStyle = 'white';
            context.fill();
            gradient = context.createRadialGradient(0, 0, radius * 0.95, 0, 0, radius * 1.05);
            gradient.addColorStop(0, '#555555');
            gradient.addColorStop(0.5, 'lightblue');
            gradient.addColorStop(1, '#555555');
            context.strokeStyle = gradient;
            context.lineWidth = 20;
            context.stroke();
            context.closePath();
            context.beginPath();
            context.arc(0, 0, radius * 0.1, 0, 2 * Math.PI);
            context.fillStyle = '#555555';
            context.fill();
            context.closePath()
         }

         function Numbers(context, radius) {
            var angle;
            var number;
            context.font = radius * 0.15 + "px Verdana";
            context.textBaseline = "middle";
            context.textAlign = "center";
            for (number = 1; number < 13; number++) {
               angle = number * Math.PI / 6;
               context.rotate(angle);
               context.translate(0, -radius * 0.85);
               context.rotate(-angle);
               context.fillText(number.toString(), 0, 0);
               context.rotate(angle);
               context.translate(0, radius * 0.85);
               context.rotate(-angle);
            }
         }

         function Time(context, radius) {
            var Present_Time = new Date();
            var hours = Present_Time.getHours();
            var minutes = Present_Time.getMinutes();
            var seconds = Present_Time.getSeconds();
            hours = hours % 12;
            hours = (hours * Math.PI / 6) + (minutes * Math.PI / (6 * 60)) + (seconds * Math.PI / (360 * 60));
            Hands(context, hours, radius * 0.5, radius * 0.07);
            minutes = (minutes * Math.PI / 30) + (seconds * Math.PI / (30 * 60));
            Hands(context, minutes, radius * 0.8, radius * 0.07);
            seconds = (seconds * Math.PI / 30);
            Hands(context, seconds, radius * 0.9, radius * 0.02);
         }

         function Hands(context, pos, length, width) {
            context.beginPath();
            context.lineWidth = width;
            context.lineCap = "round";
            context.moveTo(0, 0);
            context.rotate(pos);
            context.lineTo(0, -length);
            context.stroke();
            context.rotate(-pos);
            context.closePath();
         }
      </script>
   </body>
</html>

上述代码将数字和指针相加后生成的时钟为

添加数字和手

开始计时

到目前为止,我们已经使用 Canvas 元素构建了一个功能正常的模拟时钟,但除非我们每次刷新 HTML 页面,否则它不会自动运行。因此,我们将添加另一个函数来使时钟自主,这样我们就可以用它来识别时间而不会出现任何错误。

这使得时钟自动化并且无需任何时间更新即可工作。下面给出了实现的代码。

<!DOCTYPE html>
<html lang="en">
   <head>
      <title>canvas clock</title>
   </head>
   <body onload="clock();">
      <canvas id="canvas" width="400" height="400" style="border: 10px;"></canvas>
      <script>
         var canvas = document.getElementById("canvas");
         var context = canvas.getContext("2d");
         var radius = canvas.height / 2;
         context.translate(radius, radius);
         radius = radius * 0.90;
         setInterval(Clock, 1000);

         function Clock() {
            Face(context, radius);
            Numbers(context, radius);
            Time(context, radius);
         }

         function Face(context, radius) {
            var gradient;
            context.beginPath();
            context.arc(0, 0, radius, 0, 2 * Math.PI);
            context.fillStyle = 'white';
            context.fill();
            gradient = context.createRadialGradient(0, 0, radius * 0.95, 0, 0, radius * 1.05);
            gradient.addColorStop(0, '#555555');
            gradient.addColorStop(0.5, 'lightblue');
            gradient.addColorStop(1, '#555555');
            context.strokeStyle = gradient;
            context.lineWidth = 20;
            context.stroke();
            context.closePath();
            context.beginPath();
            context.arc(0, 0, radius * 0.1, 0, 2 * Math.PI);
            context.fillStyle = '#555555';
            context.fill();
            context.closePath()
         }

         function Numbers(context, radius) {
            var angle;
            var number;
            context.font = radius * 0.15 + "px Verdana";
            context.textBaseline = "middle";
            context.textAlign = "center";
            for (number = 1; number < 13; number++) {
               angle = number * Math.PI / 6;
               context.rotate(angle);
               context.translate(0, -radius * 0.85);
               context.rotate(-angle);
               context.fillText(number.toString(), 0, 0);
               context.rotate(angle);
               context.translate(0, radius * 0.85);
               context.rotate(-angle);
            }
         }

         function Time(context, radius) {
            var Present_Time = new Date();
            var hours = Present_Time.getHours();
            var minutes = Present_Time.getMinutes();
            var seconds = Present_Time.getSeconds();
            hours = hours % 12;
            hours = (hours * Math.PI / 6) + (minutes * Math.PI / (6 * 60)) + (seconds * Math.PI / (360 * 60));
            Hands(context, hours, radius * 0.5, radius * 0.07);
            minutes = (minutes * Math.PI / 30) + (seconds * Math.PI / (30 * 60));
            Hands(context, minutes, radius * 0.8, radius * 0.07);
            seconds = (seconds * Math.PI / 30);
            Hands(context, seconds, radius * 0.9, radius * 0.02);
         }

         function Hands(context, pos, length, width) {
            context.beginPath();
            context.lineWidth = width;
            context.lineCap = "round";
            context.moveTo(0, 0);
            context.rotate(pos);
            context.lineTo(0, -length);
            context.stroke();
            context.rotate(-pos);
            context.closePath();
         }
      </script>
   </body>
</html>

输出

上述代码生成的自动模拟时钟是

启动时钟