给星空线条模糊效果

时间:2019-05-18 20:23:18

标签: javascript html5-canvas

我已经创建了这个星空画布和动画,并且都按预期工作。但是,正如您在此环绕效果中看到的那样,线条是相当粗的直线,因此它们看起来不太现实。我希望这些行看起来更像本示例中的行。

https://www.shadertoy.com/view/Xdl3D2

但是我不知道如何使它工作。我对html5 canvas动画很陌生。有人可以帮我使这些行看起来更像上面的示例。预先感谢。

window.requestAnimationFrame=window.requestAnimationFrame||(function(callback,element){setTimeout(callback,1000/60);});

function timeStamp(){
	if(window.performance.now)return window.performance.now(); else return Date.now();
}

function isVisible(el){
	var r = el.getBoundingClientRect();
	return r.top+r.height >= 0 &&r.left+r.width >= 0 &&r.bottom-r.height <= (window.innerHeight || document.documentElement.clientHeight) && r.right-r.width <= (window.innerWidth || document.documentElement.clientWidth);
}

function Star(x,y,z){
	this.x=x;
	this.y=y;
	this.z=z;
	this.size=0.5+Math.random();
}

function WarpSpeed(targetId,config){
	this.targetId=targetId;
	if(WarpSpeed.RUNNING_INSTANCES==undefined)WarpSpeed.RUNNING_INSTANCES={};
	if(WarpSpeed.RUNNING_INSTANCES[targetId]){WarpSpeed.RUNNING_INSTANCES[targetId].destroy();}
	config=config||{};
	if(typeof config == "string")try{config=JSON.parse(config);}catch(e){config={}}
	this.SPEED=config.speed==undefined||config.speed<0?0.7:config.speed;
	this.TARGET_SPEED=config.targetSpeed==undefined||config.targetSpeed<0?this.SPEED:config.targetSpeed;
	this.SPEED_ADJ_FACTOR=config.speedAdjFactor==undefined?0.03:config.speedAdjFactor<0?0:config.speedAdjFactor>1?1:config.speedAdjFactor;
	this.DENSITY=config.density==undefined||config.density<=0?0.7:config.density;
	this.USE_CIRCLES=config.shape==undefined?true:config.shape=="circle";
	this.DEPTH_ALPHA=config.depthFade==undefined?true:config.depthFade;
	this.WARP_EFFECT=config.warpEffect==undefined?true:config.warpEffect;
	this.WARP_EFFECT_LENGTH=config.warpEffectLength==undefined?5:config.warpEffectLength<0?0:config.warpEffectLength;
	this.STAR_SCALE=config.starSize==undefined||config.starSize<=0?3:config.starSize;
	this.BACKGROUND_COLOR=config.backgroundColor==undefined?"hsl(263,45%,7%)":config.backgroundColor;	
	this.speed_inc = 0.4;
	var innerWidth = window.innerWidth;
	var innerHeight = window.innerHeight;
	var canvas=document.getElementById(this.targetId);

	if(innerWidth > innerHeight) {
		canvas.width=window.innerWidth; canvas.height=window.innerHeight;
	} else {
		canvas.width=window.innerWidth/2; canvas.height=window.innerHeight/2;
	}
	var ctx=canvas.getContext("2d");
	ctx.fillStyle=this.BACKGROUND_COLOR;
	ctx.fillRect(0,0,1,1);
	ctx.fillStyle=config.starColor==undefined?"#FFFFFF":config.starColor;
	ctx.fillRect(0,0,1,1);
	var color=ctx.getImageData(0,0,1,1).data;
	this.STAR_R=color[0]; this.STAR_G=color[1]; this.STAR_B=color[2];
	this.prevW=-1; this.prevH=-1; //width and height will be set at first draw call
	this.stars=[];
	for(var i=0;i<this.DENSITY*1000;i++){
		this.stars.push(new Star((Math.random()-0.5)*1000,(Math.random()-0.5)*1000,1000*Math.random()));
	}
	this.lastMoveTS=timeStamp();
	this.drawRequest=null;
	this.LAST_RENDER_T=0;
	WarpSpeed.RUNNING_INSTANCES[targetId]=this;
	this.draw();
}

WarpSpeed.prototype={
	constructor:WarpSpeed,
	draw:function(){
		var TIME=timeStamp();
		if(!(document.getElementById(this.targetId))){
			this.destroy();
			return;
		}
		this.move();
		var canvas=document.getElementById(this.targetId);
		if(!this.PAUSED&&isVisible(canvas)){
			if(this.prevW!=window.innerWidth||this.prevH!=window.innerHeight){

				if(innerWidth > innerHeight) {
					canvas.width=(window.innerWidth<10?10:window.innerWidth);
					canvas.height=(window.innerHeight<10?10:window.innerHeight);
				} else {
					canvas.width=(window.innerHeight<10?10:window.innerHeight/3.5);
					canvas.height=(window.innerWidth<10?10:window.innerWidth/1.15);
				}

			}
			this.size=(canvas.height<canvas.width?canvas.height:canvas.width)/(10/(this.STAR_SCALE<=0?0:this.STAR_SCALE));
			if(this.WARP_EFFECT) this.maxLineWidth=this.size/30;
			var ctx=canvas.getContext("2d");
			ctx.fillStyle=this.BACKGROUND_COLOR;
			ctx.fillRect(0,0,canvas.width,canvas.height);
			var rgb="rgb("+this.STAR_R+","+this.STAR_G+","+this.STAR_B+")", rgba="rgba("+this.STAR_R+","+this.STAR_G+","+this.STAR_B+",";
			for(var i=0;i<this.stars.length;i++){
				var s=this.stars[i];
				var xOnDisplay=s.x/s.z, yOnDisplay=s.y/s.z;
				if(!this.WARP_EFFECT&&(xOnDisplay<-0.5||xOnDisplay>0.5||yOnDisplay<-0.5||yOnDisplay>0.5))continue;
				var size=s.size*this.size/s.z;
				if(size<0.3) continue; //don't draw very small dots
				if(this.DEPTH_ALPHA){
					var alpha=(1000-s.z)/1000;
					ctx.fillStyle=rgba+(alpha>1?1:alpha)+")";
				}else{
					ctx.fillStyle=rgb;
				}
				if(this.WARP_EFFECT){
					ctx.beginPath();
					var x2OnDisplay=s.x/(s.z+this.WARP_EFFECT_LENGTH*this.SPEED), y2OnDisplay=s.y/(s.z+this.WARP_EFFECT_LENGTH*this.SPEED);
					if(x2OnDisplay<-0.5||x2OnDisplay>0.5||y2OnDisplay<-0.5||y2OnDisplay>0.5)continue;
					ctx.moveTo(canvas.width*(xOnDisplay+0.5)-size/2,canvas.height*(yOnDisplay+0.5)-size/2 + 1);
					ctx.lineTo(canvas.width*(x2OnDisplay+0.5)-size/2,canvas.height*(y2OnDisplay+0.5)-size/2);
					ctx.lineWidth=size>this.maxLineWidth?this.maxLineWidth:size;
					if(this.USE_CIRCLES){ctx.lineCap="round";}else{ctx.lineCap="butt"}
					ctx.strokeStyle=ctx.fillStyle;
					ctx.stroke();
				}else if(this.USE_CIRCLES){
					ctx.beginPath();
					ctx.arc(canvas.width*(xOnDisplay+0.5)-size/2,canvas.height*(yOnDisplay+0.5)-size/2,size/2,0,2*Math.PI);
					ctx.fill();
				}else{
					ctx.fillRect(canvas.width*(xOnDisplay+0.5)-size/2,canvas.height*(yOnDisplay+0.5)-size/2,size,size);
				}
			}

			if(innerWidth > innerHeight) {
				this.prevW=window.innerWidth;
				this.prevH=window.innerHeight;
			} else {
				this.prevW=window.innerHeight;
				this.prevH=window.innerWidth;
			}
		}
		if(this.drawRequest!=-1)this.drawRequest=requestAnimationFrame(this.draw.bind(this));
		this.LAST_RENDER_T=timeStamp()-TIME;
	},
	move:function(){
		var t=timeStamp(), speedMulF=(t-this.lastMoveTS)/(1000/60);
		this.lastMoveTS=t;
		if(this.PAUSED)return;
		var speedAdjF=Math.pow(this.SPEED_ADJ_FACTOR<0?0:this.SPEED_ADJ_FACTOR>1?1:this.SPEED_ADJ_FACTOR,1);
		
		  if (this.TARGET_SPEED >= 0.0001) {
		    this.TARGET_SPEED += this.speed_inc
		    if (this.TARGET_SPEED > 50) 
		      this.speed_inc = -3;
		  }

		this.SPEED=this.TARGET_SPEED*speedAdjF+this.SPEED*(1-speedAdjF);

		if(this.SPEED<0)this.SPEED=0;

		var speed=this.SPEED;

		for(var i=0;i<this.stars.length;i++){
			var s=this.stars[i];
			s.z-=speed;
			while(s.z<1){
				s.z+=1000;
				s.x=(Math.random()-0.5)*s.z+0.001;
				s.y=(Math.random()-0.5)*s.z+0.001;
			}
		}
	},
	destroy:function(targetId){
		if(targetId){
			if(WarpSpeed.RUNNING_INSTANCES[targetId])WarpSpeed.RUNNING_INSTANCES[targetId].destroy();
		}else{
			try{cancelAnimationFrame(this.drawRequest);}catch(e){this.drawRequest=-1;}
			WarpSpeed.RUNNING_INSTANCES[this.targetId]=undefined;
		}
	},
	pause:function(){
		this.PAUSED=true;
	},
	resume:function(){
		this.PAUSED=false;
	},
	reset_speedinc: function() {
		this.speed_inc = 0.4;
		this.TARGET_SPEED = 20;
	}
}

WarpSpeed.destroy=WarpSpeed.prototype.destroy;

var wrap = new WarpSpeed("canvas",
                         {density:12,backgroundColor:"#000000",starColor:"rgba(255,255,255)",speed:0.005, depthFade:false, starSize: 3 }
                        );

wrap.pause();

setTimeout(function(){ 
  wrap.resume(); 
}, 3000);

window.addEventListener('click', (event) => {
  wrap.reset_speedinc();
});
	html,body{
		margin:0;
		padding:0;
		font-family:sans-serif;
		color:#FFFFFF;
		background-color:#000000;
	}
	<div style="position:fixed; z-index:0; top:0; left:0; width:100%; height:100%;">
		<canvas id="canvas" style="width:100%; height:100%;"></canvas>
	</div>

0 个答案:

没有答案