1. 程式人生 > >3D炫酷雪花背景的實現

3D炫酷雪花背景的實現

效果展示(微信截動態變化背景圖,效果不太好。另外,由於不會P圖,雪花用的圖片就是一個白色的圓,特別是近鏡頭的時候,效果有點搓哈,囧囧囧~,會p圖的同學可以將ParticleSmoke.png P成無背景的雪花圖片,要是能把P好的圖片給我的話就太謝謝了!):


程式碼講解:

index.html

<!DOCTYPE html >
<html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="utf-8">

<meta name="viewport" content="width=device-width,hight=device-hight,minimum-scale=1.0,maximum-scale=1.0,ser-scalable=none">
<title>開始下雪了</title>
<link type="text/css" rel="stylesheet" href="">

<style>
*{margin: 0;padding: 0;overflow: hidden;}
body{
	background-image:url('images/background.jpg');
	background-size:cover;
	background-repeat: no-repeat;
	position: relative;
	width:100%;
}

</style>
</head>

<body>
<audio autoplay="autoplay" loop="loop"><source src="js/網路歌手-冰海.mp3" type="audio/ogg"></audio>
</body>
<script type="text/javascript" src="./js/ThreeCanvas.js"></script>
<script src="http://www.jq22.com/jquery/2.1.1/jquery.min.js"></script>
<script type="text/javascript" src="./js/Snow.js"></script>
<script type="text/javascript" src="./js/snowFall.js"></script>
<script type="text/javascript" src="./js/snowFalling.js"></script>
<script>
	$.snowFalling({
		//初始雪花粒子數量,密度
		particleNo:0,
		//粒子下拉速度
		particleSpeed:50,
		//粒子在垂直(Y軸)方向運動範圍
		particleY_Range:window.innerWidth,
		//粒子在垂直(X軸)方向運動範圍
		particleX_Range:window.innerHeight,
	    //相機離Z軸原點距離
	    zIndex:600,
	  //攝像機視野角度
	    angle:55,
	    wind_weight:10 //風速:大於0,雪花向右飄;小於0,雪花向左飄;等於0,無風。
		});
</script>


</html>

index.html除了設定下雪的引數,加個背景音樂外,沒有其他的了。

snowFalling.js

 //建立snowFall物件
var snowFall=new snowFall(window.innerWidth,window.innerHeight,true,20);
//容器
var container;

//繫結jquery方法
jQuery.extend({
	snowFalling:function(options){
		 var defaults = {     
			//建立粒子數量,密度
			particleNo: 500,
			//粒子下拉速度
			particleSpeed:15,
			//粒子在垂直(Y軸)方向運動範圍
			particleY_Range:1300,
			//粒子在垂直(X軸)方向運動範圍
			particleX_Range:1000,
		    //相機離Z軸原點距離
		    zIndex:600,
		    //風力強度,正值向右,負值向左
		    wind_weight:0,
		    //攝像機視野角度
		    angle:55
		  };  
		  
		var particleImage = new Image();
		particleImage.src = "images/ParticleSmoke.png";
		var opts = $.extend(defaults, options);
		opts.particleImage=particleImage;
		opts.screenWidth=window.innerWidth;
		opts.screenHeight=window.innerHeight;
		//初始化下雪廠景
		snowFall.init(opts);
		
		container = document.createElement('div');
		document.body.appendChild(container);
		container.appendChild(snowFall.renderer.domElement );
		
		//雪景變化
		snowFall.snowFallChange();
	}
});

snowFalling.js主要做了三件事:1、獲取index.html中設定的引數;2、new 一個snowFall物件,並進行初始化;3、呼叫snowFall.snowFallChange()函式;

snowFall.js

function snowFall(screenWidth,screenHeight,flag,parameter){
	this.screenWidth=screenWidth;
	this.screenHeight=screenHeight;
	this.flag=flag;
	this.parameter=parameter;
}
snowFall.prototype.init=function(opts){
		snowFall.options=opts;
//		透視相機,物體大小隨距離攝像機遠近改變,對比投影相機
//		相機的上方向為Y軸,右方向為X軸,沿著Z軸垂直朝裡(視野角:fov; 縱橫比:aspect; 相機離視最近的距離:near; 相機離視體積最遠距離:far)		
		snowFall.camera = new THREE.PerspectiveCamera( opts.angle, snowFall.screenWidth / snowFall.screenHeight, 1, 10000 );
		//設定攝像機z座標位置距離原點向外距離
		snowFall.camera.position.z = snowFall.options.zIndex;
		//建立場景
		snowFall.scene = new THREE.Scene();
		snowFall.scene.add(snowFall.camera);
		//建立渲染器
		snowFall.renderer = new THREE.CanvasRenderer();
		snowFall.renderer.setSize(snowFall.screenWidth, snowFall.screenHeight);
		//建立材料
		snowFall.material = new THREE.ParticleBasicMaterial( { map: new THREE.Texture(snowFall.options.particleImage) } );
		
		snowFall.particles = []; 
		
		for (var i = 0; i < snowFall.options.particleNo; i++) {
			snowFall.addparticle(); 
		}
}
snowFall.prototype.loop=function(){
	for(var i = 0; i<snowFall.particles.length; i++){
		snowFall.particle = snowFall.particles[i]; 
		snowFall.particle.updatePhysics(); 
		with(snowFall.particle.position){
			if(y<-snowFall.options.particleY_Range/2){
				y+=snowFall.options.particleY_Range;
			} 
//			Z軸位置不變
			if(x>snowFall.options.screenWidth/2){
				x-=snowFall.options.screenWidth;
			}else if(x<-snowFall.options.screenWidth/2){
				x+=snowFall.options.screenWidth;
			} 
			//風力偏向效果
			x+=snowFall.options.wind_weight;
		}				
	}
	snowFall.camera.lookAt(snowFall.scene.position); 
	snowFall.renderer.render( snowFall.scene, snowFall.camera );
}

snowFall.prototype.addParticle=function(){
	snowFall.particle = new Snow(snowFall.material);
	snowFall.particle.position.x = Math.random() * snowFall.options.screenWidth *2- snowFall.options.screenWidth/2;
	snowFall.particle.position.y = Math.random() * snowFall.options.screenHeight * 2 - snowFall.options.screenHeight;
	snowFall.particle.position.z = Math.random() * snowFall.options.zIndex * 2 - snowFall.options.zIndex*1;
	snowFall.particle.scale.x = snowFall.particle.scale.y =  1;
	snowFall.scene.add( snowFall.particle );		
	snowFall.particles.push(snowFall.particle); 
}

snowFall.prototype.removeParticle=function(){
	snowFall.particle=snowFall.particles.pop();
	snowFall.scene.remove( snowFall.particle ); 
}

snowFall.prototype.parameterChange=function(){
	if(snowFall.particles.length>=500){
		snowFall.parameter=500;
	}else if(snowFall.particles.length>=200&&snowFall.particles.length<500){
		snowFall.parameter=300;
	}else if(snowFall.particles.length>=100&&snowFall.particles.length<200){
		snowFall.parameter=100;
	}else if(snowFall.particles.length>=50&&snowFall.particles.length<100){
		snowFall.parameter=50;
	}else{
		snowFall.parameter=20;
	}
}

snowFall.prototype.particlesCountChange=function(){
	snowFall.parameterChange(snowFall.particles);
	if(snowFall.flag){
		for(var j=0;j<parseInt(snowFall.parameter*Math.random());j++){
			if(snowFall.particles.length>=1500){
				snowFall.flag=false;
				return snowFall.flag;
			}
			snowFall.addParticle();
		}
	}else{
		for(var j=0;j<parseInt(snowFall.parameter*Math.random());j++){
			if(snowFall.particles.length>0){
				snowFall.removeParticle();
			}else{
				snowFall.flag=true;
			}
		}
	}
}

snowFall.prototype.snowFallChange=function(){
	var time1=setInterval( snowFall.loop, snowFall.options.particleSpeed );
		setInterval(function(){
			snowFall.options.particleNo+=parseInt(10*Math.random());
			window.clearInterval(time1); 
			snowFall.particlesCountChange();
			time1=setInterval( snowFall.loop, snowFall.options.particleSpeed);
		},3000);
}

snowFall.js主要是已Prototype/Constructor雜合方式建立了一個snowFall類。

function snowFall() 建構函式;

snowFall.init() 初始化,主要實現包括三維相機、場景、渲染器、材料的初始化,以及開始雪花粒子數量的設定;

snowFall.snowFallChange() 雪景的變化,包括雪花粒子數量的變化以及雪花移動位置的動態變化;

snowFall.particlesCountChange() 雪花粒子數量的變化,雪花粒子數量一開始是預設增加,當達到1500的時候,雪花粒子數量                                         就會減小;雪花粒子每次迴圈增加/減小的數量是隨機的,但增加/減少的雪花粒子速

                                        率 和當前雪花粒子數量正相關。

snowFall.loop() 雪花粒子位置的變化;

snowFall.parameterChange() 雪花粒子增加/減少速度變化;

snowFall.addParticle() 增加雪花粒子;

snowFall.removeParticle() 移除雪花粒子;

Snow.js

Snow=function(material){
	THREE.Particle.call(this,material);
	this.velocity=new THREE.Vector3(0,-8,0);//速度;
	//this.velocity.rotateX(2);//旋轉;
	this.gravity=new THREE.Vector3(0,0,0);//加速度;
	this.drag=1;//速度相乘係數;
};
//Particle:粒子;
//prototype:原形;
Snow.prototype=new THREE.Particle();
Snow.prototype.constructor=Snow;//建構函式
Snow.prototype.updatePhysics=function(){
	this.velocity.multiplyScalar(this.drag);//向量相乘函式
	this.velocity.addSelf(this.gravity);//向量相加函式
	this.position.addSelf(this.velocity);//向量相加函式
}
var TO_RADIANS=Math.PI/180;//角度向弧度轉換系數*
THREE.Vector3.prototype.rotateY=function(angle){
	//繞Y軸順時針旋轉angle;
	cosRY=Math.cos(angle*TO_RADIANS);
	sinRY=Math.sin(angle*TO_RADIANS);
	var tempz=this.z;
	var tempx=this.x;
	this.x=(tempx*cosRY)+(tempz*sinRY);
	this.z=(tempx*-sinRY)+(tempz*cosRY);
}
THREE.Vector3.prototype.rotateX=function(angle){
	//繞X軸順時針旋轉angle;
	cosRY=Math.cos(angle*TO_RADIANS);
	sinRY=Math.sin(angle*TO_RADIANS);
	var tempz=this.z;;
	var tempy=this.y;
	this.y=(tempy*cosRY)+(tempz*sinRY);
	this.z=(tempy*-sinRY)+(tempz*cosRY);
}
THREE.Vector3.prototype.rotateZ=function(angle){
	//繞Z軸順時針旋轉angle;
	cosRY=Math.cos(angle*TO_RADIANS);
	sinRY=Math.sin(angle*TO_RADIANS);
	var tempx=this.x;;
	var tempy=this.y;
	this.y=(tempy*cosRY)+(tempx*sinRY);
	this.x=(tempy*-sinRY)+(tempx*cosRY);
}

snow.js 主要是對ThreeCanvas.js的應用,想學的可以去了解一下three.js和ThreeCanvas.js

相關推薦

3D雪花背景實現

效果展示(微信截動態變化背景圖,效果不太好。另外,由於不會P圖,雪花用的圖片就是一個白色的圓,特別是近鏡頭的時候,效果有點搓哈,囧囧囧~,會p圖的同學可以將ParticleSmoke.png P成無背景的雪花圖片,要是能把P好的圖片給我的話就太謝謝了!):程式碼講解:inde

@description iPhoneX彩漸變背景實現

1.3 return texture nim tar path iphone undefine orf /** * @author zhangxinxu(.com) * @description iPhoneX炫彩漸變背景實現 * @link http://

CSS 背景效果的 10 個代碼片段

pos 圖片 http 動效 變色 基於用戶 漸變 ani 面板 在現代網頁設計中,大背景圖設計非常流行。隨著高清(現在是4K)顯示器的出現,越來越多的網頁設計師使用大背景圖來填充屏幕。 因為這樣可以造成很大的視覺沖擊力,並有助於更好的傳遞所要表現的內容。 但是,如果只是吧

字體背景圖的實現——神奇的background-clip: text

rep ima ice ack code 酷炫 chrom -s 關系   愉快的時光總是飛快,七天小長假已接近尾聲,抓住假期的尾巴,再學個新知識點——css的background-clip: text屬性...會不會有種陌生的感覺,畢竟在我們的印象裏,background

WebGIS簡單實現一個區域3D立體地圖效果

1.別人的效果         作為一個GIS專業的,做一個高大上的GIS系統一直是我的夢想,雖然至今為止還沒有做出一個理想中的系統,但是偶爾看看別人做的,學習下別人的技術還是很有必要的。眼睛是最容易誤導我們的,有時候看著炫酷的效果,可能只是因為一點視覺誤差,本文用一個別人的系統介面來解析如何實現一個小區域

Android之——史上最簡單最3D圖片瀏覽效果的實現

如今,Android開發已經成為移動互聯開發領域中一支不可或缺的力量,那麼Android中要實現3D的效果那也就是合情合理的事情了。那麼,如何在Android中實現像IOS中那樣的3D圖片瀏覽效果呢?下面,鄙人將重磅推出今天的重點博文,和大家一起在Android中實現酷炫

學習 CSS 之用 CSS 3D 實現效果

一、前言   把大象關進冰箱需要幾步?三步,把冰箱門開啟,把大象關進去,把冰箱門關上。   用 CSS 實現 3D 效果需幾步?三步,設定透視效果 perspective,改變元素載體為 preserve-3d,對元素進行 3D 轉換操作。   perspective 屬性決定了我們從什麼地方檢視元素,定義時

canvas - 3D星空

size 國際 代碼註釋 fun cit rfi prototype stars plug-in 1.國際慣例,先上效果 (⊙o⊙)… 效果圖看上去效果並不很炫酷啊,直接戳 這裏 看效果吧! 2代碼部分 html: <canvas id="canvas" wi

C語言實現粒子運動效果,最美C語言!最C語言!

eight src tps space hit size fad mar font 效果 我有一個微信公眾號,經常會分享一些C語言/C++技術相關的幹貨;如果你喜歡我的分享,可以用微信搜索“C語言學習部落”關註歡迎大家加入千人交流答疑裙:627+012+464C語

純CSS程式碼實現翻轉選單的效果

1、思路分析 滑鼠移入選單出現並翻轉 滑鼠移出收回選單 2、完整程式碼 <!DOCTYPE html> <html lang="en"> <head> <meta char

CSS3 實現圖片倒影特效

-webkit-box-reflect: below 0px -webkit-gradient(linear, left top, left bottom, from(transparent), color-stop(70%, transparent) , to(rgba(250

python的簡潔程式碼,實現的座標圖!

python簡潔的程式碼實現炫酷的功能,一副座標圖獻給各位看官瞧瞧 # -*- coding: utf-8 -*- """ Created on Fri Jan 19 13:34:15 2018 @author: administrator """ im

如何製作的PCB板3D效果圖

最近開源STM32四軸DIY群的專案進展到了畫板子階段。 大家畫的如火如荼,時而討論如何原理圖如何改進,時而討論如何進行PCB佈線,當然,晒圖是少不了的。 在晒的圖中我發現有個大神畫的3D效果特別棒。 在網上還看到了不少很棒的特效。

css hover背景點綴

滑鼠懸停時候,一層半透明白色從左往右,效果圖如下: 程式碼如下: <html> <head> <meta content = "text/html,charset=utf-8" > <style> html,body{ margin:0px

mix-blend-mode及background-blend-mode實現的圖片樣式

在網上看到了有如相機功能的mix-blend-mode實現比較好看的圖片樣式,自己也想弄下,在這裡記錄下 1.效果圖 2.mix-blend-mode相關屬性 { mix-blend-mode: normal; // 正常

仿製慕課網app實現鬥魚,全民k歌視訊引導頁(ViewVideoViewPaper)效果

在幾個月前,我第一次玩全民k歌,下載完app,它彈出來的引導頁吸引了我,不像以前的引導頁一樣千篇一律,而是用了視訊的方式,用一種動態的方式來實現。在今天,我突然又想起了這個效果,就抽出了一點時間在網上也借鑑了一些人的想法自己寫了一下這個炫酷的視訊引導頁。 現在我們先來看一下

css3實現ps蒙版效果以及動畫,吊炸天!

css3越來越強大,使用css也可以做越來越多意想不到的效果。 css3實現了ps的蒙版效果,炫酷叼炸天的技能,必須要分享出來啊! 實現原理 這個動畫,其實也並不複雜。它使用background-clip實現了文字蒙版的效果,然後結合了背景圖片的animation實現瞭如上圖所示的文字蒙版動畫。

純CSS導航欄的實現

純CSS酷炫導航欄的實現       作者語錄: 導航欄對於我們現在的日常生活非常的重要,基本上每一個頁面都要用到,所以讓我們的導航欄加上酷炫的效果會更加的吸睛,今天我就用純CSS和CSS3來實現。 1.先給大家說一下我要用到的東西:

生動的迴圈視訊背景網頁設計實戰

迴圈(Loop)是現代瀏覽器中HTML5視訊標籤下的布林屬性,包括IE9在內的主流瀏覽器都支援這一屬性。它能讓一個或者一系列視訊短片迴圈播放。開發者社群中,網頁設計師非常青睞這一功能,並且截至目前影響了許多專案,讓網站看起來更加絢麗和精彩。 從作品展示類的網站到移動端的專題頁,迴圈視訊背景的運用範疇非常廣泛

android實現水波紋介面

利用正弦函式 1、這篇是兩條水波紋,樣子類似點融(理財),波浪上面還漂浮一個圖示,超炫酷 2、多條水波紋聯動效果(容易出現問題) 1)有種向右漂移的感覺 2)動著動著就重合了(大姨媽app) 利用2階貝塞爾曲線 1、android 繪製波浪線 2、 Android 貝