5.10.1_秒表

来源:互联网 发布:windows更新怎么关闭 编辑:程序博客网 时间:2024/06/11 01:23

5.10.1_秒表

<!DOCTYPE html><html>    <head>        <meta charset="UTF-8">        <title>秒表</title>        <style>            body{                background: #fff;            }            #canvas{                background: #eee;            }            #controls{                position: absolute;                left: 25px;                top: 25px;            }        </style>    </head>    <body>        <div id="controls">            秒数(0-60):<input id="secondsInput" type="number" value="0" />            <input id="startStopButton" type="button" value="start"  />        </div>        <canvas id="canvas" width="1000" height="600"></canvas>    </body>    <!-- 秒表的构造函数 -->    <script>        StopWatch = function(){};        StopWatch.prototype = {            startTime: 0,            running: false,            elapsed: undefined, //过去的时间            start:function(){                this.startTime = +new Date();                this.elapsed = undefined;                this.running = true;            },            stop:function(){                this.elapsed = (+new Date()) - this.startTime;                this.running = false;            },            getElapsedTime:function(){                if(this.running){                    return (+new Date()) - this.startTime;                }else{                    return this.elapsed;                }            },            isRunning:function(){                return this.running;            },            reset:function(){                this.elapsed = 0;            }        }    </script>    <script>        var canvas = document.getElementById('canvas'),            context = canvas.getContext('2d'),            stopwatch = new StopWatch(),            secondsInput = document.getElementById('secondsInput'),            startStopButton = document.getElementById('startStopButton'),            timerSetting = 0,            //离屏canvas            offscreenCanvas = document.createElement('canvas'),            offscreenContext = offscreenCanvas.getContext('2d'),            //中心点圆的样式            centroid_radius = 10 ,            centroid_stroke_style = 'rgba(0,0,0,0.5)',            centroid_fill_style = 'rgba(80,190,240,0.6)',            //内外圆小半径            ring_inner_radius = 35,            ring_outer_radius = 55,            //刻度文字的样式            annotations_fill_style = 'rgba(0,0,230,0.9)',            annotations_text_size = 16,            //刻度线的样式            tick_width = 10,            tick_long_stroke_style = 'rgba(100,140,230,0.9)',            tick_short_stroke_style = 'rgba(100,140,230,0.7)',            tracking_dial_stroking_style = 'rgba(100,140,230,0.5)',            //指针的样式            guidewire_stroke_style = 'goldenrod',            guidewire_fill_style = 'rgba(250,250,0,0.6)',            //圆            circle ={                x:canvas.width/2,                y:canvas.height/2,                radius:150            };            //初始化            offscreenCanvas.width = canvas.width;            offscreenCanvas.height = canvas.height;            context.shadowColor ='rgba(0,0,0,0.4)';            context.shadowOffsetX = 2;            context.shadowOffsetY = 2;            context.shadowBlur = 4;            context.textAlign = 'center';            context.textBaseline = 'middle';            drawGrid('lightgray',10,10);            drawDial();            //保存背景            offscreenContext.drawImage(canvas,0,0);            //绘制指示线            drawCentroidGuidewire(circle,-Math.PI/2);            //事件            startStopButton.onclick = function(e){                var value = this.value;                timerSetting = parseFloat(secondsInput.value);                if(value == 'start'){                    stopwatch.start();                    this.value = 'stop';                    secondsInput.disabled = true;                    requestAnimationFrame(animate);                }else{                    stopwatch.stop();                    this.value = 'start';                    secondsInput.disabled = false;                }            }            //每帧动画            function animate(){                if(stopwatch.isRunning()&& stopwatch.getElapsedTime()>timerSetting*1000){ //倒计时已完成                    stopwatch.stop();                    startStopButton.value = 'start';                    secondsInput.disabled = false;                    secondsInput.value = 0;                    erase();                    context.drawImage(offscreenCanvas,0,0);                    drawCentroidGuidewire(circle,-Math.PI/2);                }else if(stopwatch.isRunning()){ //倒计时进行中                    redraw();                    requestAnimationFrame(animate);                }            }            //重绘            function redraw(){                //得到从start开始的秒数                var ang = (stopwatch.getElapsedTime()/1000)*6*(Math.PI/180)-Math.PI/2;                erase();                context.drawImage(offscreenCanvas,0,0);                drawCentroidGuidewire(circle,ang);            }            //清空画布            function erase(){                context.clearRect(0,0,canvas.width,canvas.height);            }            //绘制指示线            function drawCentroidGuidewire(loc,ang){                var angle = ang,                   radius,endpt;                radius = circle.radius+ring_outer_radius;                if(loc.x>=circle.x){  //这里加判断不是很清楚                    endpt ={                        x:circle.x+radius*Math.cos(angle),                        y:circle.y+radius*Math.sin(angle)                    }                }else{                    endpt = {                        x:circle.x-radius*Math.cos(angle),                        y:circle.y-radius*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.fill();                context.stroke();                context.restore()            }            //绘制表盘            function drawDial(){                var loc = {                    x:circle.x,                    y:circle.y                };                drawCentroid();//画表盘中心                drawRing();//绘制表盘                drawTickInnerCircle();//绘制刻度线内圆                drawTicks();//绘制刻度线                drawAnnotations();//绘制刻度文字            }            //绘制刻度文字            function drawAnnotations(){                var radius = circle.radius+ring_inner_radius-tick_width*3.5;                context.save();                context.fillStyle = annotations_fill_style;                context.font = annotations_text_size +'px helvetica';                for(var angle =0; angle<2*Math.PI;angle+=Math.PI/6){                    context.beginPath();                    context.fillText((angle*30/Math.PI).toFixed(0),                        circle.x-Math.cos(angle+Math.PI/2)*radius,                        circle.y-Math.sin(angle+Math.PI/2)*radius                    );                }                context.restore();            }            //绘制刻度线            function drawTicks(){                var radius = circle.radius+ring_inner_radius,                    angle_max = Math.PI*2,                    angle_delta = Math.PI/30,//半圆分30段                    tickWidth;                    context.save();                    for(var angle = 0,cnt=0;angle<angle_max;angle+=angle_delta,cnt++){                        drawTick(angle,radius,cnt);                    }                    context.restore();            }            //绘制每个刻度线            function drawTick(angle,radius,cnt){                var tickWidth = cnt % 5 ===0? tick_width*2:tick_width/2;                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.strokeStyle = tick_short_stroke_style;                context.stroke();            }            //绘制刻度线内圆            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 drawRing(){                //利用了非零环绕原则                drawRingOuterCircle();                drawRingInnerCircle();            }            //绘制外表盘            function drawRingOuterCircle(){                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,true);//逆时针画外圆                context.stroke();            }            //绘制内表盘            function drawRingInnerCircle(){                context.strokeStyle = 'rgba(0,0,0,0.1)';                context.fillStyle = 'rgba(100,140,230,0.1)';//              context.moveTo(circle.x+circle.radius+ring_inner_radius,circle.y);                context.arc(circle.x,circle.y,circle.radius+ring_inner_radius,0,Math.PI*2,false);//顺时针画圆                context.fill();                context.stroke();            }            //绘制表盘中心            function drawCentroid(){                context.beginPath();                context.save();                context.strokeStyle = centroid_stroke_style;                context.fillStyle = centroid_fill_style;                context.arc(circle.x,circle.y,centroid_radius,0,Math.PI*2,false);                context.fill();                context.stroke();                context.restore();            }            //网格线            function drawGrid(color,stepX,stepY){                context.save();                context.shadowColor = undefined;                context.shadowOffsetX = 0;                context.shadowOffsetY = 0;                context.shadowBlur =0;                context.strokeStyle = color;                context.lineWidth =0.5;                context.fillStyle = '#fff';                context.fillRect(0,0,canvas.width,canvas.height);                for(var i=stepX+0.5;i<context.canvas.width;i+=stepX){                    context.beginPath();                    context.moveTo(i,0);                    context.lineTo(i,context.canvas.height);                    context.stroke();                }                for(var i=stepY+0.5;i<context.canvas.height;i+=stepY){                    context.beginPath();                    context.moveTo(0,i);                    context.lineTo(context.canvas.width,i);                    context.stroke();                }                context.restore();            }    </script></html>
原创粉丝点击