1. 程式人生 > >Canvas---Canvas繪製鐘錶,儀表盤

Canvas---Canvas繪製鐘錶,儀表盤

Canvas繪製鐘錶,儀表盤。

《HTML5 Canvas核心技術》這本書在程式碼方面,沒有絲毫註解,我感覺看的挺費勁,如果你想買書的話,最好還是先下本pdf看看吧。

下面是錶盤的繪製圖解

函式順序是按照上圖的順序來寫的,最後我為儀表加上了樣式。

原始碼:

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="content-type" content="text/html; charset=utf-8" />
        <style type="text/css">
            canvas{
                border: 1px solid black;
                background-color: #fff;
            }
        </style>
    </head>
    <body>
        <canvas  id="canvas" width="500" height="500">
        </canvas>
    </body>
    <script type = "text/javascript">
        var canvas = document.getElementById("canvas");
        var context = canvas.getContext("2d");
        
        var CENTROID_RADIUS = 10,
            CENTROID_STROKE_STYLE = "rgba(0,0,0,0.5)",
            CENTROID_FILL_STYLE = "rgba(80,190,240,0.6)";
        
        var RING_INNER_RADIUS = 35,
            RING_OUTER_RADIUS = 55;
        
        var ANNOTATION_FILL_STYLE = "rgba(0,0,230,0.9)",
            ANNOTATION_TEXT_SIZE = 12;
        
        var TICK_WIDTH = 10,
            TICK_LONG_STROKE_STYLE = "rgba(100,140,230,0.9)",
            TICK_SHORT_STROKE_STYLE = "rgba(100,140,230,0.7)";
        
        var TRACKING_DIAL_STROKING_STYLE = "rgba(100,140,230,0.5)";
        var GUIDEWIRE_STROKE_STYLE = "goldenrod",
            GUIDEWIRE_FILL_STYLE = "rgba(250,250,0,0.6)";
        
        var circle ={
            x : canvas.width/2,
            y : canvas.height/2,
            radius : 150
        };
        
         var SEC_HAND_LONG = circle.radius + RING_OUTER_RADIUS,
             MIN_HAND_LONG = SEC_HAND_LONG*(2/3),
             HOUR_HAND_LONG = SEC_HAND_LONG/3;
        
//Functions------------------------------------------------
        //繪製儀表中心的小圓
        function drawCentroid(){
            context.save();
            context.beginPath();
            context.strokeStyle = CENTROID_STROKE_STYLE;
            context.fillStyle = CENTROID_FILL_STYLE;
            context.arc(circle.x,circle.y,CENTROID_RADIUS,0,Math.PI*2,false);
            context.stroke();
            context.fill();
            context.restore();
        }
        
        //利用非零環繞規則,繪製剪紙效果的儀表外框(圓環)
        function drawRing (){
            context.save();
            
            //順時針繪製外圍圓
            context.shadowColor = "rgba(0,0,0,0.7)";
            context.shadowOffsetX = 3;
            context.shadowOffsetY = 3;
            context.shadowBlur = 6;
            context.strokeStyle = TRACKING_DIAL_STROKING_STYLE;
            context.beginPath();
            context.arc(circle.x,circle.y,circle.radius+RING_OUTER_RADIUS,0,Math.PI*2,false);
            context.stroke();
            
            //逆時針繪製內圈
            context.strokeStyle = "rgba(0,0,0,0.1)";
            context.arc(circle.x,circle.y,circle.radius+RING_INNER_RADIUS,0,Math.PI*2,true);
            context.fillStyle = "rgba(100,140,230,0.1)";
            context.fill();
            context.stroke();
            
            context.restore();
        }
        
        
        
        
        //繪製恰好與長刻度線相交的,內部的圓
        function drawTickInnerCircle(){
            context.save();
            context.beginPath();
            context.strokeStyle = "rgba(0,0,0,0.1)";
            context.arc(circle.x,circle.y,circle.radius + RING_INNER_RADIUS-TICK_WIDTH,0,Math.PI*2,false);
            context.stroke();
            context.restore();
        }
        
        
        
        //繪製儀表刻度(包括長刻度,短刻度)
        function drawTicks(){
            var radius = circle.radius + RING_INNER_RADIUS,
                ANGLE_MAX = Math.PI*2,
                ANGLE_DELTA = Math.PI/64,
                tickWidth;
            //利用度數做迴圈
            //cnt用於計算數目
            for(var angle = 0,cnt = 0; angle < ANGLE_MAX; angle = angle + ANGLE_DELTA, cnt++){
                drawTick(angle,radius,cnt);   
            }
            //利用半徑與半徑與x軸夾角繪製單個刻度
            function drawTick(angle,radius,cnt){
                var tickWidth;
                context.save();
                
                if(cnt%4 === 0){   
                    tickWidth = TICK_WIDTH;
                    context.strokeStyle = TICK_LONG_STROKE_STYLE;
                }else{
                    tickWidth = TICK_WIDTH/2;
                    context.strokeStyle = TICK_SHORT_STROKE_STYLE;
                }
                
                context.beginPath();
                context.moveTo(
                               circle.x+Math.cos(angle)*(radius-tickWidth),
                               circle.y+Math.sin(angle)*(radius-tickWidth)
                              );
                context.lineTo(
                               circle.x+Math.cos(angle)*(radius),
                               circle.y+Math.sin(angle)*(radius)
                              );
                context.stroke();
                
                context.restore();
            }
        }
        //繪製錶盤文字
        function drawAnnotations(){
            var radius = circle.radius +RING_INNER_RADIUS;
            context.save();
            context.textAlign = "center";
            context.textBaseline = "middle";
            context.font = ANNOTATION_TEXT_SIZE + "px Helvetial";
            context.fillStyle = ANNOTATION_FILL_STYLE;
            for(var angle=0; angle<Math.PI*2; angle= angle+Math.PI/8 ){
                context.beginPath();
                context.fillText(
                    (angle*180/Math.PI).toFixed(0),
                    circle.x+Math.cos(angle)*(radius-TICK_WIDTH*2),
                    circle.y+Math.sin(angle)*(radius-TICK_WIDTH*2)
                );
            }
            context.restore();
        }
        //繪製指標
        function drawPointHand(angle,handLong){
            var endpt = {
                x:circle.x+handLong*Math.cos(angle),
                y:circle.y+handLong*Math.sin(angle)
            };
            context.save();
            context.strokeStyle = GUIDEWIRE_STROKE_STYLE;
            context.fillStyle = GUIDEWIRE_FILL_STYLE;
            //繪製針柄
            context.beginPath();
            context.moveTo(circle.x,circle.y);
            context.lineTo(endpt.x,endpt.y);
            context.stroke();
            //繪製針頭(圓)
            context.beginPath();
            context.strokeStyle = TICK_LONG_STROKE_STYLE;
            context.arc(endpt.x,endpt.y,5,0,Math.PI*2,false);
            context.stroke();
            context.fill();
            context.restore();
        }
//Init-----------------------------------------------------
        drawCentroid();
        drawRing();
        drawTicks();
        drawTickInnerCircle();
        drawAnnotations();
        drawPointHand(Math.PI/3,SEC_HAND_LONG);
    </script>
</html>

本文由CSDN MIKUScallion 原創