我正在使用HTML5的画布和javascript制作一个时钟动画.它应该有三只移动的手,但似乎只有两只手在渲染和工作(小时和分钟).我没有看到任何运行时错误阻止渲染第三个.第三只手怎么了?

Example Clock顺便说一句,这不是地球钟,所以数学可能看起来很奇怪.

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8" />
    <title>Wyrdling Clock</title>
</head>
<body onload="init();">
    <div style="position: relative;">
        <canvas id="clock_layer1" width="1080" height="1080" style="position: absolute; left: 0; top: 0; z-index: 0;"></canvas>
        <canvas id="clock_layer2" width="1080" height="1080" style="position: absolute; left: 0; top: 0; z-index: 1;"></canvas>
        <canvas id="clock_layer3" width="1080" height="1080" style="position: absolute; left: 0; top: 0; z-index: 2;"></canvas>
        <canvas id="clock_layer4" width="1080" height="1080" style="position: absolute; left: 0; top: 0; z-index: 3;"></canvas>
    </div>
</body>

<script>
    var clock_face = null,
        hour_hand = null,
        minute_hand = null,
        second_hand = null,
        cycle_hand = null,
        ctx_l1 = null,
        ctx_l2 = null,
        ctx_l3 = null,
        ctx_l4 = null,
        degrees = 0;
    var WyrdTimeStarts = new Date("2019-05-22");

    var HEIGHT = 1080;
    var WIDTH = 1080;
    var HALF_HEIGHT = HEIGHT / 2;
    var HALF_WIDTH = WIDTH / 2;
    var FPS = 15;

    var CIRCLE_TO_HOUR_RATIO = 360 / 9;
    var CIRCLE_TO_MINUTES_RATIO = 360 / 60;
    var CIRCLE_TO_SECOND_RATIO = 360 / 60;
    var CIRCLE_TO_CYCLE_RATIO = 360 / 3;
    var CIRCLE_TO_MS_RATIO = 360 / 60000;

    var DEGRESS_TO_RADIANS = Math.PI / 180;
    var RADIANS_TO_DEGREES = 180 / Math.PI;

    function fCleanCanvas() {
        // clear canvas
        ctx_l1.clearRect(0, 0, HEIGHT, WIDTH);
        ctx_l2.clearRect(0, 0, HEIGHT, WIDTH);
        ctx_l3.clearRect(0, 0, HEIGHT, WIDTH);
        ctx_l4.clearRect(0, 0, HEIGHT, WIDTH);
    } // End function fCleanCanvas

    function fMinuteAngle(currentMinutes) {
        // Calculate the expected angle
        return Math.floor(CIRCLE_TO_MINUTES_RATIO * currentMinutes, 0);
    } // End function fMinuteAngle

    function fHourAngle(currentHours) {
        // Calculate the expected angle
        return Math.floor(CIRCLE_TO_HOUR_RATIO * currentHours, 0);
    } // End function fHourAngle

    function fSecondAngle(currentTime) {
        // Calculate the expected angle
        var secondsToMilliseconds = currentTime.getSeconds() * 1000;
        var totalMilliseconds = currentTime.getMilliseconds() + secondsToMilliseconds;
        return Math.floor(CIRCLE_TO_MS_RATIO * totalMilliseconds, 0);
    } // End function fSecondAngle

    function fDayCycleAngle(currentHours) {
        // Calculate the expected angle
        return Math.floor(((360/3) * (currentHours/9)),0);
    } // End function fDayCycleAngle

    function fDrawAsRotatedInLayer(image, angle, x) {
        switch (x) {
            case 1:
                // Rotate around this point
                ctx_l1.rotate(angle * DEGRESS_TO_RADIANS);

                // Draw the image back and up
                ctx_l1.drawImage(image, 0 - HALF_HEIGHT, 0 - HALF_WIDTH);
    
                break;
            case 2:
                // Rotate around this point
                ctx_l2.rotate(angle * DEGRESS_TO_RADIANS);

                // Draw the image back and up
                ctx_l2.drawImage(image, 0 - HALF_HEIGHT, 0 - HALF_WIDTH);
    
                break;
            case 3:
                // Rotate around this point
                ctx_l3.rotate(angle * DEGRESS_TO_RADIANS);

                // Draw the image back and up
                ctx_l3.drawImage(image, 0 - HALF_HEIGHT, 0 - HALF_WIDTH);
    
                break;
            case 3:
                // Rotate around this point
                ctx_l4.rotate(angle * DEGRESS_TO_RADIANS);

                // Draw the image back and up
                ctx_l4.drawImage(image, 0 - HALF_HEIGHT, 0 - HALF_WIDTH);
    
                break;
            default:
                break;
        }
    } // End function fDrawAsRotatedInLayer

    function draw() {
        var currentTime = new Date();
        var today = new Date();
        var diffMs = (today - WyrdTimeStarts); // milliseconds in the Wyrd so far
        var diffDays = Math.floor(diffMs / 97200000); // Wyrd days
        var diffHrs = (diffMs % 97200000) / 3600000; // hours
        var diffMins = ((diffMs % 97200000) % 3600000) / 60000; // minutes

        fCleanCanvas();

        // Draw the clock background onto canvas layer 1
        ctx_l1.drawImage(clock_face_base, 0, 0);

        // Save canvas layer 1's drawing state
        ctx_l1.save();

        // Move to center point for rotation of hour hand
        ctx_l1.translate(HALF_HEIGHT, HALF_WIDTH);
        fDrawAsRotatedInLayer(hour_hand, fHourAngle(diffHrs), 1);

        // Restore canvas layer 1's previous drawing state
        ctx_l1.restore();



        // Draw the clock's middle layer onto canvas layer 2
        ctx_l2.drawImage(clock_face_mid, 0, 0);

        // Save canvas layer 2's drawing state
        ctx_l2.save();

        // Move to center point for rotation of minute hand
        ctx_l2.translate(HALF_HEIGHT, HALF_WIDTH);
        fDrawAsRotatedInLayer(minute_hand, fMinuteAngle(diffMins), 2);
        
        // Restore canvas layer 2's previous drawing state
        ctx_l2.restore();



        // Save canvas layer 3's drawing state
        ctx_l3.save();

        // Move to center point for rotation of day cycle (shows which 9 hour segment of the 27 hour day is it)
        ctx_l3.translate(HALF_HEIGHT, HALF_WIDTH);
        fDrawAsRotatedInLayer(cycle_hand, fDayCycleAngle(diffHrs), 3);

        // Restore canvas layer 3's previous drawing state
        ctx_l3.restore();



        // Draw the clock's cap onto canvas layer 4
        ctx_l4.drawImage(clock_face_top, 0, 0);

        // Save canvas layer 4's drawing state
        ctx_l4.save();

        // Move to center point for rotation of second hand
        ctx_l4.translate(HALF_HEIGHT, HALF_WIDTH);
        fDrawAsRotatedInLayer(second_hand, fSecondAngle(currentTime), 4);

        // Restore canvas layer 4's previous drawing state
        ctx_l4.restore();



        window.requestAnimationFrame(draw, 1000 / FPS);
        
    } // End function draw

    function imgLoaded() {
        // Image loaded event complete.  Start the timer
        window.requestAnimationFrame(draw, 1000 / FPS);
    } // End function imgLoaded

    function init() {
        // Grab the clock element
        var canvas1 = document.getElementById('clock_layer1');
        var canvas2 = document.getElementById('clock_layer2');
        var canvas3 = document.getElementById('clock_layer3');
        var canvas4 = document.getElementById('clock_layer4');
    
        // Canvas supported?
        if(canvas1.getContext('2d')) {
            ctx_l1 = canvas1.getContext('2d');
            ctx_l2 = canvas2.getContext('2d');
            ctx_l3 = canvas3.getContext('2d');
            ctx_l4 = canvas4.getContext('2d');
    
            // Load the hour hand image
            hour_hand = new Image();
            hour_hand.src = 'Wyrdling Clock - hand 1.png';
    
            // Load the minute hand image
            minute_hand = new Image();
            minute_hand.src = 'Wyrdling Clock - hand 2.png';
    
            // Load the cycle hand image
            cycle_hand = new Image();
            cycle_hand.src = 'Wyrdling Clock - hand 3.png';
    
            // Load the second hand image
            second_hand = new Image();
            second_hand.src = 'Wyrdling Clock - hand 4.png';
    
            // Load the clock face part 2 image
            clock_face_mid = new Image();
            clock_face_mid.src = 'Wyrdling Clock - face 2.png';

            // Load the clock face part 3 image
            clock_face_top = new Image();
            clock_face_top.src = 'Wyrdling Clock - face 3.png';

            // Load the clock face base image
            clock_face_base = new Image();
            clock_face_base.src = 'Wyrdling Clock - face 1.png';
            clock_face_base.onload = imgLoaded;

        } else {
            alert("Canvas not supported!");
        } // End if(canvas1.getContext('2d'))

    } // End function init

</script>
</html>

推荐答案

Once you see it, you are going to kick yourself for this.
Look at the switch in fDrawAsRotatedInLayer you have 2 times case 3:. It never enters the branch for the seconds handle

Javascript相关问答推荐

如何修复内容安全策略指令脚本-SRC自身错误?

react 路由加载程序行为

当在select中 Select 选项时,我必须禁用不匹配的 Select

如何使用侧边滚动按钮具体滚动每4个格?

使用续集和下拉栏显示模型属性

Javascript,部分重排序数组

如何修复我的js构建表每当我添加一个额外的列作为它的第一列?

在执行异步导入之前判断模块是否已导入()

JQuery Click事件不适用于动态创建的按钮

检索相加到点的子项

回溯替代方式

使用类型:assets资源 /资源&时,webpack的配置对象&无效

未捕获语法错误:Hello World中的令牌无效或意外

在查看网页时,如何使HTML中的按钮工作方式类似于鼠标上的滚轮或箭头键?

如何更改Html元素S的 colored颜色 ,然后将其褪色为原始 colored颜色

如何在下一个js中更改每个标记APEXCHARTS图表的 colored颜色

在单击按钮时生成多个表单时的处理状态

有角粘桌盒阴影

REACT-本机错误:错误类型错误:无法读取未定义的容器的属性

不允许在对象文本中注释掉的属性