canvas 圆点组成的汉字闪烁,

来源:互联网 发布:学拼音打字软件下载 编辑:程序博客网 时间:2024/05/16 01:58
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();*/}//获取文字点的xyvar 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 dyfunction 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.onload=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