zoukankan      html  css  js  c++  java
  • 小任务之Canvas绘制时钟

    背景图的绘制(大圆、数字、小圆点)

    掌握基础知识:圆的绘制(arc方法),关于圆的弧度的计算,数学中关于sin cos的用法

    圆的弧度为2*Math.PI

    12个数字分得弧度每个为2*Math.PI/12

    那么rad=i*2*Math.PI/12

    x=Math.cos(rad)*所需要的长度(也就是半径-差值)

    y=Math.sin(rad)*所需要的长度(也就是半径-差值)

    同理可得60个点的绘制

    60个数字分得弧度每个rad=i*2*Math.PI/60

    x=Math.cos(rad)*所需要的长度(也就是半径-差值)

    y=Math.sin(rad)*所需要的长度(也就是半径-差值)

      1 <!DOCTYPE html>
      2 <html>
      3 
      4 <head>
      5     <meta charset="utf-8" />
      6 
      7     <title>canvas练习</title>
      8 
      9 </head>
     10 
     11 <body>
     12     <canvas id="prac" width="500" height="500" style="border:1px solid black"></canvas>
     13     <canvas id="clock" width="500" height="500" style="border:1px solid black"></canvas>
     14     <script>
     15         var prac = document.querySelector("#prac");
     16         var test = prac.getContext("2d");
     17         test.moveTo(20, 25); //起点,但是绘制
     18         test.lineTo(200, 25); //终点
     19         test.stroke(); //绘制路径
     20 
     21         test.beginPath();
     22         test.lineWidth = "10";
     23         test.rect(200, 200, 50, 50);
     24         test.stroke();
     25 
     26         test.beginPath();
     27         test.rect(260, 200, 50, 50);
     28         test.fill();
     29 
     30         test.fillStyle = "rgb(200,0,0)";
     31         test.lineWidth = "10"; //带填充的,画线粗细无作用
     32         test.fillRect(100, 100, 55, 50); //带填充的矩形
     33 
     34         test.strokeStyle = "blue";
     35         test.lineWidth = "1";
     36         test.strokeRect(85, 85, 100, 150); //不带填充的矩形
     37 
     38         test.beginPath();
     39         test.arc(100, 295, 15, 0, 2 * Math.PI); //圆心坐标+半径+起始角和结束角;
     40         test.stroke();
     41 
     42         test.beginPath();
     43         test.arc(150, 295, 15, 0, 2 * Math.PI); //圆心坐标+半径+起始角和结束角;
     44         test.fill();
     45 
     46         test.font = "20px Arial";
     47         test.textAlign = "center";
     48         test.fillText("Hello World", 400, 200);
     49         test.textAlign = "center";
     50         test.textBaseline = "hanging";
     51         test.fillText("Hello World", 400, 200);
     52 
     53         //以下为时钟部分
     54         var clock = document.getElementById("clock");
     55         var ctx = clock.getContext("2d");
     56         var width = clock.width;
     57         var height = clock.height;
     58         var radius = width / 2; //半径
     59         var rem = width / 200; //画面比例
     60 
     61         function drawBG() {
     62             ctx.save(); //保存当前环境
     63             ctx.translate(width / 2, height / 2);//转换原点为中心
     64             ctx.beginPath();
     65             ctx.lineWidth = 8 * rem;
     66             //以0,0为原点,r为半径,0为起始角,2*Math.PI为结束角,顺时针画圆
     67             ctx.arc(0, 0, radius - ctx.lineWidth / 2, 0, 2 * Math.PI, false);
     68             ctx.closePath();
     69             ctx.stroke();
     70 
     71             var hourNumber = [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2];
     72             //画出1-12的数字
     73             hourNumber.forEach(function (number, i) {
     74                 var rad = 2 * Math.PI / 12 * i;
     75                 var x = Math.cos(rad) * (radius - 35 * rem);
     76                 var y = Math.sin(rad) * (radius - 35 * rem);
     77                 ctx.font = 20 * rem + "px Arial"; //拼接字符串
     78                 ctx.textAlign = "center";
     79                 ctx.textBaseline = "middle";
     80                 ctx.fillText(number, x, y);
     81             })
     82             //画出秒针走动的60个点
     83             for (let i = 0; i < 60; i++) {
     84                 var rad = 2 * Math.PI / 60 * i;
     85                 var x = Math.cos(rad) * (radius - 18 * rem);
     86                 var y = Math.sin(rad) * (radius - 18 * rem);
     87                 ctx.beginPath();
     88                 if (i % 5 === 0) {
     89                     ctx.fillStyle = "#000";
     90                     ctx.arc(x, y, 3 * rem, 0, 2 * Math.PI);
     91                 } else {
     92                     ctx.fillStyle = "#ccc";
     93                     ctx.arc(x, y, 3 * rem, 0, 2 * Math.PI);
     94                 }
     95                 ctx.fill();
     96             }
     97 
     98 
     99         }
    100         //绘制时针
    101         function drawHour(hour, minute) {
    102             ctx.save();
    103             ctx.beginPath();
    104             var rad = 2 * Math.PI / 12 * hour;
    105             var mrad = 2 * Math.PI / 12 / 60 * minute; //分60等份弧度         
    106             ctx.rotate(rad + mrad); //时针特殊性+上对应每分钟占的时钟刻度
    107             ctx.moveTo(0, 10 * rem);
    108             ctx.lineWidth = 6 * rem;
    109             ctx.lineCap = "round";
    110             ctx.lineTo(0, -radius / 2);
    111             ctx.stroke();
    112             ctx.restore();
    113         }
    114         //绘制分针
    115         function drawMinute(minute) {
    116             ctx.save();
    117             ctx.beginPath();
    118             var rad = 2 * Math.PI / 60 * minute;
    119             ctx.rotate(rad);
    120             ctx.moveTo(0, 10 * rem);
    121             ctx.lineWidth = 3 * rem;
    122             ctx.lineCap = "round";
    123             ctx.lineTo(0, -radius + 45 * rem);
    124             ctx.stroke();
    125             ctx.restore();
    126         }
    127         //绘制秒针
    128         function drawSecond(second) {
    129             ctx.save();
    130             ctx.beginPath();
    131             var rad = 2 * Math.PI / 60 * second;
    132             ctx.rotate(rad);
    133             ctx.moveTo(-2 * rem, 20 * rem);
    134             ctx.lineTo(2 * rem, 20 * rem);
    135             ctx.lineTo(1 * rem, -radius + 18 * rem);
    136             ctx.lineTo(-1 * rem, -radius + 18 * rem);
    137             ctx.fillStyle = "red";
    138             ctx.fill();
    139             ctx.restore();
    140         }
    141         //画时钟上的中心白色原点
    142         function drawDot() {
    143             ctx.beginPath();
    144             ctx.arc(0, 0, 2 * rem, 0, 2 * Math.PI, false);
    145             ctx.fillStyle = "white";
    146             ctx.fill();
    147         }
    148 
    149         //绘制整体函数
    150         function draw() {
    151             ctx.clearRect(0, 0, width, height); //清空画布
    152             var now = new Date();//获取时间
    153             var hour = now.getHours();
    154             var minute = now.getMinutes();
    155             var second = now.getSeconds();
    156             console.log(hour, minute, second);
    157             drawBG();
    158             drawHour(hour, minute);
    159             drawMinute(minute);
    160             drawSecond(second);
    161             drawDot();
    162             ctx.restore(); //清除,起始坐标回到0,0
    163         }
    164         draw();//提前先画一次,避免空白
    165         setInterval(draw, 1000); //每秒执行一次
    166     </script>
    167 </body>
    168 
    169 </html>

    注意点:

    1.rem=width/200(基准值)

    所需要的像素换算=x*rem

    2.canvas的字体设置可以用拼接字符串来动态根据rem修改大小:

    ctx.font = 20 * rem + "px Arial"; //拼接字符串

    3.为了使文字填充为该坐标中心, 那么利用文字对齐方式调整至中心位置

    ctx.textAlign = "center";
    ctx.textBaseline = "middle";

    4.记得保存和重置,因为清除画布(不清除画布,画面会重叠)需要把坐标移动至左上角原始位置,所以本来我们画背景的时候将画布原点移致画布中心,所以要ctx.restore()

    5.moveTo和lineTo都是不绘制的,最后得stroke(),或者fill()

    6.由于时针的特殊性,所以要加上分钟走过的弧度来确定指针指向的位置

    var rad = 2 * Math.PI / 12 * hour;
    var mrad = 2 * Math.PI / 12 / 60 * minute; //分60等份弧度         
    ctx.rotate(rad + mrad); //时针特殊性+上对应每分钟占的时钟刻度

    7.时分秒针以及中心原点的绘制,其中时针和分针就是绘制一个直线即可,秒针则画一个梯形样式呈现又粗到细的效果,要掌握的基础知识:直线的绘制,旋转角度的控制(rotate以弧度为单位),时钟的动态走动效果,则用setInterval函数控制每一秒钟执行一次绘制时钟的函数。

  • 相关阅读:
    WPF 使用 Direct2D1 画图 绘制基本图形
    WPF 使用 Direct2D1 画图 绘制基本图形
    dot net core 使用 IPC 进程通信
    dot net core 使用 IPC 进程通信
    win2d 图片水印
    win2d 图片水印
    Java实现 LeetCode 240 搜索二维矩阵 II(二)
    PHP closedir() 函数
    PHP chroot() 函数
    PHP chdir() 函数
  • 原文地址:https://www.cnblogs.com/Joe-and-Joan/p/10218564.html
Copyright © 2011-2022 走看看