效果:http://www.scarecrow.top/seeview?aid=90
代码下载:
https://gitee.com/scarecrowpqs/codes/nbo51eg7msacpzvf9whxk38
其中核心部分讲解:
1、Canvas单位问题:
<canvas id="ScarecrowCanvasId_246154" width="600" height="400" style="background-color: rgb(12, 55, 143);"></canvas>代表 宽600px高400px,他的默认单位是像素(px) (注意:不能用Css来改变canvas的宽高,因为他本身的像素分布接受CSS分配,CSS只能调整她在显示中的像素即你看到的像素,但是这样他就会拉伸或者压缩原本的Canvas)
例子:<canvas id="ScarecrowCanvasId_246154" width="600" height="400" style="background-color: rgb(12, 55, 143);width:1200px;height:800px;"></canvas>则是将Canvas的像素点放大了一倍,不是代表Canvas有横向1200个像素点,纵向800像素点。你看到的是宽1200px高800px是HTML展示的宽度,实际是宽600px高400px。
此处还有一个点注意:
你本身Canvas设计的是1000x1000但是你截图时显示的不是1000X1000,那么三种原因造成的:1、你是用CSS对Canvas进行了宽高操作。2、在我的电脑显示配置中设置了文本基于标准文字放大或缩小了一定倍数。3、浏览器进行了放大或缩小。自己在查看的时候要去验证一下。
2、代码展示
var ScarecrowGrainTime = (function(window) {
var ScarecrowGrainTime = function(el, num=800, backgroundColor = '#0C378F',size = 15, space=1) {
var num = num < 800 ? 800 : num;
if (size < 1) {
size = 1;
}
return new ScarecrowGrainTime.fn.init(el, num, size, backgroundColor, space);
}
window.requestAnimationFrame = (function () {
return window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function (callback) {
setTimeout(callback, 1000 / 60);
}
})();
ScarecrowGrainTime.fn = ScarecrowGrainTime.prototype = {
constructor: ScarecrowGrainTime,
//画布宽
canvasWidth: 0,
//画布高
canvasHeight: 0,
//画布背景颜色
canvasBackgroundColor:'#0C378F',
//附属元素
el:'',
//附属元素对象
elId:'',
//canvasID
canvasId:'',
//canvasObj
canvasObj:'',
//画板对象
canvasDrawObj:'',
//所有粒子
allGrainList:[],
//所有粒子数
grainNum:0,
//缓存所有坐标
allZb:[],
//数字大小
size:15,
//数字间间距
space:1,
//显示时间起点坐标
showX:-1,
showY:-1,
//初始化
init: function(el, num, size, backgroundColor, space) {
this.el = window.document.getElementById(el);
this.elId = el;
this.canvasWidth = parent.parseInt(this.el.clientWidth || this.el.offsetWidth);
this.canvasHeight = parent.parseInt(this.el.clientHeight || this.el.offsetHeight);
this.canvasBackgroundColor = backgroundColor;
this.canvasId = 'ScarecrowCanvasId_' + this.getRandStr();
this.grainNum = num;
this.size = size;
this.space = space;
this.size = this.canvasWidth / (9 * 8 + 5 * this.space) / 3 * 2;
},
//设置所有粒子数(如果需要调用必须在run方法之前)
setGrainNum:function(num) {
this.grainNum = num;
},
//设置数字之间间距(必须为整数且必须在run 方法之前调用)
setSpace:function(num) {
this.space = parent.parseInt(num);
},
//设置数字字体大小(必须为整数且必须在run 方法之前调用)
setSize:function(num) {
this.size = parent.parseInt(num);
},
//设置背景颜色(必须在run 方法之前调用)
setBackgroundColor:function (colorStr) {
this.canvasBackgroundColor = colorStr;
},
//设置时间的起点坐标
setShowPoint:function(x, y) {
if (x == undefined || y == undefined) {
this.showX = (this.canvasWidth - (this.size * 9 * 8 + this.size * this.space * 5)) / 2;
this.showY = (this.canvasHeight - this.size * 12) / 2;
} else {
this.showX = x > this.canvasWidth || x < 0 ? 0 : x;
this.showY = y > this.canvasHeight || x < 0 ? 0 : y;
}
},
//开始运行
run:function() {
if (this.showX == -1) {
this.setShowPoint();
}
this.createCanvas();
this.createAllGrain(this.grainNum);
var tileList = this.getNowTimeList();
this.setTime(this.showX, this.showY, tileList[0],tileList[1],tileList[2],tileList[3],tileList[4],tileList[5], ':', this.space);
this.showDongHua();
},
//创建画板
createCanvas:function () {
var canvasObj = document.createElement('canvas');
canvasObj.id = this.canvasId;
canvasObj.width = this.canvasWidth;
canvasObj.height = this.canvasHeight;
canvasObj.style.backgroundColor = this.canvasBackgroundColor;
this.canvasObj = canvasObj;
this.canvasDrawObj = canvasObj.getContext('2d');
this.el.appendChild(canvasObj);
},
//获取随机数
getRandomNum:function(x=0, y=100000) {
return parent.parseInt(Math.random() * (y - x)) + x;
},
//获取随机字符串
getRandStr:function(len = 6) {
var tempStr = "123456789abcdefghijklmopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
var relStr = "";
for(var i = 0 ; i < len; i++) {
relStr = relStr + tempStr[this.getRandomNum(0, 6)];
}
return relStr;
},
//获取随机颜色
getRandomColor:function() {
return "rgb(" + (~~(Math.random() * 255)) + "," + (~~(Math.random() * 255)) + "," + (~~(Math.random() * 255)) + ")";
},
//绘制一个粒子
createGrain:function (x = 400, y = 400, radius = 100, color='') {
this.canvasDrawObj.strokeStyle = 'rgba(0,0,0,0)';
this.canvasDrawObj.beginPath();
this.canvasDrawObj.arc(x, y, radius,0,360*Math.PI/180);
this.canvasDrawObj.stroke();
var grd=this.canvasDrawObj.createRadialGradient(x,y,radius * 0.6, x,y,radius);
grd.addColorStop(0,color == '' ? this.getRandomColor() : color);
grd.addColorStop(1,'rgba(0,0,0,0)');
this.canvasDrawObj.fillStyle=grd
this.canvasDrawObj.fill();
},
//创建所有粒子坐标信息
createAllGrain:function (num) {
var radiusStart = (this.size / 2) - 4 < 1 ? 1 : (this.size / 2) - 4;
var startEnd = this.size / 2 < 1 ? 1 : this.size / 2;
for (var i = 0; i<num; i++) {
var obj = {
x:this.getRandomNum(0, this.canvasWidth),
y:this.getRandomNum(0, this.canvasHeight),
radius:this.getRandomNum(radiusStart , startEnd),
speed:this.getRandomNum(3, 10),
toX:0,
toY:0,
color:this.getRandomColor()
};
this.allGrainList.push(obj);
}
},
//绘制所有粒子
drawAllGrain:function(){
var j = 0;
for (var i in this.allGrainList) {
if (this.allGrainList[i].x != this.allGrainList[i].toX) {
var times = Math.abs(this.allGrainList[i].toX - this.allGrainList[i].x) / this.allGrainList[i].speed;
var toY = Math.abs(this.allGrainList[i].toY - this.allGrainList[i].y) / times;
this.allGrainList[i].x = this.allGrainList[i].toX > this.allGrainList[i].x ? this.allGrainList[i].x + this.allGrainList[i].speed : this.allGrainList[i].x - this.allGrainList[i].speed;
this.allGrainList[i].y = this.allGrainList[i].toY > this.allGrainList[i].y ? this.allGrainList[i].y + toY : this.allGrainList[i].y - toY;
if (Math.abs(this.allGrainList[i].toX-this.allGrainList[i].x) < this.allGrainList[i].speed) {
this.allGrainList[i].x = this.allGrainList[i].toX;
this.allGrainList[i].y = this.allGrainList[i].toY;
j = j + 1;
}
} else {
this.allGrainList[i].x = this.allGrainList[i].toX;
this.allGrainList[i].y = this.allGrainList[i].toY;
j = j + 1;
}
this.createGrain(this.allGrainList[i].x, this.allGrainList[i].y, this.allGrainList[i].radius, this.allGrainList[i].color)
}
return j == this.grainNum ? 1 : 0;
},
//清空画板
clearDeraw:function () {
this.canvasObj.width = this.canvasWidth;
this.canvasObj.height = this.canvasHeight;
},
//开始动画
showDongHua:function () {
this.clearDeraw();
if(this.drawAllGrain() == 1) {
var tileList = this.getNowTimeList();
this.setTime(this.showX, this.showY, tileList[0],tileList[1],tileList[2],tileList[3],tileList[4],tileList[5], ':', this.space);
this.clearDeraw();
}
window.requestAnimationFrame(this.showDongHua.bind(this));
},
//获取数字模板
getShowNumList:function (num) {
switch (num) {
case 0:
return [
[0,0,1,1,1,1,1,0,0],
[0,1,1,1,1,1,1,1,0],
[1,1,0,0,0,0,0,1,1],
[1,1,0,0,0,0,0,1,1],
[1,1,0,0,0,0,0,1,1],
[1,1,0,0,0,0,0,1,1],
[1,1,0,0,0,0,0,1,1],
[1,1,0,0,0,0,0,1,1],
[1,1,0,0,0,0,0,1,1],
[1,1,0,0,0,0,0,1,1],
[0,1,1,1,1,1,1,1,0],
[0,0,1,1,1,1,1,0,0],
];
case 1:
return [
[0,0,1,1,1,1,0,0,0],
[0,1,1,1,1,1,0,0,0],
[1,1,1,1,1,1,0,0,0],
[0,0,0,1,1,1,0,0,0],
[0,0,0,1,1,1,0,0,0],
[0,0,0,1,1,1,0,0,0],
[0,0,0,1,1,1,0,0,0],
[0,0,0,1,1,1,0,0,0],
[0,0,0,1,1,1,0,0,0],
[0,0,0,1,1,1,0,0,0],
[0,1,1,1,1,1,1,1,0],
[1,1,1,1,1,1,1,1,1],
];
case 2:
return [
[0,0,1,1,1,1,1,0,0],
[0,1,1,1,1,1,1,1,0],
[1,1,0,0,0,0,0,1,1],
[1,1,0,0,0,0,0,1,1],
[0,0,0,0,0,0,1,1,1],
[0,0,0,0,0,1,1,0,0],
[0,0,0,0,1,1,0,0,0],
[0,0,0,1,1,0,0,0,0],
[0,0,1,1,0,0,0,0,0],
[0,1,1,0,0,0,0,1,1],
[1,1,1,1,1,1,1,1,1],
[1,1,1,1,1,1,1,1,1],
];
case 3:
return [
[0,1,1,1,1,1,1,1,0],
[1,1,1,1,1,1,1,1,1],
[1,1,0,0,0,0,0,1,1],
[1,1,0,0,0,0,0,1,1],
[0,0,0,0,0,0,1,1,0],
[0,0,0,0,0,1,1,0,0],
[0,0,0,0,1,1,1,0,0],
[0,0,0,0,0,1,1,0,0],
[1,1,0,0,0,0,1,1,0],
[1,1,0,0,0,0,0,1,1],
[1,1,1,1,1,1,1,1,1],
[0,1,1,1,1,1,1,1,0],
];
case 4:
return [
[0,0,0,0,0,0,1,1,0],
[0,0,0,0,0,1,1,1,0],
[0,0,0,0,1,1,1,1,0],
[0,0,0,1,1,0,1,1,0],
[0,0,1,1,0,0,1,1,0],
[0,1,1,0,0,0,1,1,0],
[1,1,0,0,0,0,1,1,0],
[1,1,1,1,1,1,1,1,1],
[1,1,1,1,1,1,1,1,1],
[0,0,0,0,0,0,1,1,0],
[0,0,0,0,0,0,1,1,0],
[0,0,0,0,0,0,1,1,0],
];
case 5:
return [
[0,1,1,1,1,1,1,1,0],
[1,1,1,1,1,1,1,1,0],
[1,1,0,0,0,0,0,0,0],
[1,1,0,0,0,0,0,0,0],
[1,1,1,1,1,1,1,1,0],
[0,1,1,1,1,1,1,1,1],
[0,0,0,0,0,0,0,1,1],
[0,0,0,0,0,0,0,1,1],
[1,1,0,0,0,0,0,1,1],
[1,1,0,0,0,0,0,1,1],
[1,1,1,1,1,1,1,1,1],
[0,1,1,1,1,1,1,1,0],
];
case 6:
return [
[0,1,1,1,1,1,1,1,0],
[1,1,1,1,1,1,1,1,1],
[1,1,0,0,0,0,0,1,1],
[1,1,0,0,0,0,0,0,0],
[1,1,0,0,0,0,0,0,0],
[1,1,1,1,1,1,1,1,0],
[1,1,1,1,1,1,1,1,1],
[1,1,0,0,0,0,0,1,1],
[1,1,0,0,0,0,0,1,1],
[1,1,0,0,0,0,0,1,1],
[1,1,1,1,1,1,1,1,1],
[0,1,1,1,1,1,1,1,0],
];
case 7:
return [
[0,1,1,1,1,1,1,1,0],
[1,1,1,1,1,1,1,1,1],
[1,1,0,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,0,1,1,0,0],
[0,0,0,0,1,1,0,0,0],
[0,0,0,0,1,1,0,0,0],
[0,0,0,0,1,1,0,0,0],
[0,0,0,0,1,1,0,0,0],
[0,0,0,0,1,1,0,0,0],
[0,0,0,0,1,1,0,0,0],
];
case 8:
return [
[0,1,1,1,1,1,1,1,0],
[1,1,1,1,1,1,1,1,1],
[1,1,0,0,0,0,0,1,1],
[1,1,0,0,0,0,0,1,1],
[1,1,0,0,0,0,0,1,1],
[0,1,1,1,1,1,1,1,0],
[0,1,1,1,1,1,1,1,0],
[1,1,0,0,0,0,0,1,1],
[1,1,0,0,0,0,0,1,1],
[1,1,0,0,0,0,0,1,1],
[1,1,1,1,1,1,1,1,1],
[0,1,1,1,1,1,1,1,0],
];
case 9:
return [
[0,1,1,1,1,1,1,1,0],
[1,1,1,1,1,1,1,1,1],
[1,1,0,0,0,0,0,1,1],
[1,1,0,0,0,0,0,1,1],
[1,1,0,0,0,0,0,1,1],
[1,1,1,1,1,1,1,1,1],
[0,1,1,1,1,1,1,1,1],
[0,0,0,0,0,0,0,1,1],
[0,0,0,0,0,0,0,1,1],
[1,1,0,0,0,0,0,1,1],
[1,1,1,1,1,1,1,1,1],
[0,1,1,1,1,1,1,1,0],
];
case ':':
return [
[0,0,0,0,0,0,0,0,0],
[0,0,1,1,1,1,1,0,0],
[0,0,1,1,1,1,1,0,0],
[0,0,1,1,1,1,1,0,0],
[0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0],
[0,0,0,0,0,0,0,0,0],
[0,0,1,1,1,1,1,0,0],
[0,0,1,1,1,1,1,0,0],
[0,0,1,1,1,1,1,0,0],
[0,0,0,0,0,0,0,0,0],
];
}
},
//设置时间
setTime:function (x=0, y=0, H1 = 0,H2 = 1,I1 = 0,I2 = 1,S1 = 0,S2 = 1,eox=':',space=5) {
var w = this.size * (9+space);
this.allZb = [];
this.setNum(H1, x + (0 * w),y);
this.setNum(H2, x + (1 * w),y);
this.setNum(eox, x + (2 * w),y);
this.setNum(I1, x + (3 * w),y);
this.setNum(I2, x + (4 * w),y);
this.setNum(eox, x + (5 * w),y);
this.setNum(S1, x + (6 * w),y);
this.setNum(S2, x + (7 * w),y);
var m = 0;
var zbNum = this.allZb.length;
for(var i in this.allGrainList) {
m = m % zbNum;
this.allGrainList[i].toX = this.allZb[m].x;
this.allGrainList[i].toY = this.allZb[m].y;
m = m + 1;
}
},
//设置一个数字
setNum:function (num, x, y) {
if (num < 0 || num > 9) {
num = 0;
}
var numList = this.getShowNumList(num);
for (var i in numList) {
for (var j in numList[i]) {
if (numList[i][j] == 1) {
this.allZb.push({
x: x + this.size * j,
y: y + this.size * i
});
}
}
}
},
//获取当前时间数组
getNowTimeList:function () {
var myDate = new Date();
var myHours = myDate.getHours();
var myMinu = myDate.getMinutes();
var mySec = myDate.getSeconds();
var relData = [parent.parseInt(myHours / 10),parent.parseInt(myHours % 10),parent.parseInt(myMinu / 10),parent.parseInt(myMinu % 10),parent.parseInt(mySec / 10),parent.parseInt(mySec % 10)];
return relData;
}
}
ScarecrowGrainTime.fn.init.prototype = ScarecrowGrainTime.fn;
return ScarecrowGrainTime;
})(window);
//挂在全局
window.$=window.ScarecrowGrainTime=ScarecrowGrainTime;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
html,body{
width: 100%;
height: 100%;
padding: 0;
margin: 0;
}
</style>
</head>
<body id="bodys">
<div style="width: 600px;height: 400px; background-color:red;display: block;margin: auto;" id="showCanvas"></div>
<script src="ScarecrowGrainTime.js"></script>
<script>
//创建对象
var obj = ScarecrowGrainTime('showCanvas');
// //设置字体大小
// obj.setSize(10);
// //设置背景颜色
// obj.setBackgroundColor('green');
// //设置字体间间距
obj.setSpace(2);
// //设置时间显示的起点坐标
// obj.setShowPoint(50,300);
// //设置粒子数
obj.setGrainNum(1500);
//开始执行
obj.run();
</script>
</body>
</html>