先给大家贴一张图片,因为我不会上传视频( ̄□ ̄||) ,请大家谅解了~  如果有知道怎么上传视频的大神还请指点指点 ^_^ ~

然后看一下代码:

html部分 : 

 <!DOCTYPE html>
<html lang="en" style="height: 100%"> <head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>倒计时</title>
</head> <body style="height:96%">
<canvas id="canvas" style="height: 100%"></canvas>
</body> </html>
<script src="./digit.js"></script>

然后需要引入来控制小球位置来构成数字,来看一张图片:看到这张图片,想必大家就会明白了我们需要引入的数据结构。

看一下需要引入的digit.js的代码:

 digit = [
[
[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, 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],
], //
[
[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],
], //
[
[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, 0, 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],
], //
[
[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],
], //
[
[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],
], //
[
[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],
], //
[
[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],
], //
[
[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],
], //
[
[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],
], //
[
[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],
] // :
]

小球的位置该怎么计算呢?再来看一张图片:

js的代码我就直接粘贴出来了,大部分都已经写上注释了。大家如果还是有地方弄不明白可以去慕课网看刘宇波老师的免费教学视频再学习一下。把地址直接给你们贴出来省去大家搜索的时间。炫丽的倒计时效果Canvas绘图与动画基础

 <script>
var WINDOW_WIDTH = undefined; //画布的宽度
var WINDOW_HEIGHT = undefined; //画布的高度
var RADIUS = undefined; //小球的半径
var MARGIN_LEFT = undefined; //数字距离画布上方的距离
var MARGIN_TOP = undefined; //最左边数字距离画布左边的距离 // var endTime = new Date(2019, 5, 28, 08, 30, 30); //设置倒计时终止的时间,此处注意月份是从0开始计算,即0代表1月 var endTime = new Date();
endTime.setTime(endTime.getTime() + 3600 * 1000) //设置一小时的倒计时
var curShowTimeSecoeds = undefined; //现在倒计时有多少毫秒
var balls = []; //存储时间变化时产生的新的小球
var colors = ['#33B5E5', '#0099CC', '#AA66CC', '#9933CC', '#669900', '#FFBB33', '#FF8800', '#FF4444', '#CC0000']; window.onload = function () {
var canvas = document.getElementById('canvas'); WINDOW_WIDTH = document.body.clientWidth;
WINDOW_HEIGHT = document.body.clientHeight; MARGIN_LEFT = Math.round(WINDOW_WIDTH / 10);
MARGIN_TOP = Math.round(WINDOW_HEIGHT / 5);
RADIUS = Math.round(WINDOW_WIDTH * 4 / 5 / 119) - 1; canvas.width = WINDOW_WIDTH;
canvas.height = WINDOW_HEIGHT; if (canvas.getContext("2d")) {
var context = canvas.getContext('2d'); curShowTimeSecoeds = getCurrentShowTimeSeconds(); //定时器
setInterval(
function () {
render(context);
update();
},
50
)
} else {
alert('您的浏览器不支持canvas,请更换浏览器尝试~')
}
} function render(cxt) { //清空一下画布内容
cxt.clearRect(0, 0, WINDOW_WIDTH, WINDOW_HEIGHT); //计算需要倒计时的时分秒
var hours = parseInt(curShowTimeSecoeds / 3600);
var minutes = parseInt((curShowTimeSecoeds - hours * 3600) / 60);
var seconds = curShowTimeSecoeds % 60; //确定时分秒和冒号的数字及位置
renderDigit(MARGIN_LEFT, MARGIN_TOP, parseInt(hours / 10), cxt)
renderDigit(MARGIN_LEFT + 15 * (RADIUS + 1), MARGIN_TOP, parseInt(hours % 10), cxt)
renderDigit(MARGIN_LEFT + 32 * (RADIUS + 1), MARGIN_TOP, 10, cxt)
renderDigit(MARGIN_LEFT + 43 * (RADIUS + 1), MARGIN_TOP, parseInt(minutes / 10), cxt)
renderDigit(MARGIN_LEFT + 59 * (RADIUS + 1), MARGIN_TOP, parseInt(minutes % 10), cxt)
renderDigit(MARGIN_LEFT + 76 * (RADIUS + 1), MARGIN_TOP, 10, cxt)
renderDigit(MARGIN_LEFT + 88 * (RADIUS + 1), MARGIN_TOP, parseInt(seconds / 10), cxt)
renderDigit(MARGIN_LEFT + 104 * (RADIUS + 1), MARGIN_TOP, parseInt(seconds % 10), cxt) //绘制时分秒和冒号的小球的
for (var i = 0; i < balls.length; i++) {
cxt.fillStyle = balls[i].color; cxt.beginPath();
cxt.arc(balls[i].x, balls[i].y, RADIUS, 0, 2 * Math.PI, true);
cxt.closePath(); cxt.fill();
}
} //画时分秒上的小球
function renderDigit(x, y, num, cxt) { cxt.fillStyle = 'rgb(0,102,153)'; for (var i = 0; i < digit[num].length; i++) {
for (var j = 0; j < digit[num][i].length; j++) {
if (digit[num][i][j] === 1) {
cxt.beginPath();
cxt.arc(x + j * 2 * (RADIUS + 1) + (RADIUS + 1), y + i * 2 * (RADIUS + 1) + (RADIUS + 1), RADIUS, 0, 2 * Math.PI);
cxt.closePath(); cxt.fill();
}
}
}
} //计算倒计时的时间
function getCurrentShowTimeSeconds() {
var curTime = new Date(); //当前时间
var ret = endTime.getTime() - curTime.getTime(); //截止时间-当前时间
ret = Math.round(ret / 1000); //需要倒计时的时间 秒 return ret >= 0 ? ret : 0; // //时钟效果
// var ret = curTime.getHours() * 3600 + curTime.getMinutes() * 60 + curTime.getSeconds(); return ret; } //时间发生倒计时的函数
function update() { //下一次显示的时间
var nextShowTimeSeconds = getCurrentShowTimeSeconds(); var nextHours = parseInt(nextShowTimeSeconds / 3600);
var nextMinutes = parseInt((nextShowTimeSeconds - nextHours * 3600) / 60);
var nextSeconds = nextShowTimeSeconds % 60; //现在显示的时间
var curHours = parseInt(curShowTimeSecoeds / 3600);
var curMinutes = parseInt((curShowTimeSecoeds - curHours * 3600) / 60);
var curSeconds = curShowTimeSecoeds % 60; //如果时间发生改变就会在相应位置产生新的彩色小球
if (nextShowTimeSeconds !== curShowTimeSecoeds) { if (parseInt(curHours / 10) !== parseInt(nextHours / 10)) {
addBalls(MARGIN_LEFT + 0, MARGIN_TOP, parseInt(nextHours / 10));
}
if (parseInt(curHours % 10) !== parseInt(nextHours % 10)) {
addBalls(MARGIN_LEFT + 15 * (RADIUS + 1), MARGIN_TOP, parseInt(nextHours % 10));
} if (parseInt(curMinutes / 10) !== parseInt(nextMinutes / 10)) {
addBalls(MARGIN_LEFT + 43 * (RADIUS + 1), MARGIN_TOP, parseInt(nextMinutes / 10));
}
if (parseInt(curMinutes % 10) !== parseInt(nextMinutes % 10)) {
addBalls(MARGIN_LEFT + 59 * (RADIUS + 1), MARGIN_TOP, parseInt(nextMinutes % 10));
} if (parseInt(curSeconds / 10) !== parseInt(nextSeconds / 10)) {
addBalls(MARGIN_LEFT + 88 * (RADIUS + 1), MARGIN_TOP, parseInt(nextSeconds / 10));
}
if (parseInt(curSeconds % 10) !== parseInt(nextSeconds % 10)) {
addBalls(MARGIN_LEFT + 104 * (RADIUS + 1), MARGIN_TOP, parseInt(nextSeconds % 10));
} curShowTimeSecoeds = nextShowTimeSeconds; }
//产生的彩色小球的运动
updateBalls(); } //产生的彩色小球运动的函数
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 >= WINDOW_HEIGHT - RADIUS) {
balls[i].y = WINDOW_HEIGHT - RADIUS;
balls[i].vy = -balls[i].vy * 0.75;
}
} //优化 小球如果滚出画布就取消这些小球
var cnt = 0;
for (var i = 0; i < balls.length; i++) {
if (balls[i].x + RADIUS > 0 && balls[i].x - RADIUS < WINDOW_WIDTH) {
balls[cnt++] = balls[i]
}
} //为了确保性能可以定义一下最多产生多少彩色小球
while (balls.length > Math.min(2000, cnt)) {
balls.pop();
}
} //时间发生变化的时候产生新的彩色小球的函数
function addBalls(x, y, num) {
for (var i = 0; i < digit[num].length; i++) {
for (var j = 0; j < digit[num][i].length; j++) {
if (digit[num][i][j] === 1) {
var aBall = {
x: x + j * 2 * (RADIUS + 1) + (RADIUS + 1),
y: y + i * 2 * (RADIUS + 1) + (RADIUS + 1),
g: 1.5 + Math.random(),
vx: Math.pow(-1, Math.ceil(Math.random() * 1000)) * 4,
vy: Math.pow(-1, Math.ceil(Math.random() * 1000)) * 4,
color: colors[Math.floor(Math.random() * colors.length)]
}
balls.push(aBall)
}
}
}
// console.log(balls.length)
} </script>

canvas的进阶 - 学习利用canvas做一个炫酷的倒计时功能的更多相关文章

  1. 在树莓派上用 python 做一个炫酷的天气预报

    教大家如何在树莓派上自己动手做一个天气预报.此次教程需要大家有一定的python 基础,没有也没关系,文末我会放出我已写好的代码供大家下载. 首先在开始之前 需要申请高德地图API,去高德地图官网注册 ...

  2. 利用UIWebView打造一个炫酷的视频背景视图(OC & Swift)

    http://www.cocoachina.com/ios/20151023/13860.html 2015-10-6更新:适配 Swift2.0 如有需要,可以通过pjin.elvin@gmail. ...

  3. 如何利用GitHub设计一个炫酷的个人网站(含代码)

    1.在开始制作之前我们先预览一下我的网站吧! 1.方式一: 由于是手机版的所以用手机访问下面的链接体验比较好一点: https://tom-shushu.github.io/MyWeb.github. ...

  4. 教你用canvas打造一个炫酷的碎片切图效果

    前言 今天分享一个炫酷的碎片式切图效果,这个其实在自己的之前的博客上有实现过,本人觉得这个效果还是挺炫酷的,这次还是用我们的canvas来实现,代码量不多,但有些地方还是需要花点时间去理解的,需要点数 ...

  5. 百度前端技术学院2018笔记 之 利用 CSS animation 制作一个炫酷的 Slider

    前言 题目地址 利用 CSS animation 制作一个炫酷的 Slider 思路整理 首先页面包含三种东西 一个是type为radio的input其实就是单选框 二是每个单选框对应的label 三 ...

  6. 使用 jquery 的 上传文件插件 uploadify 3.1 配合 java 来做一个简单的文件上次功能。并且在界面上有radio 的选择内容也要上传

    使用 jquery 的 上传文件插件 uploadify 3.1 配合 java 来做一个简单的文件上次功能.并且在界面上有radio 的选择内容也要上传 uploadify 插件的 下载和文档地址  ...

  7. 一个炫酷的Actionbar效果

    今天在网上看到一个炫酷的Actionbar效果,一个老外做的DEMO,目前很多流行的app已经加入了这个效果. 当用户初始进入该界面的时候,为一个透明的 ActiionBar ,这样利用充分的空间显示 ...

  8. 2019基于Hexo快速搭建个人博客,打造一个炫酷博客(1)-奥怪的小栈

    本文转载于:奥怪的小栈 这篇文章告诉你如何在2019快速上手搭建一个像我一样的博客:基于HEXO+Github搭建.并完成SEO优化,打造一个炫酷博客. 本站基于HEXO+Github搭建.所以你需要 ...

  9. Android一个炫酷的树状图组织架构图开源控件实现过程

    Android一个炫酷的树状图组织架构图开源控件 文章目录 [1 简介] [2 效果展示] [3 使用步骤] [4 实现基本布局流程] [5 实现自由放缩及拖动] [6 实现添加删除及节点动画] [7 ...

随机推荐

  1. Matlab使用鼠标标注图像位置并返回坐标(标注图像ROI)

    代码 function ROI=LabelBox(filename) Mat=imread(filename); imshow(Mat); mouse=imrect; pos=getPosition( ...

  2. url参数解析

    http://happycoder.net/parse-querystring-using-regexp/ http://www.cnblogs.com/babycool/p/3169058.html ...

  3. 浏览器兼容性之ECMAScript

    1 IE中不能操作TR标签的innnerHTML. 2 日期处理函数不一致. (1)IE 8- new Date().getYear()返回的是到当前日期到1900年的差值,FF返回的是当前的年. ( ...

  4. Unity3d报告奇怪的错误CompareBaseObjectsInternal can only be called from the main thread.

    其中使用了该项目.NET的Async Socket代码.后来不知道什么时候这个奇怪的错误的出现: CompareBaseObjectsInternal can only be called from ...

  5. QList介绍(QList比QVector更快,这是由它们在内存中的存储方式决定的。QStringList是在QList的基础上针对字符串提供额外的函数。at()操作比操作符[]更快,因为它不需要深度复制)非常实用

    FROM:http://apps.hi.baidu.com/share/detail/33517814 今天做项目时,需要用到QList来存储一组点.为此,我对QList类的说明进行了如下翻译. QL ...

  6. uwp - 控件精确移动动画

    原文:uwp - 控件精确移动动画 先看效果图: 一共有8个GRID,黄色的负责移动,其他7个负责定位.新建一个页面page,替换默认代码: <UserControl.Resources> ...

  7. Java文件运用

    1.使用java修改文件内容: package fileopt; import java.io.BufferedReader; import java.io.BufferedWriter; impor ...

  8. C ++ 17 技术上已经完成,C ++ 20 也在路上(有路线图)

    在前不久结束的冬季 ISO C ++标准会议(Kona)上,C ++ 17 宣布在技术上已完成,仅剩下一些 ISO 相关的繁文缛节,即将提交至最终的 ISO 投票表决.该会议由 Plum Hall 和 ...

  9. WPF里的一些Effect特效

    原文:WPF里的一些Effect特效 Blend的特效都在Microsoft.Expression.Media.Effects里,用之前添加一下引用. 可以在前台选中对象后直接点击Effect新建一种 ...

  10. 2015微软创新杯Imaginecup正在进行参赛(报名截止日期2014年12月31日本23:59)

    CSDN高校俱乐部与微软官方合作,2015微软创新杯大赛中国区官网落户CSDN高校俱乐部:http://student.csdn.net/mcs/imaginecup2015 在微软官方设置创新杯中国 ...