js Canvas实现的日历时钟案例分享

;var calendarWithTime = function(){ v = navigator.userAgent.toLowerCase().indexOf("android") != -1 || navigator.userAgent.toLowerCase().indexOf("iphone") != -1 || navigator.userAgent.toLowerCase().indexOf("ipad") != -1; // 浏览器可见区域 appWidth = (window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth); appHeight = (window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight) - 3; // chrome下,高度一样是,会出现下拉滚动条 // 中心点 centerPoint = {'x':appWidth*0.5,'y':appHeight*0.5}; // 动画用 lastFpsUpdateTime = (+new Date); // canvas对象 caObj = null; // canvas context对象 ctxtObj = null; // 现在时间 timeNow = ""; // 开始年份 startY = 1988; init = function(){ window.onload=function(){this.initCanvas();} }(); getDomId = function(id){return document.getElementById(id);} initCanvas = function(id){ this.caObj = this.getDomId("calendarWithTime"); this.ctxtObj = this.caObj.getContext("2d"); // 全屏canvas this.caObj.style.width = (this.appWidth+'px'); this.caObj.style.height = (this.appHeight+'px'); this.caObj.width = this.appWidth; this.caObj.height = this.appHeight; if (v) { caObj.style.border = "none"; } // 开始年份 startY = Math.floor((new Date()).getFullYear() / 8) * 8; // test // startY = Math.floor(2010 / 8) * 8; this.lastFpsUpdateTime = (+new Date); this.animate(); } doDraw = function(){ this.ctxtObj.clearRect(0, 0, this.caObj.width, this.caObj.height); var date = new Date(); // test /*date.setDate(29); date.setMonth(3); date.setFullYear(2010);*/ var afterGap = 8 - (date.getFullYear() - startY); var allYears = date.getFullYear()-this.startY+afterGap; var allDays = this.getCountDays(date.getFullYear(),date.getMonth()); this.doDrawDayPanel(31,allDays); this.doDrawMonthPanel(); this.doDrawYearPanel(this.startY,date.getFullYear(),afterGap); // 画时间针 this.doDrawTPanel(); this.drawYMDHMS(0,0.35,0,0.1,date.getSeconds(),0,30,'s',''); this.drawYMDHMS(0,0.3,0,0.05,date.getMinutes(),date.getSeconds()/60,30,'m',''); this.drawYMDHMS(0,0.25,0,0.03,date.getHours() % 12,date.getMinutes()/60,6,'h',''); this.drawYMDHMS(0.4,0.7,0.4,0.66,date.getDate(),date.getHours()/24,Math.ceil(31*0.5),'d',date.getDate()); this.drawYMDHMS(0.4,0.6,0.4,0.568,(date.getMonth()),date.getDate()/(allDays+1),6,'M',date.getMonth()+1); this.drawYMDHMS(0.4,0.55,0.4,0.52,(date.getFullYear() - this.startY),(date.getMonth()+1)/13,Math.ceil(allYears*0.5),'y',date.getFullYear()); // 显示时间 this.getTimeNow(); this.ctxtObj.save(); this.ctxtObj.beginPath(); this.ctxtObj.fillStyle = "#369"; this.ctxtObj.strokeStyle = "#369"; this.ctxtObj.font = "30px bold 微软雅黑"; this.ctxtObj.textAlign="start"; this.ctxtObj.textBaseline="top"; this.ctxtObj.fillText(this.timeNow,0,0); this.ctxtObj.strokeText(this.timeNow,0,0); this.ctxtObj.restore(); /* fillText(String text,float x,float y,[float maxwidth]):填充字符串 strokeText(String text,float x,float y,[float maxwidth]):绘制边框 font="bold 45px 宋体" textAlign:设置绘制字符串的水平对齐方式,start|end|right|center textBaseline:垂直对齐方式:top|hanging|middle|alphabetic|bottom */ } doChangeToFront = function(i,x){ // 转换为画面值 return (i +Math.ceil(x/4)) % 60; } doChangeToEnd = function(i,x){ // 转换为后台值 return (i +Math.ceil(x/4*3)) % 60; } doDrawTPanel = function(){ // 画时钟面板 var minsLen = Math.min( this.caObj.width, this.caObj.height)*0.5*0.3; var mineLen = Math.min( this.caObj.width, this.caObj.height)*0.5*0.32; var maxsLen = Math.min( this.caObj.width, this.caObj.height)*0.5*0.28; var maxeLen = Math.min( this.caObj.width, this.caObj.height)*0.5*0.34; var gap = Math.PI/30; futoNum = 5; this.ctxtObj.save(); this.ctxtObj.fillStyle = "#369"; this.ctxtObj.strokeStyle = "#369"; for(var i =0;i<=59;i++){ if(i % futoNum==0){ sLen = maxsLen; eLen = maxeLen; }else{ sLen = minsLen; eLen = mineLen; } this.ctxtObj.beginPath(); this.ctxtObj.moveTo(Math.cos(i*gap)*sLen + this.centerPoint.x ,Math.sin(i*gap)*sLen + this.centerPoint.y); this.ctxtObj.lineTo(Math.cos(i*gap)*eLen + this.centerPoint.x,Math.sin(i*gap)*eLen + this.centerPoint.y); this.ctxtObj.stroke(); this.ctxtObj.closePath(); /*iDiff = this.doChangeToFront(i); // i => iDiff //iDiff2 = this.doChangeToEnd(iDiff,60); // iDiff => i this.ctxtObj.font = "2px bold 微软雅黑"; this.ctxtObj.textAlign="center" this.ctxtObj.textBaseline="middle" this.ctxtObj.fillText(iDiff,Math.cos(i*gap)*eLen + this.centerPoint.x,Math.sin(i*gap)*eLen + this.centerPoint.y); */ } this.ctxtObj.beginPath(); this.ctxtObj.arc(this.centerPoint.x,this.centerPoint.y,Math.min( this.caObj.width, this.caObj.height)*0.5*0.01,0,360,false); this.ctxtObj.fillStyle="red"; this.ctxtObj.fill(); this.ctxtObj.closePath(); this.ctxtObj.restore(); } doDrawYearPanel = function(startYear,nowYear,afterGap){ // 画年份面板 var sLen = Math.min( this.caObj.width, this.caObj.height)*0.5*0.53; var eLen = Math.min( this.caObj.width, this.caObj.height)*0.5*0.55; var labelLen = Math.min( this.caObj.width, this.caObj.height)*0.5*0.60; var allYears = nowYear-startYear+afterGap; var gap = Math.PI/Math.ceil(allYears*0.5); this.ctxtObj.save(); this.ctxtObj.fillStyle = "#b4ffff"; this.ctxtObj.beginPath(); this.ctxtObj.arc(this.centerPoint.x,this.centerPoint.y,eLen+2,0,360,false); this.ctxtObj.closePath(); this.ctxtObj.fill(); this.ctxtObj.fillStyle = "white"; this.ctxtObj.beginPath(); this.ctxtObj.arc(this.centerPoint.x,this.centerPoint.y,sLen-2,0,360,false); this.ctxtObj.closePath(); this.ctxtObj.fill(); this.ctxtObj.restore(); this.ctxtObj.fillStyle = "#369"; this.ctxtObj.strokeStyle = "#369"; for(var i =-2;i<=allYears-3;i++){ this.ctxtObj.save(); this.ctxtObj.beginPath(); this.ctxtObj.moveTo(Math.cos(i*gap)*sLen + this.centerPoint.x ,Math.sin(i*gap)*sLen + this.centerPoint.y); this.ctxtObj.lineTo(Math.cos(i*gap)*eLen + this.centerPoint.x,Math.sin(i*gap)*eLen + this.centerPoint.y); this.ctxtObj.closePath(); this.ctxtObj.stroke(); iDiff = this.doChangeToFront(i,allYears) + startYear; this.ctxtObj.translate(this.centerPoint.x, this.centerPoint.y); this.ctxtObj.rotate(i*gap); this.ctxtObj.font = "10px bold 微软雅黑"; this.ctxtObj.textAlign="start"; this.ctxtObj.textBaseline="bottom"; this.ctxtObj.fillText(iDiff,sLen,0); this.ctxtObj.restore(); } } doDrawMonthPanel = function(){ // 画年份面板 var sLen = Math.min( this.caObj.width, this.caObj.height)*0.5*0.58; var eLen = Math.min( this.caObj.width, this.caObj.height)*0.5*0.6; var labelLen = Math.min( this.caObj.width, this.caObj.height)*0.5*0.70; var gap = Math.PI/6; this.ctxtObj.save(); this.ctxtObj.fillStyle = "#fde08c"; this.ctxtObj.beginPath(); this.ctxtObj.arc(this.centerPoint.x,this.centerPoint.y,eLen+2,0,360,false); this.ctxtObj.closePath(); this.ctxtObj.fill(); this.ctxtObj.fillStyle = "white"; this.ctxtObj.beginPath(); this.ctxtObj.arc(this.centerPoint.x,this.centerPoint.y,sLen-2,0,360,false); this.ctxtObj.closePath(); this.ctxtObj.fill(); this.ctxtObj.restore(); this.ctxtObj.fillStyle = "#369"; this.ctxtObj.strokeStyle = "#369"; for(var i =-2;i<=9;i++){ this.ctxtObj.save(); this.ctxtObj.beginPath(); this.ctxtObj.moveTo(Math.cos(i*gap)*sLen + this.centerPoint.x ,Math.sin(i*gap)*sLen + this.centerPoint.y); this.ctxtObj.lineTo(Math.cos(i*gap)*eLen + this.centerPoint.x,Math.sin(i*gap)*eLen + this.centerPoint.y); this.ctxtObj.closePath(); this.ctxtObj.stroke(); iDiff = (this.doChangeToFront(i,12)) % 12+1; this.ctxtObj.translate(this.centerPoint.x, this.centerPoint.y); this.ctxtObj.rotate(i*gap); this.ctxtObj.font = "20px bold 微软雅黑"; this.ctxtObj.textAlign="start"; this.ctxtObj.textBaseline="middle"; this.ctxtObj.fillText((iDiff+'').PadLeft(2,0),eLen,0); this.ctxtObj.restore(); } } doDrawDayPanel = function(dayCount,realAllDay){ // 画年份面板 var sLen = Math.min( this.caObj.width, this.caObj.height)*0.5*0.68; var eLen = Math.min( this.caObj.width, this.caObj.height)*0.5*0.7; var labelLen = Math.min( this.caObj.width, this.caObj.height)*0.5*0.80; var gap = Math.PI/Math.ceil(dayCount*0.5); this.ctxtObj.save(); this.ctxtObj.fillStyle = "#e587e5"; this.ctxtObj.beginPath(); this.ctxtObj.arc(this.centerPoint.x,this.centerPoint.y,eLen+2,0,360,false); this.ctxtObj.closePath(); this.ctxtObj.fill(); this.ctxtObj.fillStyle = "white"; this.ctxtObj.beginPath(); this.ctxtObj.arc(this.centerPoint.x,this.centerPoint.y,sLen-2,0,360,false); this.ctxtObj.closePath(); this.ctxtObj.fill(); this.ctxtObj.restore(); this.ctxtObj.fillStyle = "#369"; this.ctxtObj.strokeStyle = "#369"; for(var i =-2;i<=dayCount-2;i++){ this.ctxtObj.save(); this.ctxtObj.beginPath(); this.ctxtObj.moveTo(Math.cos(i*gap)*sLen + this.centerPoint.x ,Math.sin(i*gap)*sLen + this.centerPoint.y); this.ctxtObj.lineTo(Math.cos(i*gap)*eLen + this.centerPoint.x,Math.sin(i*gap)*eLen + this.centerPoint.y); this.ctxtObj.closePath(); this.ctxtObj.stroke(); iDiff = (this.doChangeToFront(i,dayCount)) % (dayCount+1); if(iDiff<=realAllDay && iDiff!=0){ this.ctxtObj.translate(this.centerPoint.x, this.centerPoint.y); this.ctxtObj.rotate(i*gap); this.ctxtObj.font = "20px bold 微软雅黑"; this.ctxtObj.textAlign="start"; this.ctxtObj.textBaseline="middle"; this.ctxtObj.fillText((iDiff+'').PadLeft(2,0),eLen,0); } this.ctxtObj.restore(); } } drawYMDHMS = function(slen,elen,cslen,celen,main,sub,gapM,type,value){ // 画日期时间针 var date = new Date(); var siM = main; var siS = sub; var gap = Math.PI/gapM; var sLen = Math.min( this.caObj.width, this.caObj.height)*0.5*slen; var eLen = Math.min( this.caObj.width, this.caObj.height)*0.5*elen; var csLen = Math.min( this.caObj.width, this.caObj.height)*0.5*cslen; var ceLen = Math.min( this.caObj.width, this.caObj.height)*0.5*celen; i = this.doChangeToEnd(siM+siS,gapM*2); ci = (i+gapM) % (gapM*2); this.ctxtObj.save(); this.ctxtObj.beginPath(); if(type=='y'){ this.ctxtObj.strokeStyle="#00cece"; this.ctxtObj.lineWidth = 6; }else if(type=='M'){ this.ctxtObj.strokeStyle="#ce9b00"; this.ctxtObj.lineWidth = 5; }else if(type=='d'){ this.ctxtObj.strokeStyle="#bd01bd"; this.ctxtObj.lineWidth = 4; }else if(type=='h'){ this.ctxtObj.lineWidth = 3; }else if(type=='m'){ this.ctxtObj.lineWidth = 2; }else if(type=='s'){ this.ctxtObj.lineWidth = 1; } this.ctxtObj.moveTo(Math.cos(i*gap)*sLen + this.centerPoint.x ,Math.sin(i*gap)*sLen + this.centerPoint.y); this.ctxtObj.lineTo(Math.cos(i*gap)*eLen + this.centerPoint.x,Math.sin(i*gap)*eLen + this.centerPoint.y); this.ctxtObj.moveTo(Math.cos(ci*gap)*csLen + this.centerPoint.x ,Math.sin(ci*gap)*csLen + this.centerPoint.y); this.ctxtObj.lineTo(Math.cos(ci*gap)*ceLen + this.centerPoint.x,Math.sin(ci*gap)*ceLen + this.centerPoint.y); this.ctxtObj.stroke(); this.ctxtObj.closePath(); this.ctxtObj.restore(); var cpi = ci*gap*360/Math.PI; if(type=='y'){ this.ctxtObj.save(); this.ctxtObj.fillStyle = "#00cece"; this.ctxtObj.strokeStyle="#00cece"; this.ctxtObj.lineWidth = 8; this.ctxtObj.beginPath(); this.ctxtObj.arc(this.centerPoint.x,this.centerPoint.y,ceLen,ci*gap-gap*0.5,ci*gap+gap*0.5,false); this.ctxtObj.stroke(); this.ctxtObj.closePath(); this.ctxtObj.translate(this.centerPoint.x, this.centerPoint.y); this.ctxtObj.rotate(i*gap); this.ctxtObj.font = "20px bold 微软雅黑"; this.ctxtObj.textAlign="start"; this.ctxtObj.textBaseline="middle"; this.ctxtObj.lineWidth = 2; this.ctxtObj.fillText(value + '年',eLen*1.03,0); this.ctxtObj.strokeText(value + '年',eLen*1.03,0); this.ctxtObj.restore(); }else if(type=='M'){ this.ctxtObj.save(); this.ctxtObj.beginPath(); this.ctxtObj.fillStyle = "#ce9b00"; this.ctxtObj.strokeStyle="#ce9b00"; this.ctxtObj.lineWidth = 7; this.ctxtObj.arc(this.centerPoint.x,this.centerPoint.y,ceLen,ci*gap-gap*0.5,ci*gap+gap*0.5,false); this.ctxtObj.stroke(); this.ctxtObj.closePath(); this.ctxtObj.translate(this.centerPoint.x, this.centerPoint.y); this.ctxtObj.rotate(i*gap); this.ctxtObj.font = "20px bold 微软雅黑"; this.ctxtObj.textAlign="start"; this.ctxtObj.textBaseline="middle"; this.ctxtObj.lineWidth = 2; this.ctxtObj.fillText(value + '月',eLen*1.03,0); this.ctxtObj.strokeText(value + '月',eLen*1.03,0); this.ctxtObj.restore(); }else if(type=='d'){ this.ctxtObj.save(); this.ctxtObj.beginPath(); this.ctxtObj.fillStyle = "#bd01bd"; this.ctxtObj.strokeStyle="#bd01bd"; this.ctxtObj.lineWidth = 6; this.ctxtObj.arc(this.centerPoint.x,this.centerPoint.y,ceLen,ci*gap-gap*0.5,ci*gap+gap*0.5,false); this.ctxtObj.stroke(); this.ctxtObj.closePath(); this.ctxtObj.translate(this.centerPoint.x, this.centerPoint.y); this.ctxtObj.rotate(i*gap); this.ctxtObj.font = "20px bold 微软雅黑"; this.ctxtObj.textAlign="start"; this.ctxtObj.textBaseline="middle"; this.ctxtObj.lineWidth = 2; this.ctxtObj.fillText(value + '日',eLen*1.03,0); this.ctxtObj.strokeText(value + '日',eLen*1.03,0); this.ctxtObj.restore(); } this.ctxtObj.restore(); } animate = function(){ var now = (+new Date); if (now - this.lastFpsUpdateTime > 60) { this.lastFpsUpdateTime = now; this.doDraw(); } window.requestNextAnimationFrame(this.animate); } getCountDays = function (year,month) { var curDate = new Date(); curDate.setFullYear(year); curDate.setMonth(month+1); curDate.setDate(0); return curDate.getDate(); } getTimeNow = function(){ var date = new Date(); var seperator1 = "-"; var seperator2 = ":"; this.timeNow = date.getFullYear() + seperator1 + (date.getMonth()+1+'').PadLeft(2,0) + seperator1 + (date.getDate()+'').PadLeft(2,0) + " " + (date.getHours()+'').PadLeft(2,0) + seperator2 + (date.getMinutes()+'').PadLeft(2,0) + seperator2 + (date.getSeconds()+'').PadLeft(2,0) + '.' +(date.getMilliseconds()+'').PadLeft(3,0); } // objects } var cwt = new calendarWithTime(); //================================================= String.prototype.PadLeft = function(totalWidth, paddingChar) { if ( paddingChar != null ) { return this.PadHelper(totalWidth, paddingChar, false); } else { return this.PadHelper(totalWidth, ' ', false); } } String.prototype.PadRight = function(totalWidth, paddingChar) { if ( paddingChar != null ) { return this.PadHelper(totalWidth, paddingChar, true); } else { return this.PadHelper(totalWidth, ' ', true); } } String.prototype.PadHelper = function(totalWidth, paddingChar, isRightPadded) { if ( this.length < totalWidth) { var paddingString = new String(); for (i = 1; i <= (totalWidth - this.length); i++) { paddingString += paddingChar; } if ( isRightPadded ) { return (this + paddingString); } else { return (paddingString + this); } } else { return this; } }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wwjxgx.html