模拟时钟的canvas API模拟

问题描述 投票:0回答:1

我尝试在 Canvas API 中创建模拟时钟的模拟。我不想使用时间对象,因为我的时钟不会告诉实际时间。时钟应该有三个指针(秒、分和小时)。装入文档后,指针应指向 9.00,然后指针将开始移动。 我画了一个钟身和指针。显示第二个的手按照我的意愿转动。但是,我不知道如何移动显示分钟和小时的指针。我尝试使用变量“计数器”来计算循环次数,每当计数器能被 60 整除时,就会移动显示 6 度角分钟的指针。我想将相同的逻辑应用于显示小时的指针(当计数器可被 3600 整除时,将指针移动 30 度角)。有人可以帮助我或提示我如何实现它吗?

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Analog Clock</title>
    <style>
        #my-canvas {
            border: 1px solid black;
        }
    </style>
</head>
<body>
    <canvas id="my-canvas" width="400" height="300">
        Your web browser does not support canvas.
    </canvas>
    <script>
        window.onload = draw;
                function draw() {
                    let myCanvas = document.getElementById('my-canvas');

                    if(myCanvas.getContext) {
                        let ctx = myCanvas.getContext('2d');
                        // set interval to one second
                        setInterval(function() {
                            update(ctx);
                        }, 1000);
                    } else {
                        alert('Canvas is not supported.')
                    }
                }
                // set the counter
                let ct = 0;
                
                // set angles for clock hands
                let angleS = 6;
                let angleM = 6;
                let angleH = 30;

                // update function
                function update(ctx) {
                    ctx.clearRect(0, 0, 400, 300);
                    ctx.save();

                    showClock(ctx);
                    showHands(ctx);
                    
                    ctx.restore()
                }
                
                // show the clock 
                function showClock(ctx) {

                    // draw circle - body of the clock 
                    ctx.beginPath();
                    ctx.arc(120, 120, 120, 0, 2 * Math.PI);
                    ctx.closePath();
                    ctx.strokeStyle = 'black';
                    ctx.lineWidth = 2;
                    ctx.stroke();
                    
                    // show clock "brand"
                    ctx.font = "18px Arial";
                    ctx.fillText('Timex', 98, 75);
                    
                    // show numbers 12, 3, 6 i 9
                    ctx.font = "43px serif";
                    ctx.fillText("12", 100, 40);
                    ctx.fillText("3", 215, 135);
                    ctx.fillText("6", 110, 235);
                    ctx.fillText("9", 5, 135);

                    // draw the center of the clock
                    ctx.beginPath();
                    ctx.arc(120,120, 10, 0, 2 * Math.PI);
                    ctx.closePath();
                    ctx.fillStyle = "black";
                    ctx.fill();
                    ctx.stroke();
                    
                }

                // show hands
                function showHands(ctx) {
                    ct += 1;
                    console.log(ct);

                    // draw hand for seconds
                    ctx.translate(120, 120);
                    ctx.rotate((Math.PI/180) * angleS);
                    ctx.translate(-120, -120); 

                    ctx.beginPath();
                    ctx.moveTo(120, 120);
                    ctx.strokeStyle = 'red';
                    ctx.lineTo(120, 10);
                    ctx.stroke();

                    // increase angle for 6 degrees 
                    angleS +=6;

                    if (ct < 60) {
                        // draw hands for minutes
                        ctx.restore();
                        ctx.beginPath();
                        ctx.moveTo(120, 120);
                        ctx.lineWidth = 5;
                        ctx.strokeStyle = 'black';
                        ctx.lineCap = 'round';
                        ctx.lineTo(120, 30);
                        ctx.stroke();
                    }

                    if (ct%60==0) {
                        
                        ctx.translate(120, 120);
                        ctx.rotate((Math.PI/180) * angleM);
                        ctx.translate(-120, -120); 
                        ctx.restore();

                        ctx.beginPath();
                        ctx.moveTo(120, 120);
                        ctx.lineWidth = 5;
                        ctx.strokeStyle = 'black';
                        ctx.lineCap = 'round';
                        ctx.lineTo(120, 30);
                        ctx.stroke();
                        ctx.restore();
                        // increase angle for minutes
                        angleM +=6;

                    } 
                        
                    
                    
                    

                        
                        

                    

                
                    // draw hands for hours
                    ctx.restore();
                    ctx.beginPath();
                    ctx.moveTo(120, 120);
                    
                    ctx.lineWidth = 9;
                    ctx.strokeStyle = 'black';
                    ctx.lineCap = 'round';
                    ctx.lineTo(45,120);
                    ctx.stroke();   
                }
    </script>
</body>
</html>

javascript html css animation canvas
1个回答
0
投票

本质上有两个问题:

  1. Canvas API 方法:
    save()
    restore()
    未正确使用。
  2. 我应该遵循单一职责原则。 If 语句对于改变手的角度是必需的,但对于绘制手则不需要。

最后,我不需要条件

if (ct  % 3600==0)
,因为显示时间的指针每分钟逐渐移动0.5度(不是60分钟过去时立即移动30度)。

现在,模拟时钟可以正常工作了。它从 09:00 开始,只要脚本在浏览器中打开,就会继续。

<!DOCTYPE html>
<html lang='en'>
<head>
  <meta charset='UTF-8'>
  <meta name='viewport' content='width=device-width, initial-scale=1.0'>
  <title>Analog Clock - simulation</title>
  <style>
    #my-canvas {
      border: 1px solid black;
    }
  </style>
</head>
<body>
  <canvas id='my-canvas' width='400' height='300'>
    Your web browser does not support canvas.
  </canvas>
  <script>
    // set the counter variable
    let ct = 0;
    
    // set the angles of the clock hands
    let angleS = 0;
    let angleM = 0;
    let angleH = 0;
    
    window.onload = draw;
    
    function draw() {
      let myCanvas = document.getElementById('my-canvas');
      
      if (myCanvas.getContext) {
        let ctx = myCanvas.getContext('2d');
        
        showClock(ctx);
        showHands(ctx);
        
         // set interval to one second
         setInterval(function() { 
           update(ctx); 
         }, 1000);
       } else {
          alert('Canvas is not supported');
       }
    }
    
    // update function: clock mechanics and drawing
    function update(ctx) {
      // increase anlge for 6 degrees and counter for 1
      angleS += 6;
      ct += 1;
      
      if (ct % 60 == 0) {
        angleM += 6;
        angleH += 0.5;
      }
      
      ctx.clearRect(0, 0, 400, 300);
      showClock(ctx);
      showHands(ctx);
    }
    
    // draw hand for hours
    function drawHourHand(ctx) {
      ctx.save();
      
      ctx.translate(120, 120);
      ctx.rotate((Math.PI/180)* angleH);
      ctx.translate(-120, -120);
      
      ctx.beginPath();
      ctx.moveTo(120, 120);
      ctx.lineWidth = 9;
      ctx.strokeStyle = 'black';
      ctx.lineCap = 'round';
      ctx.lineTo(45, 120);
      ctx.stroke();
      
      ctx.restore();
    }
    
    //draw hand for minutes
    function drawMinuteHand(ctx) {
      ctx.save();
      
      ctx.translate(120, 120);
      ctx.rotate((Math.PI/180)* angleM);
      ctx.translate(-120, -120);
      
      ctx.beginPath();
      ctx.moveTo(120, 120);
      ctx.lineWidth = 5;
      ctx.strokeStyle = 'black';
      ctx.lineCap = 'round';
      ctx.lineTo(120, 30);
      ctx.stroke();
      
      ctx.restore();
    }
    
    // draw hand for seconds
    function drawSecondHand(ctx) {
      ctx.save();
      
      ctx.translate(120, 120);
      ctx.rotate((Math.PI/180)* angleS);
      ctx.translate(-120, -120);
      
      ctx.beginPath();
      ctx.moveTo(120, 120);
      ctx.strokeStyle = 'red';
      ctx.lineTo(120, 10);
      ctx.stroke();
      
      ctx.restore();
    }
    
    // draw the clock body
    function showClock(ctx) {
      ctx.save();
      
      ctx.beginPath();
      ctx.arc(120, 120, 120, 0, 2*Math.PI);
      ctx.closePath();
      ctx.strokeStyle = 'black';
      ctx.lineWidth = 2;
      ctx.stroke();
      
      ctx.font = '18px Arial';
      ctx.fillText('Timex', 98, 75);
      
      ctx.font = '43px serif';
      ctx.fillText('12', 100, 40);
      ctx.fillText('3', 215, 135);
      ctx.fillText('6', 110, 235);
      ctx.fillText('9', 5, 135);
      
      // drae the center of the clock
      ctx.beginPath();
      ctx.arc(120, 120, 10, 0, 2*Math.PI);
      ctx.closePath();
      ctx.fillStyle = 'black';
      ctx.fill();
      ctx.stroke();
      
      ctx.restore();
    }
    
    // show hands
    function showHands(ctx) {
      drawHourHand(ctx);
      drawMinuteHand(ctx);
      drawSecondHand(ctx);
    }
  </script>
</body>
</html>

© www.soinside.com 2019 - 2024. All rights reserved.