代码改变世界

HTML5 Canvas 绘制时钟

2013-01-29 15:47  VVG  阅读(6479)  评论(6编辑  收藏

demo演示:

用到的一些绘制方法说明:

context.translate(x,y)方法,重新设置画布的坐标源点,设置后,x,y坐标处为变为起始坐标(0,0);

context.arc(圆心x坐标, 圆心Y坐标, 圆半径, 起始弧度,结束点弧度, 是否顺时针) 方法绘制圆形,或者圆弧;

context.rotate(弧度) 方法接受一个弧度制参数,旋转画布,然后绘制图形,相当于给绘制的图形旋转一个角度;

context.save() 和 context.restore() 方法,记录起始状态和回复状态

context.fillRect(矩形左上角X坐标,Y坐标,宽度,高度):  绘制矩形

context.fillText(text,左上角x坐标,Y坐标): 绘制文字

修改:调整了下数字的显示,最开始用Math.cos\Math.sin计算出来的值总是不对,就偷懒用旋转的方式来画的数字,这样显示出来文字是旋转的

最后发现原来是Math.cos\Math.sin接受的是弧度制为单位,我最开始传成角度制了,查了资料才发现时这个原因,改了就对了:

数字坐标计算方法:

      知道了半径,知道了角度,用三角函数的公式就能计算出相应的位置。     

        // 绘制表盘文字
        for(i = 0;i<12;i++){
            // 360度分为12段,每段30度
            angle = i * 30;
            // 转换为弧度制,Math.sin、Math.cos都接受弧度制单位
            angle = angle*Math.PI/180;;
            // 0度角是3点,所以需要转换一下数字
            font = (i + 3 > 12)?i+3-12 : i+3;
            // 计算X坐标
            fontX = Math.round(Math.cos(angle)*(r-30));
            // 计算Y坐标
            fontY = Math.round(Math.sin(angle)*(r-30));
            // 设置文字样式
            context.font = 'bold 14px 微软雅黑';
            // 绘制文字
            context.fillText(font+'',fontX,fontY);
        }

canvas 动画就是不断清除重绘的过程

角度弧度制转换,高中课本上有,都忘得差不多了,如下:

弧度制单位:rad    角度制单位:度        →      180度 = PI弧度    →        1度 = PI弧度/180度      →       1弧度= 180度/PI弧度

得出角度转换公式 ↓↓↓↓↓

弧度 = 角度*PI/180

角度 = 弧度*180/PI

代码如下:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>canvas绘制时钟</title>
</head>
<body>
<canvas id="graph" width="500px" height="500">你的浏览器不支持canvas</canvas>
<script type="text/javascript">
    var canvas = document.getElementById('graph');
    var context = canvas.getContext('2d');
    var r = canvas.width/2.5;  //半径
    //将坐标中心作为起启点
    context.translate(canvas.width / 2, canvas.height / 2);

    function drawCircle() {
        context.beginPath();
        context.lineWidth = 5;
        context.strokeStyle = "#000";
        context.arc(0, 0, r, 0, Math.PI * 2, true);
        context.stroke();
        context.closePath();
    }

    function drawClockScale() {
        var rad = 0, angle, font, fontX, fontY;
        context.fillStyle = '#000';
        // 绘制表盘时刻度
        for (var i = 0; i < 12; i++) {
            context.save();
            rad = i * Math.PI / 6;  // 弧度制,大刻度,总共分为12刻度,每刻度为:2π/12 → π/6
            context.rotate(rad);  // 旋转画布绘制刻度
            context.fillRect(r - 10, 0, 10, 5);
            context.restore();
        }
        // 绘制表盘分刻度
        for (i = 0; i < 60; i++) {
            context.save();      // 记录旋转画布之前初始状态
            rad = i*Math.PI/30;
            context.rotate(rad);  // 旋转画布绘制刻度
            context.fillRect(r - 10, 0, 5, 2);   //绘制
            context.restore();  // 恢复初始状态,未旋转前
        }

        // 绘制表盘文字
        for(i = 0;i<12;i++){
            angle = i * 30;
            // 转换为弧度制,Math.sin、Math.cos都接受弧度制单位
            angle = angle*Math.PI/180;;
            font = (i + 3 > 12)?i+3-12 : i+3;
            fontX = Math.round(Math.cos(angle)*(r-30));
            fontY = Math.round(Math.sin(angle)*(r-30));
            context.font = 'bold 14px 微软雅黑';
            context.fillText(font+'',fontX,fontY);
        }
    }

    function drawHand(rotate,width,height){
        context.save();
        rotate = rotate*Math.PI/180;      // 转换为弧度制
        context.rotate(rotate);
        context.fillRect(-10,0,width,height);
        context.restore();
    }

    function setTime(){
        var hour = new Date().getHours();
        var minute = new Date().getMinutes();
        var second = new Date().getSeconds();

        //console.log(hour + ':' + minute + ':' + second);
        var hourRotate,minRotate,secRotate;
        // 计算秒针角度并绘制图形
        secRotate = second*6-90;
        drawHand(secRotate,r-30,2);
        // 计算分针角度并绘制图形
        minRotate = (minute*60 + second)*0.1 - 90;
        drawHand(minRotate,r-50,4);
        // 计算时针角度并绘制图形
        hourRotate = (hour*60*60 + minute*60 + second)/120 - 90;
        drawHand(hourRotate,r-70,5);
    }

    setInterval(function(){
        context.clearRect(-canvas.width / 2,-canvas.height / 2,canvas.width,canvas.height);
        drawCircle();
        drawClockScale();
        setTime();
    },1000);
</script>
</body>
</html>