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函数控制每一秒钟执行一次绘制时钟的函数。

  • 相关阅读:
    软件工程概论总结第三章
    软件工程概论总结第二章
    软件工程概论总结
    软件工程概论10-软件测试
    软件工程概论9-软件实现
    软件工程概论-8面向对象设计
    软件工程概论-7面向对象分析
    软件工程概论-6面向对象基础
    软件工程概论-5软件工程中的形式化方法
    软件工程概论-4需求过程
  • 原文地址:https://www.cnblogs.com/Joe-and-Joan/p/10218564.html
Copyright © 2011-2022 走看看