canvas的进阶 - 学习利用canvas做一个炫酷的倒计时功能
先给大家贴一张图片,因为我不会上传视频( ̄□ ̄||) ,请大家谅解了~ 如果有知道怎么上传视频的大神还请指点指点 ^_^ ~
然后看一下代码:
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做一个炫酷的倒计时功能的更多相关文章
- 在树莓派上用 python 做一个炫酷的天气预报
教大家如何在树莓派上自己动手做一个天气预报.此次教程需要大家有一定的python 基础,没有也没关系,文末我会放出我已写好的代码供大家下载. 首先在开始之前 需要申请高德地图API,去高德地图官网注册 ...
- 利用UIWebView打造一个炫酷的视频背景视图(OC & Swift)
http://www.cocoachina.com/ios/20151023/13860.html 2015-10-6更新:适配 Swift2.0 如有需要,可以通过pjin.elvin@gmail. ...
- 如何利用GitHub设计一个炫酷的个人网站(含代码)
1.在开始制作之前我们先预览一下我的网站吧! 1.方式一: 由于是手机版的所以用手机访问下面的链接体验比较好一点: https://tom-shushu.github.io/MyWeb.github. ...
- 教你用canvas打造一个炫酷的碎片切图效果
前言 今天分享一个炫酷的碎片式切图效果,这个其实在自己的之前的博客上有实现过,本人觉得这个效果还是挺炫酷的,这次还是用我们的canvas来实现,代码量不多,但有些地方还是需要花点时间去理解的,需要点数 ...
- 百度前端技术学院2018笔记 之 利用 CSS animation 制作一个炫酷的 Slider
前言 题目地址 利用 CSS animation 制作一个炫酷的 Slider 思路整理 首先页面包含三种东西 一个是type为radio的input其实就是单选框 二是每个单选框对应的label 三 ...
- 使用 jquery 的 上传文件插件 uploadify 3.1 配合 java 来做一个简单的文件上次功能。并且在界面上有radio 的选择内容也要上传
使用 jquery 的 上传文件插件 uploadify 3.1 配合 java 来做一个简单的文件上次功能.并且在界面上有radio 的选择内容也要上传 uploadify 插件的 下载和文档地址 ...
- 一个炫酷的Actionbar效果
今天在网上看到一个炫酷的Actionbar效果,一个老外做的DEMO,目前很多流行的app已经加入了这个效果. 当用户初始进入该界面的时候,为一个透明的 ActiionBar ,这样利用充分的空间显示 ...
- 2019基于Hexo快速搭建个人博客,打造一个炫酷博客(1)-奥怪的小栈
本文转载于:奥怪的小栈 这篇文章告诉你如何在2019快速上手搭建一个像我一样的博客:基于HEXO+Github搭建.并完成SEO优化,打造一个炫酷博客. 本站基于HEXO+Github搭建.所以你需要 ...
- Android一个炫酷的树状图组织架构图开源控件实现过程
Android一个炫酷的树状图组织架构图开源控件 文章目录 [1 简介] [2 效果展示] [3 使用步骤] [4 实现基本布局流程] [5 实现自由放缩及拖动] [6 实现添加删除及节点动画] [7 ...
随机推荐
- laravel routes除了默认路由,其他的都无效 解决方案
按照教程.该php升级到5.5,所有是开放的扩展,默认路由进入,证明代码错误,平时不开rewrite铅 假设你其它路由,localhost/文件夹/public/index.php/home能够进去. ...
- windows下Eclipse启动tomcat提示port已被占用 already in use
>netstat -ano | findstr 8009 TCP 127.0.0.1:8005 0.0.0.0:0 LISTENING ...
- 【转】NIO与传统IO的区别
转自:http://blog.csdn.net/zhouhl_cn/article/details/6568119 传统的socket IO中,需要为每个连接创建一个线程,当并发的连接数量非常巨大时, ...
- 在WPF中制作正圆形公章
原文:在WPF中制作正圆形公章 之前,我利用C#与GDI+程序制作过正圆形公章(利用C#制作公章 ,C#制作公章[续])并将它集成到一个小软件中(个性印章及公章的画法及实现),今天我们来探讨一下WPF ...
- wpf窗体定位
原文:wpf窗体定位 据WPF外包小编了解,通常,不需要在屏幕上明确定位窗口.而是简单地将WindowState属性设置为Normal,并忽略其他所有细节.另一方面,很少会将WindowStartup ...
- jquery hover()的使用
<!DOCTYPE html><html><head><meta http-equiv="Content-Type" content=&q ...
- WPF值转换器的使用
<Window x:Class="CollectionBinding.MainWindow" xmlns="http://schemas.micros ...
- surfaceview组件的surfaceCreated()不被调用的解决方案
原文:surfaceview组件的surfaceCreated()不被调用的解决方案 有时候我们有需要在native层做在surfaceview的上下文中做渲染,这个时候只是提供了一个单独什么都不做的 ...
- 从一段简单算法题来谈二叉查找树(BST)的基础算法
先给出一道很简单,喜闻乐见的二叉树算法题: 给出一个二叉查找树和一个目标值,如果其中有两个元素的和等于目标值则返回真,否则返回假. 例如: Input: 5 / \ 3 6 / \ \ 2 4 7 T ...
- PHP 实现自动加载器(Autoloader)
我们知道PHP可以实现自动加载,避免了繁重的体力活,代码更规范,整洁.那如果我们把这个自动加载再升华一下,变成自动加载类,每次只需要引入这个类,那么其他类就自动加载了,已经开源,仓库地址在这里.同时如 ...