原理:
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" οnchange="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 οnclick="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