想法是在 Canvas 上绘制由小方块组成的数字。

第一步是实现绘制小方块的方法,先画出一个边长为 5 的 10x10 个方块,使用两个 for 循环很简单就能完成。

 for (let i = 0; i < 10; i++) {
for (let j = 0; j < 10; j++) {
context.fillRect(5 * i, 5 * j, 5, 5);
}
}

效果如下:

但是这样一大块黑色不是很好看,可以把小方块的边长减一 ,有显示网格的效果,即: context.fillRect(5 * i, 5 * j, 4, 4);

效果如下:

 

接下来就是把数字转换成像素风,我的想法是创建一个数组,用 0 和 1 来表示是否填充,然后遍历数组。

如 1 为: ["0010", "0110", "0010", "0010", "0111"] ,下图所示方便理解:

 

为之前的循环增加一个判断,遍历字符串的索引判断是否要在相应位置绘制小方块。

x,y 是整个数字的原点(数字的左上角)。

 function draw_single_word(context, x, y, numberList) {
for (let i = 0; i < numberList.length; i++) {
for (let j = 0; j < numberList[i].length; j++) {
if (numberList[i][j] === "1") {
context.fillRect(x + 5 * y + j, 5 * i, 4, 4);
}
}
}
}

显示效果:

类似的其他数字也可以显示,还可以加上冒号和破折号。

 function pixelNumber(number) {
let _number = number;
switch (_number) {
case "0":
_number = ["1111", "1001", "1001", "1001", "1111"];
break;
case "1":
_number = ["0010", "0110", "0010", "0010", "0111"];
break;
case "2":
_number = ["1111", "0001", "1111", "1000", "1111"];
break;
case "3":
_number = ["1111", "0001", "1111", "0001", "1111"];
break;
case "4":
_number = ["1001", "1001", "1111", "0001", "0001"];
break;
case "5":
_number = ["1111", "1000", "1111", "0001", "1111"];
break;
case "6":
_number = ["1111", "1000", "1111", "1001", "1111"];
break;
case "7":
_number = ["1111", "0001", "0001", "0001", "0001"];
break;
case "8":
_number = ["1111", "1001", "1111", "1001", "1111"];
break;
case "9":
_number = ["1111", "1001", "1111", "0001", "1111"];
break;
case ":":
_number = ["0", "1", "0", "1", "0"];
break;
case "-":
_number = ["000", "000", "111", "000", "000"];
break;
case ".":
_number = ["0", "0", "0", "0", "1"];
break;
case " ":
_number = ["0", "0", "0", "0", "0"];
break;
}
return _number;
}

pixelNumber(number)

如下所示为数字 1-9 和 0

 

多个字符的话,可以遍历字符逐一调用刚才的 draw_single_word 函数画出。

只要在每个字符的 X 轴坐标上增加上一个字符的宽度,就可以防止几个字符重叠在一起。为了让字符不显得太挤,我增加了一个格子的宽度。

需要注意的是,我设置的 “:” 和 “-” 字符宽度只有三格,因此要在循环外创建 width 函数。

 function draw_words(context, x, y, text) {
let width = 0;
for (let i = 0; i < text.length; i++) {
let numberList = pixelNumber(text[i]);
draw_single_word(context, x + width, y, numberList);
width += (numberList[0].length + 1) * 5;
}
}

效果如下:

 

现在可以获取当前时间,并将字符绘制出来,获取当前时间的函数:

 function getTime() {
let date = new Date();
let year = date.getFullYear();
let month = zeroNumber(date.getMonth() + 1); // 注意月份默认从 0 开始,所以加一才是正确的
let day = zeroNumber(date.getDate());
let hour = zeroNumber(date.getHours());
let minutes = zeroNumber(date.getMinutes());
let seconds = zeroNumber(date.getSeconds());
return {
date: year + "-" + month + "-" + day,
time: hour + ":" + minutes + ":" + seconds
}
}

为了美观,我创建了一个 zeroNumber 函数来给不足十的数字前加一个零。

 function zeroNumber(number) {
number = number < 10 ? "0" + number : number;
return number;
}

zeroNumber(number)

 

最后,使用 requestAnimationFrame 函数让它动起来。

 function time_animate() {
ctx_animate.clearRect(0, 0, 200, 60);
draw_words(ctx_animate, 0, 0, getTime().time);
window.requestAnimationFrame(time_animate);
}
time_animate();

其实修改一下,也可显示其他东西,比如字母和简单符号。

最后贴一下我左上角的时间的代码,这是最初的版本,可能有些许问题,顺便说一句,IE不支持 class 。

 class PixelTime {
constructor(canvas) {
this.canvas = canvas;
this.context = this.canvas.getContext("2d");
this.dateShow = 1; // 是否显示年
this.timeShow = 1; // 是否显示时间
this.pixelSide = this.canvas.width < 102 ? 2 : Math.floor(this.canvas.width / 51);
}
/**
* 确定字符的点阵数组。
*/
pixelNumber(number) {
switch (number) {
case 0:
number = ["1111", "1001", "1001", "1001", "1111"];
break;
case 1:
number = ["0010", "0110", "0010", "0010", "0111"];
break;
case 2:
number = ["1111", "0001", "1111", "1000", "1111"];
break;
case 3:
number = ["1111", "0001", "1111", "0001", "1111"];
break;
case 4:
number = ["1001", "1001", "1111", "0001", "0001"];
break;
case 5:
number = ["1111", "1000", "1111", "0001", "1111"];
break;
case 6:
number = ["1111", "1000", "1111", "1001", "1111"];
break;
case 7:
number = ["1111", "0001", "0001", "0001", "0001"];
break;
case 8:
number = ["1111", "1001", "1111", "1001", "1111"];
break;
case 9:
number = ["1111", "1001", "1111", "0001", "1111"];
break;
case ":":
number = ["0", "1", "0", "1", "0"];
break;
case "-":
number = ["000", "000", "111", "000", "000"];
break;
case ".":
number = ["0", "0", "0", "0", "1"];
break;
case " ":
number = ["0", "0", "0", "0", "0"];
break;
}
return number;
} /**
* 绘制点阵。
*/
drawPixelWord(x, y, words) {
let width = 0;
for (let i = 0; i < words.length; i++) {
let word = parseInt(words[i]) || words[i] === "0" ? parseInt(words[i]) : words[i];
word = this.pixelNumber(word);
for (let r = 0; r < word.length; r++) {
for (let c = 0; c < word[r].length; c++) {
if (word[r][c] === "1") {
let side = this.pixelSide - 1;
this.context.save();
this.context.translate(x + width + this.pixelSide * 2, y + this.pixelSide * 2);
this.context.fillRect(c * (side + 1), r * (side + 1), side, side);
this.context.restore();
}
}
}
width += (1 + word[0].length) * this.pixelSide;
}
} /**
* 给个位数前面加个零,如:01
* @param number {number}
* @returns {number}
*/
zeroNumber(number) {
number = number < 10 ? "0" + number : number;
return number;
} /**
* 获取当前时间。
* @returns {{date: string, time: string}}
*/
getTime() {
let date = new Date();
let year = date.getFullYear();
let month = this.zeroNumber(date.getMonth() + 1); // 月份默认从 0 开始
let day = this.zeroNumber(date.getDate());
let hour = this.zeroNumber(date.getHours());
let minutes = this.zeroNumber(date.getMinutes());
let seconds = this.zeroNumber(date.getSeconds());
return {
date: year + "-" + month + "-" + day,
time: hour + ":" + minutes + ":" + seconds
}
} drawTime() {
this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
let now = this.getTime();
if (this.dateShow && this.timeShow) {
this.drawPixelWord(0, 0, now.date);
this.drawPixelWord(this.pixelSide * 14, this.pixelSide * 6, now.time);
} else if (this.dateShow) {
this.drawPixelWord(0, 0, now.date);
} else if (this.timeShow) {
this.drawPixelWord(0, 0, now.time);
}
}
}

PixelTime

Canvas 绘制一个像素风电子时钟的更多相关文章

  1. 使用canvas绘制一个时钟

    周末学习canvas的一些基础功能,顺带写了一个基础的时钟.现在加工一下,做的更好看一点,先放上效果图: 谈一些自己的理解: (1).要绘制一个新的样式(不想被其他样式影响,或者影响到其他样式),那么 ...

  2. HTML5 Canvas中实现绘制一个像素宽的细线

    正统的HTML5 Canvas中如下代码 ctx.lineWidth = 1; ctx.beginPath(); ctx.moveTo(10, 100); ctx.lineTo(300,100); c ...

  3. 用canvas绘制一个简易时钟

    在见识了html5中canvas的强大,笔者准备制作一个简易时钟. 下面就是成果啦,制作之前我们先分析一下,绘制一个时钟需要做哪些准备. 一 . 1.首先这个时钟分为表盘,指针(时针,分针,秒针)和数 ...

  4. HTML5 在canvas绘制一个矩形

    笔者:本笃庆军 原文地址:http://blog.csdn.net/qingdujun/article/details/32930501 一.绘制矩形 canvas使用原点(0,0)在左上角的坐标系统 ...

  5. Canvas绘制一个大鱼喂小鱼的游戏

    Canvas是HTML5中的一部分,强大的API足以让我们绘制我们任意想绘制的东西.利用Canvas的基础学习以及JavaScript面向对象的思想绘制一个小游戏,下面是源码地址https://git ...

  6. 用canvas绘制一个时钟

    实现一个时钟的绘制和时间的显示 一,首先是页面的搭建html部分以及一点点的css代码,因为css这块用的比较少,所以就没有单独出来: <!DOCTYPE html> <html l ...

  7. Canvas绘制图形

    1.Canvas绘制一个蓝色的矩形 <!DOCTYPE html> <html> <head lang="en"> <meta chars ...

  8. iOS: 如何正确的绘制1像素的线

    iOS 绘制1像素的线 一.Point Vs Pixel iOS中当我们使用Quartz,UIKit,CoreAnimation等框架时,所有的坐标系统采用Point来衡量.系统在实际渲染到设置时会帮 ...

  9. canvas绘制百分比圆环进度条

    开发项目,PM会跟踪项目进度:完成某个事情,也可以设置一个完成的进度. 这里用canvas绘制一个简单百分比圆环进度条. 看下效果: 1. 动画方式   2. 静默方式   // 贴上代码,仅供参考 ...

随机推荐

  1. MySQL远程连接和备份还原

    连接远程数据库 mysql -h 数据库地址 -P 端口号 -u 用户名 -p mysql -h -u root -p 备份数据库, 热备份 mysqldump -h 127.0.0.1 -u roo ...

  2. Qt编写气体安全管理系统12-设备双击

    一.前言 在编写这个项目的过程中,有个得到客户夸赞的小功能就是,设备按钮双击,在离线的时候是双击重连设备,在线的时候是双击弹出具体详情界面,回控设备,参数设置等.在modbus设备通信过程中,设定了超 ...

  3. ng2中 如何使用自定义属性data-id 以及赋值和取值操作

    项目环境:ng4.x 写法说明: [attr.data-nurseKey] <div [attr.data-nurseKey]="k.nurseKey"></di ...

  4. 10点睛Spring MVC4.1-全局异常处理

    10.1 全局异常处理 使用@ControllerAdvice注解来实现全局异常处理; 使用@ControllerAdvice的属性缩小处理范围 10.2 演示 演示控制器 package com.w ...

  5. git的使用学习(三)时光机穿梭

    1.版本回退 现在,你已经学会了修改文件,然后把修改提交到Git版本库,现在,再练习一次,修改readme.txt文件如下: Git is a distributed version control ...

  6. 【GStreamer开发】GStreamer基础教程13——播放速度

    目标 快进,倒放和慢放是trick模式的共同技巧,它们有一个共同点就是它们都修改了播放的速度.本教程会展示如何来获得这些效果和如何进行逐帧的跳跃.主要内容是: 如何来变换播放的速度,变快或者变慢,前进 ...

  7. simple config of webpack

    Demo1操作手册 本Demo演示进行简单配置的基本使用 准备环境 初始化环境, cd到demo目录之后, 执行如下命令: npm init -y npm install webpack webpac ...

  8. urls 视图层

    urls.py 路由层 路由与视图函数对应关系 >>> 路由层 URL配置(URLconf)就像Django 所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射 ...

  9. pytorch1.0神经网络保存、提取、加载

    pytorch1.0网络保存.提取.加载 import torch import torch.nn.functional as F # 包含激励函数 import matplotlib.pyplot ...

  10. 最详细的maven教程

    转载   https://blog.csdn.net/wymrdjm/article/details/78695956 所有用Maven管理的真实的项目都应该是分模块的,每个模块都对应着一个pom.x ...