canvas画时钟,重拾乐趣!
LonaKXUR
8年前
<p style="text-align:center"><img src="https://simg.open-open.com/show/a47fbfa242705f493ccbc780adb9726f.png"></p> <p style="text-align: center;">canvas时钟--效果图</p> <h3>一、先来简单介绍画时钟需要的canvas知识</h3> <p>1.在HTML页面中添加canvas元素,必须定义canvas元素的id属性值以便接下来的调用。</p> <p>HTML代码:</p> <pre> <code class="language-javascript"><canvas id="canvas" class="canvas" width="400" height="400" border:></canvas> </code></pre> <p>2.使用id寻找canvas元素,在js代码中使用document.getElementById()等方法获取id。</p> <pre> <code class="language-javascript">var canvas = document.getElementById("canvas"); </code></pre> <p>3.通过canvas元素的getContext方法来获取其上下文(Context),即创建Context对象,以获取允许绘画的2D环境。</p> <pre> <code class="language-javascript">var ctx = canvas.getContext("2d"); </code></pre> <p>4.先来认识一下canvas的绘制方法。</p> <p>(1)绘制矩形的两种方法:fillRect 和 strokeRect</p> <p>前者用于绘制用颜色填充(fill)区域的矩形,后者用于绘制轮廊(stroke)或线条。图形指定颜色用到了两个属性,即fillStyle 和 strokeStyle,前者用于指定要绘制的填充区域的颜色,后者用于指定要绘制的线条颜色。</p> <pre> <code class="language-javascript">//绘制填充颜色矩形,默认黑色 ctx.fillStyle="red"; ctx.fillRect(0,0,200,100); //绘制有颜色线条 ctx.strokeStyle="blue"; ctx.strokeRect(0,0,100,50); </code></pre> <p>(2)绘制圆形</p> <p>绘制圆形是会用到四种方法:beginPath、arc、closePath和fill或stroke。</p> <pre> <code class="language-javascript">//画圆填充红颜色 //绘制园用法:ctx.arc(x,y,radius,startAngle,endAngle,anticlockwise); ctx.beginPath(); ctx.fillStyle="red"; ctx.arc(0,0,100,0,2*Math.PI,true); ctx.closePath(); ctx.fill(); //线条蓝色画圆 ctx.beginPath(); ctx.strokeStyle="blue"; ctx.lineWidth=10;//设置线条宽度 ctx.arc(0,0,174,0,Math.PI*2,true); ctx.stroke(); </code></pre> <p>(3)绘制直线</p> <p>用到两个主要方法:moveTo 和 lineTo 以及stroke。</p> <p>ctx.moveTo(x,y)——规定线起始点(x,y)。ctx.lineTo(x,y)——规定直线路线的终点。</p> <pre> <code class="language-javascript">ctx.moveTo(0,0); ctx.lineTo(200,100); ctx.stroke();//该方法用于沿该路径绘制线条 </code></pre> <h3>二、画canvas时钟过程</h3> <p>首先,定义画布字体的为圆角,让我们看起来美美的:ctx.lineCap="round";</p> <p>其次,非常重要,时钟是随着时分秒针的转动而转动的,so——我们需要画布范围内必须设计画布不断清除和刷新:ctx.clearRect(0,0,400,400);</p> <p>再次,一个画布初始中心点(0,0)是在画布左上角,so——画时钟需要把中心点转移:ctx.translate(200,200);</p> <p>最后,也是最重要的,每多一个save()保存就必须在下面补上一个还原restore();</p> <p>1、画分刻线</p> <p>画线嘛,上面咱们已经讲过画线的步骤,就不多说啦!只需要注意用到rotate()方法将,先用ctx.moveTo(),ctx.lineTo在画布右侧画出第一根分刻线,再定义需要旋转的角度变量——rotateD,经过ctx.rotate(rotateD)方法来for循环以及画布不断清除刷新的状态,即可画出分刻线。</p> <p>当然这里还需要注意一点:画布需要用到另个方法来包含要执行的内容,分别是save()、restore()。save() 方法把当前状态的一份拷贝压入到一个保存图像状态的栈中。这就允许你临时地改变图像状态,然后,通过调用 <a href="/misc/goto?guid=4959739464126990150" rel="nofollow,noindex">restore()</a> 来恢复以前的值。我打个比喻:我有一只手,戴上手套去完成一些事情,手套摘下来之后,我的手还是我的手。额,有点。。。呵呵</p> <pre> <code class="language-javascript">//画刻度线 for (var i = 0; i < 60; i++) { ctx.save(); ctx.beginPath(); var rotateD = i*Math.PI*2/60; ctx.rotate(rotateD); ctx.lineWidth = 4; ctx.moveTo(170,0); ctx.lineTo(160,0); ctx.stroke(); ctx.restore(); }; </code></pre> <p>2、画时刻线</p> <p>同理,画时刻线只需要修改线宽以及旋转角度</p> <p>3、画时针</p> <p>在前面new一个data变量var date = new Date;,并且定义一个时针随时间变化旋转角度也变化的变量rotateH。</p> <p>小时针旋转角度rotateH;</p> <p>公式:rotateH = 时针旋转角度 +分针旋转角度/12 - 直角 = data.getHours()/12*2*Math.PI + date.getMinutes()/60/12*Math.PI*2 - Math.PI/2;</p> <p>(为什么会减Math.PI/2呢,因为时针的初始值为(-12,0)、(125,0);针指向正好是在三点中位置,所以需要减掉一个直角才能从十二点开始旋转)。</p> <p>4、画分针</p> <p>定义一个分针随时间变化旋转角度也变化的变量rotateM。</p> <p>公式:rotateM = 分针旋转角度 + 秒针旋转角度/60 -直角 = date.getMinutes()/60*Math.PI*2 + date.getSeconds()/60/60*Math.PI*2 - Math.PI/2;</p> <p>5、画秒针</p> <p>定义一个分针随时间变化旋转角度也变化的变量rotateS。</p> <p>公式:rotateM = 秒针旋转角度 - 减直角 = date.getSeconds()/60*Math.PI*2 - Math.PI/2;</p> <p>6、时针数字略</p> <h3>三、canvas实现时钟完整代码</h3> <p>js完整代码:</p> <pre> <code class="language-javascript">jQuery(function($){ function clock(){ var canvas= document.getElementById("canvas"); var ctx = canvas.getContext("2d"); var date = new Date; ctx.lineCap = "round";//字体变圆角 ctx.clearRect(0,0,400,400);//不断清除画布 不断再执行刷新 ctx.save();//每多一个保存就必须在下面补上一个还原restore() ctx.translate(200, 200);//中心点转移 //画刻度线 for (var i = 0; i < 60; i++) { ctx.save(); ctx.beginPath(); var rotateD = i*Math.PI*2/60; ctx.rotate(rotateD); ctx.lineWidth = 4; ctx.moveTo(170,0); ctx.lineTo(160,0); ctx.stroke(); ctx.restore(); }; for (var i = 0; i < 12; i++) { ctx.save(); ctx.beginPath(); var rotateB = i*Math.PI*2/12; ctx.lineWidth = 6; ctx.rotate(rotateB); ctx.moveTo(170,0); ctx.lineTo(150,0); ctx.stroke(); ctx.restore(); }; //画时针 var rotateH = date.getHours()/12*Math.PI*2 + date.getMinutes()/60/12*Math.PI*2 - Math.PI/2; ctx.save(); ctx.beginPath(); ctx.rotate(rotateH); ctx.lineWidth=12; ctx.moveTo(-12,0); ctx.lineTo(125,0); ctx.stroke(); ctx.restore(); //画分针 var rotateM = date.getMinutes()/60*Math.PI*2 + date.getSeconds()/60/60*Math.PI*2 - Math.PI/2; ctx.save(); ctx.strokeStyle="red"; ctx.beginPath(); ctx.rotate(rotateM); ctx.lineWidth=9; ctx.moveTo(-12,0); ctx.lineTo(135,0); ctx.stroke(); ctx.restore(); //画秒针 var rotateS = date.getSeconds()/60*Math.PI*2 - Math.PI/2; ctx.save(); ctx.strokeStyle="red"; ctx.beginPath(); ctx.rotate(rotateS); ctx.lineWidth=6; ctx.moveTo(-16,0); ctx.lineTo(140,0); ctx.stroke(); //画中心圆点 ctx.fillStyle="red"; ctx.arc(0,0,10,0,2*Math.PI) ctx.closePath(); ctx.fill(); //画秒针圆圈头 ctx.strokeStyle="red"; ctx.moveTo(160,0); ctx.arc(150,0,8,0,2*Math.PI); ctx.stroke(); ctx.restore(); // 画clock的表盘 ctx.beginPath(); ctx.strokeStyle="blue"; ctx.lineWidth=10; ctx.arc(0,0,174,0,Math.PI*2); ctx.stroke(); ctx.restore(); window.requestAnimationFrame(clock); }; window.requestAnimationFrame(clock); });</code></pre> <h2> </h2> <p> </p> <p>来自:http://www.cnblogs.com/beyond-utf-8/p/beyond-utf-8.html</p> <p> </p>