Canvas 实现一个时钟

使用canvas实现另一个小时钟,效果图如下:

前端html代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        body {
            background: #dddddd;
        }

        #canvas {
            margin: 0 auto;
            padding: 10px;
            background:#ffffff;
            border: thin inset #aaaaaa;  
        }
    </style>
</head>
<body>
    <canvas id="canvas" width="400" height="400">
        Canvas not supported
    </canvas>
    <script src="./js/example.js"></script>
</body>
</html>

下面是example.js的具体实现:

var canvas = document.getElementById("canvas");
var context = canvas.getContext("2d");
 
var FONT_HEIGHT = 15;// 字体大小
var MARGIN = 35; // 边距
var HAND_TRUNCATION = canvas.width/12; // 分钟需要减去的半径
var HOUR_HAND_TRUNCATION = canvas.width/10;// 小时针需要减去的半径
var NUMBER_SPACING = 20; // 数字间距
var RADIUS = canvas.width/2 - MARGIN; // 半径
var HAND_RADIUS = RADIUS + NUMBER_SPACING; // 指针半径(数字间距)

// 绘制圆
function drawCircle(){
    context.beginPath();
    context.arc(canvas.width/2, canvas.height/2, RADIUS, 0, Math.PI*2, true);
    context.stroke();
}

// 绘制中心点
function drawCenter(){
    context.beginPath();
    context.arc(canvas.width/2, canvas.height/2, 5, 0, Math.PI*2, true);
    context.fill();
}


// 绘制数字
function drawNumbers(){
    var numberals = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];
    var angle = 0;
    var numeralWidth = 0;
    numberals.forEach(function(numeral){
        angle = Math.PI/6 * (numeral - 3);
        // 填充文字
        numeralWidth = context.measureText(numeral).width;
        context.fillText(numeral,
            canvas.width/2 + Math.cos(angle)*(HAND_RADIUS)
                - numeralWidth/2,
            canvas.height/2 + Math.sin(angle)*(HAND_RADIUS)
                + FONT_HEIGHT/3
        );
        // 绘制刻度 
        context.moveTo(canvas.width/2 + Math.cos(angle)*(RADIUS -5),
                    canvas.height/2 + Math.sin(angle)*(RADIUS -5));
        context.lineTo(canvas.width/2 + Math.cos(angle)*(RADIUS),
                canvas.height/2 + Math.sin(angle)*(RADIUS));
        context.stroke();   
    });
}

// 绘制指针
function drawHand(loc, isHour , isMin){
    var angle = (Math.PI * 2) * (loc/60) - Math.PI/2;
    var handRadius = isHour? RADIUS - HAND_TRUNCATION - HOUR_HAND_TRUNCATION
                            : (isMin ? (RADIUS - HAND_TRUNCATION) : (RADIUS * 0.95));
    context.moveTo(canvas.width/2, canvas.height/2);
    context.lineTo(canvas.width/2 + Math.cos(angle) * handRadius,
                    canvas.height/2 + Math.sin(angle) * handRadius);
    context.stroke();
}

// 绘制所有指针
function drawHands(){
    var date = new Date;
    var hour = date.getHours();
    hour = hour >12 ? hour - 12 : hour;
    // 绘制小时指针
    drawHand((hour + date.getMinutes()/60)*5, true,false);
    // 绘制分钟指针
    drawHand(date.getMinutes(),false,true);
    // 绘制秒指针
    drawHand(date.getSeconds(),false,false);
}

// 画钟
function drawClock(){
    context.clearRect(0, 0, canvas.width, canvas.height);
    drawCircle();
    drawCenter();
    drawNumbers();
    drawHands();
}
 
context.font = FONT_HEIGHT + 'px Arial';
loop = setInterval(drawClock, 1000);

另外,实现时钟的主要的难点如下:

 

在刻画指针的时候采用了这样的处理方法:

小时取1-12 但是我们会乘以5,因为我们把一个圆分成了60个小刻度,这样在渲染的时候对于时、分、秒的处理就变得很容易:

时指针的偏移度数(我们取canvas下的偏转度数)={ [ (小时数 + 当前时间的分钟/60) * 5]   /   60 } * (2 * π) - π/2。

具体理解如下:

首先我们以canvas旋转坐标定义,顺时针为+,逆时针为-,这样我们回归到0度数。假设现在需要渲染1:00,小时指针情况,显然1个小时占据圆盘的30度的夹角,我们从0开始旋转30度角成:

但是实际上1:00的表盘时指针的显示应该为:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值