canvas 圆点组成的汉字闪烁,

var can1=document.querySelector('#canvas1');
			var ctx1=can1.getContext('2d');
			var w=can1.width;
			var h=can1.height;
			var texts=["明星", "深爱", "小云", "直到", "永远"];
			var font="bold 40px arial"
			//texts=['I','LOVE','XIAO','YUN'];
			//font="40px arial"
			var index=0;
			
			var num=1500;
			var z=Math.sqrt(w*h/1500)
			var points=[];	
			var length=1500;
			
			var can2=document.createElement('canvas');
			can2.width=w;
			can2.height=h;
			var ctx2=can2.getContext('2d');
			//生成圆点
			function setpoints(){
				for(var i=0;i<num;i++){				
					points.push(new setcil(i));	
				}			
			}			
			function setcil(i){
				this.r = Math.round(Math.random() * 255 | 0);
				this.g = Math.round(Math.random() * 255 | 0);
				this.b = Math.round(Math.random() * 255 | 0);
				this.a =Math.random()*1;
				this.a=this.a.toFixed(2);
				this.x=(i*z)%w;
				this.y=(i*z)/w*z;
				this.offset=Math.random()*600;
				this.radius=Math.random()*8+0.1;
				this.state=true;
				
				/*ctx1.beginPath();
				ctx1.fillStyle='#000';
				ctx1.arc(this.x,this.y,this.radius,0,Math.PI*2);
				ctx1.fill();*/
			}
			
			//获取文字点的xy
			var textdata=[];
			function settextdata(){
				var tx=texts[index];
				if(index<texts.length-1){
					index+=1;
				}else{
					index=0;
				}
				//设置背景写字
				ctx2.fillStyle="#000";
				ctx2.fillRect(0,0,w,h);
				ctx2.fillStyle="#f00";
				ctx2.font=font;
				//ctx1.textAlign="center"//文字水平居中对齐
				ctx2.fillText(tx,20,60);
				
				//获取rgba数组值  得到红字的点x y 
				var imgdata=ctx2.getImageData(0,0,w,h).data;
				textdata=[];
				for(var i=0;i<imgdata.length;i+=4){
					if(imgdata[i] !=0  )  {
						var a={
							x:i/4%w*8,
							y:i/4/w*8	
						}
						textdata.push(a);
						/*ctx2.beginPath();
						ctx2.fillStyle='#fff';
						ctx2.arc(a.x,a.y,1,0,Math.PI*2);
						ctx2.fill();*/
					}
				}
				console.log(textdata.length)
				if(textdata.length<1500){
					length=textdata.length;
				}else{
					length=1500;
				}
				getdx();				
			}
			//计算圆点最终显示的dx dy
			function getdx(){
				for(var i=0;i<points.length;i++){
					var pa=points[i];
					var txts=[];
					var ind=0;
					if(textdata.length){
						for(var n=0;n<textdata.length;n++){
							var po=textdata[n];
							txts[n]=Math.sqrt( (pa.x-po.x)*(pa.x-po.x) + (pa.y-po.y)*(pa.y-po.y) );
							if(n>0){
								if(txts[n]<=txts[ind]){
									ind=n;
								}
							}
						}
						points[i].dx=textdata[ind].x;
						points[i].dy=textdata[ind].y;						
						textdata.splice(ind,1)
					}					
				}
			}
			function draw(){
				var now=Date.now();
				ctx1.globalCompositeOperation = "source-over";
				//设置填充为黑色并绘制全屏矩形
				ctx1.fillStyle = '#000';
				ctx1.fillRect(0, 0, w, w)
				//设置重叠样式,重复区域颜色相加
				ctx1.globalCompositeOperation = "lighter";
				for(var i=0;i<length;i++){
					var p=points[i];
					if(p.x==0){
						continue;
					}
					ctx1.beginPath();
					//ctx1.fillStyle="#fff";
					p.a=1;
					ctx1.fillStyle='rgba('+p.r+','+p.g+','+p.b+','+p.a+')';					
					var mod=(p.offset+now)%600/600;
					mod=Math.sin(mod*Math.PI);
					ctx1.arc(p.x,p.y,p.radius*mod,0,Math.PI*2);
					ctx1.fill();
					p.x+=(p.dx-p.x)/10;
					p.y+=(p.dy-p.y)/10;
				}
			}
			window.οnlοad=function(){
				setpoints();
				settextdata();
				//draw();
				setInterval(draw,30)
				setInterval(settextdata,4000)
			}
			
以上是原码

一、获取文字每个像素的xy:

在canvas上写字,字颜色不要和背景一样。

通过getImageData来获取画板每个点的rgba组成的数组

我们来分析这些数组颜色

I是加4的

可以判断 r g b 也就是i i+1 i+2 它们的颜色。

当条件满足时获取这时x y 并乘以数来放大点。

二、生成圆对象数组

圆 的个数需要固定,循环生成对象并存在数组里。

我们最先把这些圆 点平分在画板上。

需要算出每个点的xy的间隔

canvas的面积/点数 得到某面积内的一个点,开根就是长宽值内的点

圆 对象需要有rgb a 三个255内一个1内的随机数。

还需要8内的半径,和offset 值600内随机数

三、计算圆对象离哪个点最近。得到所有圆显示结果的xy

for 循环圆数组

得到当前圆对象,创建数组,循环所有点,判断这些点哪个和圆最近。

设置dy dx 也就是圆最后显示x y 

然后删除这个点。这样一直循环下去。

判断两点的最短距离就是直线。

我们在两点间画直线,两点延长线上会有一个点交接。

三点组成垂直三角形。

最短距离是斜边。

a*a+b*b=c*c

根据这个来得到c的值。

四、每隔30ms渲染一次画板,计算每个点的新x y 和半径

循环圆数组

beginPath()开始画圆

设置fillStyle 也就是rgba

创建mod 它是圆半径

用offset+当前时间 % 600 /600 得到的值 是0-1  0-1 

半径不能是小大 再从小到大这样不是闪烁的效果。

需要是0-1 1-0这样的。

这里用到了math.sin(0-3)  结果就是小大大小这样的值。

画圆。

p.x+=(p.dx-p.x)/10;
p.y+=(p.dy-p.y)/10;

算下一次新的xy。







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值