原理:
1.canvas通过clip()指定对应的区域为可用区域,在区域外的部分不受影响,每次刷新可见区域
2.通过createPattern指定背景图片,通过fillStyle = pat应用填充结果
3.save, restore恢复原来的状态
4.指针通过角度变换得到对应的坐标,lineTo即可
5.toDataURL保存对应的canvas的png的base64值
效果:
代码:
<!DOCTYPE HTML> <html lang="en"> <head> <meta charset="UTF-8"> <title>clock test</title> <style type="text/css"> canvas{border:1px solid #111;} </style> </head> <body> <canvas width="400" height="300" id="canvasContainer">Your Browser does not support Canvas</canvas> <img id="myimg" src="images/01.png" width="1" height="1" /> <select id="bg" onchange="changePic(this.value)">//背景图片选择 <option value="01">01.png</option> <option value="02">02.png</option> <option value="04">04.png</option> <option value="08">08.png</option> <option value="09">09.png</option> <option value="11">11.png</option> <option value="12">12.png</option> <option value="14">14.png</option> </select> <button onclick="savePic()">SavePic</button> <script type="text/javascript"> window.onload = init; function init(){ //数据初始化 $canvas = document.getElementById('canvasContainer'); ctx = $canvas.getContext("2d"); drawSomething(); window.setInterval(drawCircle,200); } function savePic(){//图片保存方法 var img = new Image(); img.src = $canvas.toDataURL();//这句是重点 document.body.appendChild(img); } function changePic(pic){ pic = "images/"+pic+".png"; var img = document.getElementById("myimg"); img.onload = function(){ ctx.drawImage(img,0,0,128,128,150,0,200,200);//右侧背景图片显示,以区别时钟区域的刷新 } img.src = pic; } function drawCircle(){ //时钟绘制 var x = 64, y=64; var img = document.getElementById("myimg"); var pat = ctx.createPattern(img,"no-repeat");//时钟背景填充初始化 var sL = 50,mL=40,hL=30,dt=new Date();//角度计算 var sang = -Math.PI*(dt.getSeconds()*6)/180+Math.PI; var mang = -Math.PI*(dt.getMinutes()*6)/180+Math.PI; var hang = -Math.PI*(dt.getHours()*30)/180+Math.PI-dt.getMinutes()/360*Math.PI*0.5; ctx.save(); ctx.strokeStle = "#fff"; ctx.arc(x,y,64,0,Math.PI*2); ctx.clip();//可见区域定制 ctx.clearRect(0,0,400,300);//全画布清空,只有可见区域被清空, ctx.fillStyle = pat; ctx.fill();//时钟背景应用 ctx.beginPath();//时钟指针绘制 ctx.strokeStyle = "#e33";ctx.fillStyle="#e33";ctx.lineWidth = 1; ctx.moveTo(x,y); ctx.lineTo(x+sL*Math.sin(sang),y+sL*Math.cos(sang)); ctx.arc(x+sL*Math.sin(sang),y+sL*Math.cos(sang),2,0,Math.PI*2); ctx.fill(); ctx.closePath(); ctx.stroke(); ctx.beginPath(); ctx.strokeStyle = "#2f2"; ctx.lineWidth = 2; ctx.moveTo(x,y); ctx.lineTo(x+mL*Math.sin(mang),y+mL*Math.cos(mang)); ctx.closePath(); ctx.stroke(); ctx.beginPath(); ctx.strokeStyle = "#11e"; ctx.lineWidth = 3; ctx.moveTo(x,y); ctx.lineTo(x+hL*Math.sin(hang),y+hL*Math.cos(hang)); ctx.closePath(); ctx.stroke(); ctx.fillStyle = "#e33"; ctx.arc(x,y,5,0,Math.PI*2); ctx.fill(); ctx.restore(); } function drawSomething(){//显示年月日,与右侧时钟背景作用类似,以区别这里不被重绘 ctx.fillStyle = "#eee"; ctx.fillRect(0,0,640,480); ctx.fillStyle = "#333"; ctx.fillRect(0,128,128,20); ctx.fillStyle = "#fff"; ctx.font = "14px Arial"; ctx.textAlign = "center"; ctx.textBaseline = "top"; var dt = new Date(); var dy = dt.getFullYear(),dm=dt.getMonth()+1,dd=dt.getDate(); var str = dy + "年" + dm+"月" + dd + "日"; ctx.fillText(str,64,128); } </script> </body> </html>
完整源代码如附件
如有转载,请保留以下内容
author: mooring
site: http://mooring.iteye.com/
date: 2012/07/15