[JS,Canvas]日历时钟

Html:

 1 <!doctype html>
 2 <html>
 3 <head>
 4 <meta charset="UTF-8">
 5 <title>Document</title>
 6 <script src="requestNextAnimationFrame.js"></script>
 7 <script src="calendarWithTime.js"></script>
 8 </head>
 9 <body>
10 <style>
11 * {margin:0; padding:0;}
12 #calendarWithTime{
13     margin : 0;
14 }
15 </style>
16 <canvas id="calendarWithTime"></canvas>
17 </body>
18 </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://download.csdn.net/download/wangxsh42/9720724

@wangxinsheng http://www.cnblogs.com/wangxinsheng/

时间: 2024-10-27 01:07:45

[JS,Canvas]日历时钟的相关文章

HTML5 Canvas爱心时钟代码

这是一款数字时钟动画,数字又多个小爱心组成,又何问起整理,随着时间推进,每一秒钟新数字替换旧数字,旧数字离去使用天女散花动画,花是五颜六色的. 查看效果:http://hovertree.com/texiao/html5/48/ 推荐其他时钟:http://hovertree.com/h/bjaf/o0yqj1ly.htmhttp://hovertree.com/h/bjaf/hoverclock.htm 代码如下: <!DOCTYPE html> <html> <head&

html5学习(一)--canvas画时钟

利用空余时间学习一下html5. 1 <!doctype html> 2 <html> 3 <head></head> 4 <body> 5 <canvas id="clock" width="500" height="500"></canvas> 6 <script> 7 var clock=document.getElementById('cloc

JS实现日历

7.2-- 以前写特效都用jquery,js使用还不熟的很,最近又在看<javascript权威指南>,正好公司的项目有个日历签到的功能,就先用js写个日历控件试试,目前还只实现了基本的功能,先贴代码: html 1 <!DOCTYPE html> 2 <html> 3 <head> 4 <title></title> 5 <meta charset="utf-8"> 6 <link rel=&q

分享一个很有意思的js,动态时钟显示,能跟随鼠标移动

原文:分享一个很有意思的js,动态时钟显示,能跟随鼠标移动 源代码下载地址:http://www.zuidaima.com/share/1550463688182784.htm

js绘制圆形时钟

纯js制作圆形时钟 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> *{ margin:0; padding:0; } body{ background: grey; } .box{ width:320px; height: 320px; borde

js数字滑动时钟

js数字滑动时钟: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <style type="text/css"> body,ul{margin:0;padding: 0;} .content{margin:100px auto;width

js简易日历

js简易日历中设计的知识点:选项卡切换   数组    innerHTML  连接符 与选项卡的区别:div的个数不同 连接符中需要注意的:(优先级) "abc"+12+3+"def"               结果:abc123def "abc"+(12+3)+"def"            结果:abc15def html代码: <body> <div class="contain"

js 面向对象日历实现原理详解

对于前端开发来说,日历空间在网站里应用的很多,比如:填写表单时,是选取一下事件了--等等.下面就来分析一下怎么用js来写一个自己万年历. 在没有开始之前,我们是先弄明白是什么原理,要通过几个步骤来实现. 第一,我们的知道某一个月的某第一天是星期几. 第二,我们得知道某一个月有一共有几天, 只要有了这两部就可以循环出来了,下面看一下代码 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http

使用canvas绘制时钟并通过class面向对象

使用canvas绘制时钟并通过class面向对象 1.思路分析 钟表可分为静止的刻度和动态的指针两大部分由于指针具有动态性,必然需要定时器实时刷新清空并重绘但刻度部分如果一起清空并重绘会降低性能因此可以使用两个重叠在一起的canvas画板来分别绘制两个部分 2.绘制表盘步骤 2.1.首先获取第一个面板的上下文: var canvas1=document.getElementById("canvas1"); var ctx1=canvas1.getContext("2d&quo