JS+Canvas实现动态时钟效果

 更新时间:2021年10月12日 11:08:17   作者:javscp_q  
这篇文章主要为大家详细介绍了JS+Canvas实现动态时钟效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

基于Canvas制作的动态时钟demo,供大家参考,具体内容如下

<!DOCTYPE html>
<html>
 <head>
  <meta charset="utf-8">
  <title>动态时钟</title>
  <script type="text/javascript" src="js/lattice.js"></script>
  <script type="text/javascript" src="js/script.js"></script>
  <style type="text/css">
   *{
    padding: 0;
    margin: 0;
   }
   #canvasBox{
    border-width: 2px;
    border-color: black;
    border-style: solid;
    width: 80%;
    margin: 0 auto;
   }
  </style>
 </head>
 <body>
  <!-- 将canvas放到一个盒子中,用盒子控制canvas的位置 -->
  <div id="canvasBox">
   <canvas id="canvas">
    此浏览器不支持canvas
   </canvas>
  </div>
 </body>
</html>

lattice.js

lattice =
    [
        [
            [0,0,1,1,1,0,0],
            [0,1,1,0,1,1,0],
            [1,1,0,0,0,1,1],
            [1,1,0,0,0,1,1],
            [1,1,0,0,0,1,1],
            [1,1,0,0,0,1,1],
            [1,1,0,0,0,1,1],
            [1,1,0,0,0,1,1],
            [0,1,1,0,1,1,0],
            [0,0,1,1,1,0,0]
        ],//0
        [
            [0,0,0,1,1,0,0],
            [0,1,1,1,1,0,0],
            [0,0,0,1,1,0,0],
            [0,0,0,1,1,0,0],
            [0,0,0,1,1,0,0],
            [0,0,0,1,1,0,0],
            [0,0,0,1,1,0,0],
            [0,0,0,1,1,0,0],
            [0,0,0,1,1,0,0],
            [1,1,1,1,1,1,1]
        ],//1
        [
            [0,1,1,1,1,1,0],
            [1,1,0,0,0,1,1],
            [0,0,0,0,0,1,1],
            [0,0,0,0,1,1,0],
            [0,0,0,1,1,0,0],
            [0,0,1,1,0,0,0],
            [0,1,1,0,0,0,0],
            [1,1,0,0,0,0,0],
            [1,1,0,0,0,1,1],
            [1,1,1,1,1,1,1]
        ],//2
        [
            [1,1,1,1,1,1,1],
            [0,0,0,0,0,1,1],
            [0,0,0,0,1,1,0],
            [0,0,0,1,1,0,0],
            [0,0,1,1,1,0,0],
            [0,0,0,0,1,1,0],
            [0,0,0,0,0,1,1],
            [0,0,0,0,0,1,1],
            [1,1,0,0,0,1,1],
            [0,1,1,1,1,1,0]
        ],//3
        [
            [0,0,0,0,1,1,0],
            [0,0,0,1,1,1,0],
            [0,0,1,1,1,1,0],
            [0,1,1,0,1,1,0],
            [1,1,0,0,1,1,0],
            [1,1,1,1,1,1,1],
            [0,0,0,0,1,1,0],
            [0,0,0,0,1,1,0],
            [0,0,0,0,1,1,0],
            [0,0,0,1,1,1,1]
        ],//4
        [
            [1,1,1,1,1,1,1],
            [1,1,0,0,0,0,0],
            [1,1,0,0,0,0,0],
            [1,1,1,1,1,1,0],
            [0,0,0,0,0,1,1],
            [0,0,0,0,0,1,1],
            [0,0,0,0,0,1,1],
            [0,0,0,0,0,1,1],
            [1,1,0,0,0,1,1],
            [0,1,1,1,1,1,0]
        ],//5
        [
            [0,0,0,0,1,1,0],
            [0,0,1,1,0,0,0],
            [0,1,1,0,0,0,0],
            [1,1,0,0,0,0,0],
            [1,1,0,1,1,1,0],
            [1,1,0,0,0,1,1],
            [1,1,0,0,0,1,1],
            [1,1,0,0,0,1,1],
            [1,1,0,0,0,1,1],
            [0,1,1,1,1,1,0]
        ],//6
        [
            [1,1,1,1,1,1,1],
            [1,1,0,0,0,1,1],
            [0,0,0,0,1,1,0],
            [0,0,0,0,1,1,0],
            [0,0,0,1,1,0,0],
            [0,0,0,1,1,0,0],
            [0,0,1,1,0,0,0],
            [0,0,1,1,0,0,0],
            [0,0,1,1,0,0,0],
            [0,0,1,1,0,0,0]
        ],//7
        [
            [0,1,1,1,1,1,0],
            [1,1,0,0,0,1,1],
            [1,1,0,0,0,1,1],
            [1,1,0,0,0,1,1],
            [0,1,1,1,1,1,0],
            [1,1,0,0,0,1,1],
            [1,1,0,0,0,1,1],
            [1,1,0,0,0,1,1],
            [1,1,0,0,0,1,1],
            [0,1,1,1,1,1,0]
        ],//8
        [
            [0,1,1,1,1,1,0],
            [1,1,0,0,0,1,1],
            [1,1,0,0,0,1,1],
            [1,1,0,0,0,1,1],
            [0,1,1,1,0,1,1],
            [0,0,0,0,0,1,1],
            [0,0,0,0,0,1,1],
            [0,0,0,0,1,1,0],
            [0,0,0,1,1,0,0],
            [0,1,1,0,0,0,0]
        ],//9
        [
            [0,0,0,0],
            [0,0,0,0],
            [0,1,1,0],
            [0,1,1,0],
            [0,0,0,0],
            [0,0,0,0],
            [0,1,1,0],
            [0,1,1,0],
            [0,0,0,0],
            [0,0,0,0]
        ]//:
    ];

script.js

var CANVAS_WIDTH;
var CANVAS_HEIGHT = 600;
//设置点阵中圆的半径
var RADIUS = 8;
//设置时钟距离边框的位置
var MARGIN_LEFT = 100;
var MARGIN_TOP = 40;
 
//获取初始状态的时间
var time = new Date();
var hours = time.getHours();
var minutes = time.getMinutes();
var seconds = time.getSeconds();
 
//用于存储小球对象
var balls = [];
//小球颜色
var colors = ["red","orenge","yellow","green","blue","purple","pink"]
 
window.onload = function(){
 //获得canvas外部盒子的宽度,使canvas与外部盒子宽度相同
 var canvasBox = document.getElementById("canvasBox");
 var boxWidth = getComputedStyle(canvasBox,null);
 CANVAS_WIDTH = parseInt(boxWidth.width);
 
 //设置canvas宽高并获得画笔对象
 var canvas = document.getElementById("canvas");
 canvas.width = CANVAS_WIDTH;
 canvas.height = CANVAS_HEIGHT;
 var context = canvas.getContext("2d");
 
 //定时调用,50毫秒调用一次
 setInterval(function(){
  //绘制函数
  draw(context);
 },50);
 
 function draw(ctx){
  //刷新屏幕
  ctx.clearRect(0,0,CANVAS_WIDTH,CANVAS_HEIGHT);
  
  //获取当前时间
  var curTime = new Date();
  var curHours = curTime.getHours();
  var curMinutes = curTime.getMinutes();
  var curSeconds = curTime.getSeconds();
 
  //画小时
  drawLattice(MARGIN_LEFT,MARGIN_TOP,parseInt(curHours/10),ctx);
  drawLattice(MARGIN_LEFT+15*(RADIUS+1),MARGIN_TOP,parseInt(curHours%10),ctx);
  //画冒号
  drawLattice(MARGIN_LEFT+30*(RADIUS+1),MARGIN_TOP,10,ctx);
  //画分钟
  drawLattice(MARGIN_LEFT+39*(RADIUS+1),MARGIN_TOP,parseInt(curMinutes/10),ctx);
  drawLattice(MARGIN_LEFT+54*(RADIUS+1),MARGIN_TOP,parseInt(curMinutes%10),ctx);
  //画冒号
  drawLattice(MARGIN_LEFT+69*(RADIUS+1),MARGIN_TOP,10,ctx);
  //画秒
  drawLattice(MARGIN_LEFT+78*(RADIUS+1),MARGIN_TOP,parseInt(curSeconds/10),ctx);
  drawLattice(MARGIN_LEFT+93*(RADIUS+1),MARGIN_TOP,parseInt(curSeconds%10),ctx);
  
  //更新时间并绘制小球
  update(context,curHours,curMinutes,curSeconds);
  
  //观察小球数量
  //console.log(balls.length);
 }
 
 //参数:
 //x:绘制数字点阵的左上角的横坐标
 //y:绘制数字点阵的左上角的纵坐标
 //num:要绘制的数字,实际上是lattice的索引,10表示冒号
 //ctx:画笔
 function drawLattice(x,y,num,ctx){
  for(var i=0;i<lattice[num].length;i++){
   for(var j=0;j<lattice[num][i].length;j++){
    if(lattice[num][i][j]==1){
     ctx.beginPath();
     ctx.fillStyle = "blue";
     ctx.arc(x+j*2*(RADIUS+1)+(RADIUS+1),y+i*2*(RADIUS+1)+(RADIUS+1),RADIUS,0,2*Math.PI);
     ctx.fill();
     ctx.closePath();
    }
   }
  }
 }
 
 //更新时间并绘制小球
 function update(ctx,curHours,curMinutes,curSeconds){
  if(seconds!=curSeconds){
   //更新小时
   if(parseInt(curHours/10)!=parseInt(hours/10)){
    addBalls(MARGIN_LEFT,MARGIN_TOP,parseInt(curHours/10));
   }
   if(parseInt(curHours%10)!=parseInt(hours%10)){
    addBalls(MARGIN_LEFT+15*(RADIUS+1),MARGIN_TOP,parseInt(curHours%10));
   }
   //更新分钟
   if(parseInt(curMinutes/10)!=parseInt(minutes/10)){
    addBalls(MARGIN_LEFT+39*(RADIUS+1),MARGIN_TOP,parseInt(curMinutes/10));
   }
   if(parseInt(curMinutes%10)!=parseInt(minutes%10)){
    addBalls(MARGIN_LEFT+54*(RADIUS+1),MARGIN_TOP,parseInt(curMinutes%10));
   }
   //更新秒
   if(parseInt(curSeconds/10)!=parseInt(seconds/10)){
    addBalls(MARGIN_LEFT+78*(RADIUS+1),MARGIN_TOP,parseInt(curSeconds/10));
   }
   if(parseInt(curSeconds%10)!=parseInt(seconds%10)){
    addBalls(MARGIN_LEFT+93*(RADIUS+1),MARGIN_TOP,parseInt(curSeconds%10));
   }
   
   //更新所有时间
   hours = curHours;
   minutes = curMinutes;
   seconds = curSeconds;
  }
  //绘制小球
  drawBalls(ctx);
  //更新小球运动
  updateBalls();
 }
 
 //添加单个小球
 //参数:
 //x:小球的横坐标
 //y:小球的纵坐标
 //num:变化的时间数字
 function addBalls(x,y,num){
  for(var i=0;i<lattice[num].length;i++){
   for(var j=0;j<lattice[num][i].length;j++){
    if(lattice[num][i][j]==1){
     //添加一个小球对象
     var ball = {
      //坐标
      x:x+j*2*(RADIUS+1)+(RADIUS+1),
      y:y+i*2*(RADIUS+1)+(RADIUS+1),
      //重力加速度
      g:1.5+Math.random(),
      //x、y方向的速度
      vx:Math.pow(-1,Math.ceil(Math.random()*1000))*5,
      vy:-5,
      //小球颜色
      color:colors[Math.floor(Math.random()*colors.length)]
     }
     //将小球添加进储存队列中
     balls.push(ball);
    }
   }
  }
 }
 
 //绘制小球
 function drawBalls(ctx){
  for(var i=0;i<balls.length;i++){
   ctx.beginPath();
   ctx.fillStyle = balls[i].color;
   ctx.arc(balls[i].x,balls[i].y,RADIUS,0,2*Math.PI,true);
   ctx.fill();
   ctx.closePath();
  }
 }
 
 //更新小球运动
 function updateBalls(){
  //更新储存数组中的小球的动态
  for(var i=0;i<balls.length;i++){
   balls[i].x += balls[i].vx;
   balls[i].y += balls[i].vy;
   balls[i].vy += balls[i].g;
   
   //边缘碰撞检测
   if(balls[i].y>=CANVAS_HEIGHT-RADIUS){
    balls[i].y=CANVAS_HEIGHT-RADIUS;
    //模拟碰撞反弹和阻力
    balls[i].vy=-balls[i].vy*0.6;
   }
  }
  //当小球滚出画布便可以从数组中删除,以下是删除算法
  //储存应当保留的小球的数量
  var numBall = 0;
  for(var i=0;i<balls.length;i++){
   if(balls[i].x+RADIUS>0&&balls[i].x-RADIUS<CANVAS_WIDTH){
    //若判断当前小球在屏幕内,则将此小球尽量靠前,则每次循环后,数组最后面的小球就是滚出画布的小球
    balls[numBall] = balls[i];
    numBall++;
   }
  }
  //从数组后面删除小球
  while(balls.length>numBall){
   balls.pop();
  }
 }
};

效果图:

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • 详解JavaScript设计模式中的享元模式

    详解JavaScript设计模式中的享元模式

    享元模式是一种用于性能优化的模式。享元模式的核心是运用共享技术来有效支持大量细粒度的对象.如果系统中创建了大量类似的对象而导致内存占用过高,本文通过介绍书中文件上传的优化案例来说明享元模式的使用方式和作用,需要的朋友可以参考下
    2023-06-06
  • Json按某个键的值进行排序

    Json按某个键的值进行排序

    这篇文章主要介绍了json按某个键的值进行排序的相关资料,代码简单易懂,非常不错,需要的朋友可以参考下
    2016-12-12
  • 详谈ES6中的迭代器(Iterator)和生成器(Generator)

    详谈ES6中的迭代器(Iterator)和生成器(Generator)

    下面小编就为大家带来一篇详谈ES6中的迭代器(Iterator)和生成器(Generator)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-07-07
  • 有关文件上传 非ajax提交 得到后台数据问题

    有关文件上传 非ajax提交 得到后台数据问题

    本文给大家介绍关于文件上传非ajax提交得到后台数据的问题我们该怎么处理呢?下文给大家介绍的非常详细,感兴趣的朋友一起看看吧
    2016-10-10
  • 在uniapp中如何去掉一些不想要的权限

    在uniapp中如何去掉一些不想要的权限

    在uniapp中,云打包以后会自动增加一个电话权限,并且在manifest.json里面也没有添加这个权限,怎么添加都添加不上,下面小编给大家分享在uniapp中如何去掉一些不想要的权限,感兴趣的朋友跟随小编一起看看吧
    2024-03-03
  • Javascript实现hashcode函数实现对象比较与原理说明

    Javascript实现hashcode函数实现对象比较与原理说明

    在JavaScript中,数值的比较是比较简单的,使用相等(==)和全等(===)符号基本上可以解决大多数非对象的比较。但是相等(==)和全等(===)符号在对象 object 的比较上,就不能满足所有的要求了
    2023-06-06
  • js实现下一页页码效果

    js实现下一页页码效果

    本文主要介绍了js实现下一页页码效果的实例,具有很好的参考价值。下面跟着小编一起来看下吧
    2017-03-03
  • 浅谈js构造函数的方法与原型prototype

    浅谈js构造函数的方法与原型prototype

    下面小编就为大家带来一篇浅谈js构造函数的方法与原型prototype。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-07-07
  • JavaScript设计模式之工厂模式和构造器模式

    JavaScript设计模式之工厂模式和构造器模式

    这篇文章主要介绍了JavaScript设计模式之工厂模式和构造器模式,本文同时讲解了设计模式的类别如创建型设计模式、结构型设计模式、行为设计模式等内容,需要的朋友可以参考下
    2015-02-02
  • es6函数之箭头函数用法实例详解

    es6函数之箭头函数用法实例详解

    这篇文章主要介绍了es6函数之箭头函数用法,结合实例形式详细分析了es6箭头函数基本功能、原理、用法及操作注意事项,需要的朋友可以参考下
    2020-04-04

最新评论