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

作者:望星辰 时间:2024-04-22 13:08:26 

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

来源:http://www.cnblogs.com/wangxinsheng/p/6219688.html

标签:js,Canvas,时钟
0
投稿

猜你喜欢

  • Pytorch中如何调用forward()函数

    2023-06-14 21:00:24
  • 详解python 一维、二维列表的初始化问题

    2023-01-21 06:57:31
  • 深入理解Golang的单元测试和性能测试

    2024-05-05 09:27:42
  • python通过pip更新所有已安装的包实现方法

    2021-06-04 03:22:34
  • Go语言开发编程规范命令风格代码格式

    2024-05-22 10:15:03
  • 用Python写飞机大战游戏之pygame入门(4):获取鼠标的位置及运动

    2023-09-28 11:01:21
  • 关于通过Java连接mysql对反斜杠”\\“转义的测试详解

    2024-01-27 06:52:59
  • 如何使用pyinstaller打包时引入自己编写的库

    2022-03-04 14:41:12
  • 如何提升JavaScript的运行速度(函数篇)

    2010-05-17 13:27:00
  • PyQt5组件读取参数的实例

    2023-04-02 07:47:29
  • 微软建议的ASP性能优化28条守则(8)

    2005-05-30 16:04:00
  • Tensorflow2.4从头训练Word Embedding实现文本分类

    2023-05-22 20:03:17
  • ASP判断一个字符串中只包含字母和数字

    2008-08-08 12:12:00
  • utf8_unicode_ci与utf8_general_ci的区别

    2010-03-03 15:54:00
  • vue+echarts封装气泡图的方法

    2024-05-09 15:09:45
  • 实例讲解Access数据库在线压缩的实现方法

    2008-11-28 14:29:00
  • 在Python中使用AOP实现Redis缓存示例

    2021-09-12 11:18:45
  • Python实现k-means算法

    2023-07-01 22:06:53
  • Asp 操作Access数据库时出现死锁.ldb的解决方法

    2011-03-29 10:49:00
  • SQL 截取字符串应用代码

    2024-01-21 08:53:14
  • asp之家 网络编程 m.aspxhome.com