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

Html:

<!doctype html>

<html>

<head>

<meta charset="UTF-8">

<title>Document</title>

<script src="requestNextAnimationFrame.js"></script>

<script src="calendarWithTime.js"></script>

</head>

<body>

<style>

* {margin:0; padding:0;}

#calendarWithTime{

margin : 0;

}

</style>

<canvas id="calendarWithTime"></canvas>

</body>

</html>

js:

;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;

}

}

以上是 js Canvas实现的日历时钟案例分享 的全部内容, 来源链接: utcz.com/z/333838.html

回到顶部